mmap_win32.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 "mmap.h"
  15. #ifdef __USE_FILE_OFFSET64
  16. # define DWORD_HI(x) (x >> 32)
  17. # define DWORD_LO(x) ((x) & 0xffffffff)
  18. #else
  19. # define DWORD_HI(x) (0)
  20. # define DWORD_LO(x) (x)
  21. #endif
  22. void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset)
  23. {
  24. if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
  25. return MAP_FAILED;
  26. if (fd == -1) {
  27. if (!(flags & MAP_ANON) || offset)
  28. return MAP_FAILED;
  29. } else if (flags & MAP_ANON)
  30. return MAP_FAILED;
  31. DWORD flProtect;
  32. if (prot & PROT_WRITE) {
  33. if (prot & PROT_EXEC)
  34. flProtect = PAGE_EXECUTE_READWRITE;
  35. else
  36. flProtect = PAGE_READWRITE;
  37. } else if (prot & PROT_EXEC) {
  38. if (prot & PROT_READ)
  39. flProtect = PAGE_EXECUTE_READ;
  40. else if (prot & PROT_EXEC)
  41. flProtect = PAGE_EXECUTE;
  42. } else
  43. flProtect = PAGE_READONLY;
  44. off_t end = length + offset;
  45. HANDLE mmap_fd, h;
  46. if (fd == -1)
  47. mmap_fd = INVALID_HANDLE_VALUE;
  48. else
  49. mmap_fd = (HANDLE)_get_osfhandle(fd);
  50. h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
  51. if (h == NULL)
  52. return MAP_FAILED;
  53. DWORD dwDesiredAccess;
  54. if (prot & PROT_WRITE)
  55. dwDesiredAccess = FILE_MAP_WRITE;
  56. else
  57. dwDesiredAccess = FILE_MAP_READ;
  58. if (prot & PROT_EXEC)
  59. dwDesiredAccess |= FILE_MAP_EXECUTE;
  60. if (flags & MAP_PRIVATE)
  61. dwDesiredAccess |= FILE_MAP_COPY;
  62. void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
  63. if (ret == NULL) {
  64. ret = MAP_FAILED;
  65. }
  66. // since we are handling the file ourselves with fd, close the Windows Handle here
  67. CloseHandle(h);
  68. return ret;
  69. }
  70. void munmap(void* addr, size_t length)
  71. {
  72. UnmapViewOfFile(addr);
  73. }
  74. #undef DWORD_HI
  75. #undef DWORD_LO