mmap-windows.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* mmap() replacement for Windows
  2. *
  3. * Author: Mike Frysinger <vapier@gentoo.org>
  4. * Placed into the public domain
  5. */
  6. /* References:
  7. * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
  8. * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
  9. * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
  10. * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
  11. */
  12. #include <io.h>
  13. #include <windows.h>
  14. #include <sys/types.h>
  15. #define PROT_READ 0x1
  16. #define PROT_WRITE 0x2
  17. /* This flag is only available in WinXP+ */
  18. #ifdef FILE_MAP_EXECUTE
  19. #define PROT_EXEC 0x4
  20. #else
  21. #define PROT_EXEC 0x0
  22. #define FILE_MAP_EXECUTE 0
  23. #endif
  24. #define MAP_SHARED 0x01
  25. #define MAP_PRIVATE 0x02
  26. #define MAP_ANONYMOUS 0x20
  27. #define MAP_ANON MAP_ANONYMOUS
  28. #define MAP_FAILED ((void *) -1)
  29. #ifdef __USE_FILE_OFFSET64
  30. # define DWORD_HI(x) (x >> 32)
  31. # define DWORD_LO(x) ((x) & 0xffffffff)
  32. #else
  33. # define DWORD_HI(x) (0)
  34. # define DWORD_LO(x) (x)
  35. #endif
  36. static void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
  37. {
  38. if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
  39. return MAP_FAILED;
  40. if (fd == -1) {
  41. if (!(flags & MAP_ANON) || offset)
  42. return MAP_FAILED;
  43. } else if (flags & MAP_ANON)
  44. return MAP_FAILED;
  45. DWORD flProtect;
  46. if (prot & PROT_WRITE) {
  47. if (prot & PROT_EXEC)
  48. flProtect = PAGE_EXECUTE_READWRITE;
  49. else
  50. flProtect = PAGE_READWRITE;
  51. } else if (prot & PROT_EXEC) {
  52. if (prot & PROT_READ)
  53. flProtect = PAGE_EXECUTE_READ;
  54. else if (prot & PROT_EXEC)
  55. flProtect = PAGE_EXECUTE;
  56. } else
  57. flProtect = PAGE_READONLY;
  58. off_t end = length + offset;
  59. HANDLE mmap_fd, h;
  60. if (fd == -1)
  61. mmap_fd = INVALID_HANDLE_VALUE;
  62. else
  63. mmap_fd = (HANDLE)_get_osfhandle(fd);
  64. h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
  65. if (h == NULL)
  66. return MAP_FAILED;
  67. DWORD dwDesiredAccess;
  68. if (prot & PROT_WRITE)
  69. dwDesiredAccess = FILE_MAP_WRITE;
  70. else
  71. dwDesiredAccess = FILE_MAP_READ;
  72. if (prot & PROT_EXEC)
  73. dwDesiredAccess |= FILE_MAP_EXECUTE;
  74. if (flags & MAP_PRIVATE)
  75. dwDesiredAccess |= FILE_MAP_COPY;
  76. void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
  77. if (ret == NULL) {
  78. CloseHandle(h);
  79. ret = MAP_FAILED;
  80. }
  81. return ret;
  82. }
  83. static void munmap(void *addr, size_t length)
  84. {
  85. UnmapViewOfFile(addr);
  86. /* ruh-ro, we leaked handle from CreateFileMapping() ... */
  87. }
  88. #undef DWORD_HI
  89. #undef DWORD_LO