mman.c 4.0 KB

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