• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
__map_mman_error(const DWORD err,const int deferr)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 
__map_mmap_prot_page(const int prot)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 
__map_mmap_prot_file(const int prot)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 
mmap(void * addr,size_t len,int prot,int flags,int fildes,off_t off)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 
munmap(void * addr,size_t len)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 
mprotect(void * addr,size_t len,int prot)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 
msync(void * addr,size_t len,int flags)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 
mlock(const void * addr,size_t len)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 
munlock(const void * addr,size_t len)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