1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkOSFile.h" 9 10 #include "SkTFitsIn.h" 11 12 #include <io.h> 13 #include <stdio.h> 14 #include <sys/stat.h> 15 16 typedef struct { 17 ULONGLONG fVolume; 18 ULONGLONG fLsbSize; 19 ULONGLONG fMsbSize; 20 } SkFILEID; 21 22 static bool sk_ino(SkFILE* f, SkFILEID* id) { 23 int fileno = _fileno((FILE*)f); 24 if (fileno < 0) { 25 return false; 26 } 27 28 HANDLE file = (HANDLE)_get_osfhandle(fileno); 29 if (INVALID_HANDLE_VALUE == file) { 30 return false; 31 } 32 33 //TODO: call GetFileInformationByHandleEx on Vista and later with FileIdInfo. 34 BY_HANDLE_FILE_INFORMATION info; 35 if (0 == GetFileInformationByHandle(file, &info)) { 36 return false; 37 } 38 id->fVolume = info.dwVolumeSerialNumber; 39 id->fLsbSize = info.nFileIndexLow + (((ULONGLONG)info.nFileIndexHigh) << 32); 40 id->fMsbSize = 0; 41 42 return true; 43 } 44 45 bool sk_fidentical(SkFILE* a, SkFILE* b) { 46 SkFILEID aID, bID; 47 return sk_ino(a, &aID) && sk_ino(b, &bID) 48 && aID.fLsbSize == bID.fLsbSize 49 && aID.fMsbSize == bID.fMsbSize 50 && aID.fVolume == bID.fVolume; 51 } 52 53 class SkAutoNullKernelHandle : SkNoncopyable { 54 public: 55 SkAutoNullKernelHandle(const HANDLE handle) : fHandle(handle) { } 56 ~SkAutoNullKernelHandle() { CloseHandle(fHandle); } 57 operator HANDLE() const { return fHandle; } 58 bool isValid() const { return NULL != fHandle; } 59 private: 60 HANDLE fHandle; 61 }; 62 typedef SkAutoNullKernelHandle SkAutoWinMMap; 63 64 void sk_fmunmap(const void* addr, size_t) { 65 UnmapViewOfFile(addr); 66 } 67 68 void* sk_fdmmap(int fileno, size_t* length) { 69 HANDLE file = (HANDLE)_get_osfhandle(fileno); 70 if (INVALID_HANDLE_VALUE == file) { 71 return NULL; 72 } 73 74 LARGE_INTEGER fileSize; 75 if (0 == GetFileSizeEx(file, &fileSize)) { 76 //TODO: use SK_TRACEHR(GetLastError(), "Could not get file size.") to report. 77 return NULL; 78 } 79 if (!SkTFitsIn<size_t>(fileSize.QuadPart)) { 80 return NULL; 81 } 82 83 SkAutoWinMMap mmap(CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL)); 84 if (!mmap.isValid()) { 85 //TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.") to report. 86 return NULL; 87 } 88 89 // Eventually call UnmapViewOfFile 90 void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0); 91 if (NULL == addr) { 92 //TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to report. 93 return NULL; 94 } 95 96 *length = static_cast<size_t>(fileSize.QuadPart); 97 return addr; 98 } 99 100 int sk_fileno(SkFILE* f) { 101 return _fileno((FILE*)f); 102 } 103 104 void* sk_fmmap(SkFILE* f, size_t* length) { 105 int fileno = sk_fileno(f); 106 if (fileno < 0) { 107 return NULL; 108 } 109 110 return sk_fdmmap(fileno, length); 111 } 112