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