void protect_range(void *start, unsigned long len, unsigned long prot) { uintptr_t curr = (uintptr_t)start & PAGE_MASK; len &= PAGE_MASK; for (; len; len -= PAGE_SIZE, curr += PAGE_SIZE) protect_page((void *)curr, prot); }
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, oft__ off) { #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4293) #endif const DWORD access = protect_file(prot); const DWORD protect = protect_page(prot); const oft__ max = off + (oft__)len; const DWORD max_lo = large ? (DWORD)((max) & MAXDWORD) : (DWORD)max; const DWORD max_hi = large ? (DWORD)((max >> 32) & MAXDWORD) : (DWORD)0; const DWORD file_lo = large ? (DWORD)((off) & MAXDWORD) : (DWORD)off; const DWORD file_hi = large ? (DWORD)((off >> 32) & MAXDWORD) : (DWORD)0; #ifdef _MSC_VER #pragma warning(pop) #endif if (len == 0 || (flags & MAP_FIXED) != 0 || prot == PROT_EXEC) { errno = EINVAL; return MAP_FAILED; } const HANDLE handle = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; if ((flags & MAP_ANONYMOUS) == 0 && handle == INVALID_HANDLE_VALUE) { errno = EBADF; return MAP_FAILED; } const HANDLE mapping = CreateFileMappingW(handle, NULL, protect, max_hi, max_lo, NULL); if (mapping == NULL) { errno = last_error(EPERM); return MAP_FAILED; } const LPVOID map = MapViewOfFile(mapping, access, file_hi, file_lo, len); /* TODO: verify mapping handle may be closed here and then use the map. */ if (map == NULL || CloseHandle(mapping) == FALSE) { errno = last_error(EPERM); return MAP_FAILED; } errno = 0; return map; }
int mprotect(void* addr, size_t len, int prot) { DWORD old_protect = 0; const DWORD new_protect = protect_page(prot); if (VirtualProtect(addr, len, new_protect, &old_protect) != FALSE) { errno = 0; return 0; } errno = last_error(EPERM); return -1; }