123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #include <windows.h>
- #include <errno.h>
- #include <io.h>
- #include "mman.h"
- #ifndef FILE_MAP_EXECUTE
- #define FILE_MAP_EXECUTE 0x0020
- #endif /* FILE_MAP_EXECUTE */
- static int __map_mman_error(const DWORD err, const int deferr)
- {
- if (err == 0)
- return 0;
- //TODO: implement
- return err;
- }
- static DWORD __map_mmap_prot_page(const int prot)
- {
- DWORD protect = 0;
-
- if (prot == PROT_NONE)
- return protect;
-
- if ((prot & PROT_EXEC) != 0)
- {
- protect = ((prot & PROT_WRITE) != 0) ?
- PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
- }
- else
- {
- protect = ((prot & PROT_WRITE) != 0) ?
- PAGE_READWRITE : PAGE_READONLY;
- }
-
- return protect;
- }
- static DWORD __map_mmap_prot_file(const int prot)
- {
- DWORD desiredAccess = 0;
-
- if (prot == PROT_NONE)
- return desiredAccess;
-
- if ((prot & PROT_READ) != 0)
- desiredAccess |= FILE_MAP_READ;
- if ((prot & PROT_WRITE) != 0)
- desiredAccess |= FILE_MAP_WRITE;
- if ((prot & PROT_EXEC) != 0)
- desiredAccess |= FILE_MAP_EXECUTE;
-
- return desiredAccess;
- }
- void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
- {
- HANDLE fm, h;
-
- void * map = MAP_FAILED;
-
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4293)
- #endif
- const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
- (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
- const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
- (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
- const DWORD protect = __map_mmap_prot_page(prot);
- const DWORD desiredAccess = __map_mmap_prot_file(prot);
- const off_t maxSize = off + (off_t)len;
- const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
- (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
- const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
- (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- errno = 0;
-
- if (len == 0
- /* Unsupported flag combinations */
- || (flags & MAP_FIXED) != 0
- /* Usupported protection combinations */
- || prot == PROT_EXEC)
- {
- errno = EINVAL;
- return MAP_FAILED;
- }
-
- h = ((flags & MAP_ANONYMOUS) == 0) ?
- (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
- if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
- {
- errno = EBADF;
- return MAP_FAILED;
- }
- fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
- if (fm == NULL)
- {
- errno = __map_mman_error(GetLastError(), EPERM);
- return MAP_FAILED;
- }
-
- map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
- CloseHandle(fm);
-
- if (map == NULL)
- {
- errno = __map_mman_error(GetLastError(), EPERM);
- return MAP_FAILED;
- }
- return map;
- }
- int munmap(void *addr, size_t len)
- {
- if (UnmapViewOfFile(addr))
- return 0;
-
- errno = __map_mman_error(GetLastError(), EPERM);
-
- return -1;
- }
- int mprotect(void *addr, size_t len, int prot)
- {
- DWORD newProtect = __map_mmap_prot_page(prot);
- DWORD oldProtect = 0;
-
- if (VirtualProtect(addr, len, newProtect, &oldProtect))
- return 0;
-
- errno = __map_mman_error(GetLastError(), EPERM);
-
- return -1;
- }
- int msync(void *addr, size_t len, int flags)
- {
- if (FlushViewOfFile(addr, len))
- return 0;
-
- errno = __map_mman_error(GetLastError(), EPERM);
-
- return -1;
- }
- int mlock(const void *addr, size_t len)
- {
- if (VirtualLock((LPVOID)addr, len))
- return 0;
-
- errno = __map_mman_error(GetLastError(), EPERM);
-
- return -1;
- }
- int munlock(const void *addr, size_t len)
- {
- if (VirtualUnlock((LPVOID)addr, len))
- return 0;
-
- errno = __map_mman_error(GetLastError(), EPERM);
-
- return -1;
- }
|