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 bool sk_exists(const char *path, SkFILE_Flags flags) { 17 int mode = 0; // existence 18 if (flags & kRead_SkFILE_Flag) { 19 mode |= 4; // read 20 } 21 if (flags & kWrite_SkFILE_Flag) { 22 mode |= 2; // write 23 } 24 return (0 == _access(path, mode)); 25 } 26 27 typedef struct { 28 ULONGLONG fVolume; 29 ULONGLONG fLsbSize; 30 ULONGLONG fMsbSize; 31 } SkFILEID; 32 33 static bool sk_ino(SkFILE* f, SkFILEID* id) { 34 int fileno = _fileno((FILE*)f); 35 if (fileno < 0) { 36 return false; 37 } 38 39 HANDLE file = (HANDLE)_get_osfhandle(fileno); 40 if (INVALID_HANDLE_VALUE == file) { 41 return false; 42 } 43 44 //TODO: call GetFileInformationByHandleEx on Vista and later with FileIdInfo. 45 BY_HANDLE_FILE_INFORMATION info; 46 if (0 == GetFileInformationByHandle(file, &info)) { 47 return false; 48 } 49 id->fVolume = info.dwVolumeSerialNumber; 50 id->fLsbSize = info.nFileIndexLow + (((ULONGLONG)info.nFileIndexHigh) << 32); 51 id->fMsbSize = 0; 52 53 return true; 54 } 55 56 bool sk_fidentical(SkFILE* a, SkFILE* b) { 57 SkFILEID aID, bID; 58 return sk_ino(a, &aID) && sk_ino(b, &bID) 59 && aID.fLsbSize == bID.fLsbSize 60 && aID.fMsbSize == bID.fMsbSize 61 && aID.fVolume == bID.fVolume; 62 } 63 64 class SkAutoNullKernelHandle : SkNoncopyable { 65 public: 66 SkAutoNullKernelHandle(const HANDLE handle) : fHandle(handle) { } 67 ~SkAutoNullKernelHandle() { CloseHandle(fHandle); } 68 operator HANDLE() const { return fHandle; } 69 bool isValid() const { return SkToBool(fHandle); } 70 private: 71 HANDLE fHandle; 72 }; 73 typedef SkAutoNullKernelHandle SkAutoWinMMap; 74 75 void sk_fmunmap(const void* addr, size_t) { 76 UnmapViewOfFile(addr); 77 } 78 79 void* sk_fdmmap(int fileno, size_t* length) { 80 HANDLE file = (HANDLE)_get_osfhandle(fileno); 81 if (INVALID_HANDLE_VALUE == file) { 82 return NULL; 83 } 84 85 LARGE_INTEGER fileSize; 86 if (0 == GetFileSizeEx(file, &fileSize)) { 87 //TODO: use SK_TRACEHR(GetLastError(), "Could not get file size.") to report. 88 return NULL; 89 } 90 if (!SkTFitsIn<size_t>(fileSize.QuadPart)) { 91 return NULL; 92 } 93 94 SkAutoWinMMap mmap(CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL)); 95 if (!mmap.isValid()) { 96 //TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.") to report. 97 return NULL; 98 } 99 100 // Eventually call UnmapViewOfFile 101 void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0); 102 if (NULL == addr) { 103 //TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to report. 104 return NULL; 105 } 106 107 *length = static_cast<size_t>(fileSize.QuadPart); 108 return addr; 109 } 110 111 int sk_fileno(SkFILE* f) { 112 return _fileno((FILE*)f); 113 } 114 115 void* sk_fmmap(SkFILE* f, size_t* length) { 116 int fileno = sk_fileno(f); 117 if (fileno < 0) { 118 return NULL; 119 } 120 121 return sk_fdmmap(fileno, length); 122 } 123