1 #ifdef _WIN32 2 3 #include <windows.h> 4 #include <errno.h> 5 #include <io.h> 6 7 #include "mman.h" 8 9 #ifndef FILE_MAP_EXECUTE 10 #define FILE_MAP_EXECUTE 0x0020 11 #endif /* FILE_MAP_EXECUTE */ 12 13 static int __map_mman_error(const DWORD err, const int deferr) 14 { 15 if (err == 0) 16 return 0; 17 //TODO: implement 18 return err; 19 } 20 21 static DWORD __map_mmap_prot_page(const int prot) 22 { 23 DWORD protect = 0; 24 25 if (prot == PROT_NONE) 26 return protect; 27 28 if ((prot & PROT_EXEC) != 0) 29 { 30 protect = ((prot & PROT_WRITE) != 0) ? 31 PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; 32 } 33 else 34 { 35 protect = ((prot & PROT_WRITE) != 0) ? 36 PAGE_READWRITE : PAGE_READONLY; 37 } 38 39 return protect; 40 } 41 42 static DWORD __map_mmap_prot_file(const int prot) 43 { 44 DWORD desiredAccess = 0; 45 46 if (prot == PROT_NONE) 47 return desiredAccess; 48 49 if ((prot & PROT_READ) != 0) 50 desiredAccess |= FILE_MAP_READ; 51 if ((prot & PROT_WRITE) != 0) 52 desiredAccess |= FILE_MAP_WRITE; 53 if ((prot & PROT_EXEC) != 0) 54 desiredAccess |= FILE_MAP_EXECUTE; 55 56 return desiredAccess; 57 } 58 59 void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) 60 { 61 HANDLE fm, h; 62 63 void * map = MAP_FAILED; 64 65 #ifdef _MSC_VER 66 #pragma warning(push) 67 #pragma warning(disable: 4293) 68 #endif 69 70 const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? 71 (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); 72 const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? 73 (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); 74 const DWORD protect = __map_mmap_prot_page(prot); 75 const DWORD desiredAccess = __map_mmap_prot_file(prot); 76 77 const off_t maxSize = off + (off_t)len; 78 79 const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? 80 (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); 81 const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ? 82 (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); 83 84 #ifdef _MSC_VER 85 #pragma warning(pop) 86 #endif 87 88 errno = 0; 89 90 if (len == 0 91 /* Unsupported flag combinations */ 92 || (flags & MAP_FIXED) != 0 93 /* Usupported protection combinations */ 94 || prot == PROT_EXEC) 95 { 96 errno = EINVAL; 97 return MAP_FAILED; 98 } 99 100 h = ((flags & MAP_ANONYMOUS) == 0) ? 101 (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; 102 103 if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) 104 { 105 errno = EBADF; 106 return MAP_FAILED; 107 } 108 109 fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); 110 111 if (fm == NULL) 112 { 113 errno = __map_mman_error(GetLastError(), EPERM); 114 return MAP_FAILED; 115 } 116 117 map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); 118 119 CloseHandle(fm); 120 121 if (map == NULL) 122 { 123 errno = __map_mman_error(GetLastError(), EPERM); 124 return MAP_FAILED; 125 } 126 127 return map; 128 } 129 130 int munmap(void *addr, size_t len) 131 { 132 if (UnmapViewOfFile(addr)) 133 return 0; 134 135 errno = __map_mman_error(GetLastError(), EPERM); 136 137 return -1; 138 } 139 140 int mprotect(void *addr, size_t len, int prot) 141 { 142 DWORD newProtect = __map_mmap_prot_page(prot); 143 DWORD oldProtect = 0; 144 145 if (VirtualProtect(addr, len, newProtect, &oldProtect)) 146 return 0; 147 148 errno = __map_mman_error(GetLastError(), EPERM); 149 150 return -1; 151 } 152 153 int msync(void *addr, size_t len, int flags) 154 { 155 if (FlushViewOfFile(addr, len)) 156 return 0; 157 158 errno = __map_mman_error(GetLastError(), EPERM); 159 160 return -1; 161 } 162 163 int mlock(const void *addr, size_t len) 164 { 165 if (VirtualLock((LPVOID)addr, len)) 166 return 0; 167 168 errno = __map_mman_error(GetLastError(), EPERM); 169 170 return -1; 171 } 172 173 int munlock(const void *addr, size_t len) 174 { 175 if (VirtualUnlock((LPVOID)addr, len)) 176 return 0; 177 178 errno = __map_mman_error(GetLastError(), EPERM); 179 180 return -1; 181 } 182 183 #endif // _WIN32