Code: Select all
#ifdef _WIN32
/*
* Implementation of mmap()/munmap() replacement for Windows.
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define PROT_READ 0x0001
#define PROT_WRITE 0x0002
#define PROT_EXEC 0x0004
#define PROT_NONE 0x0008
#define MAP_SHARED 0x0001
#define MAP_PRIVATE 0x0002
#define MAP_FIXED 0x0004
#define MAP_FAILED ((void *)-1)
typedef struct {
unsigned int prot_flag;
DWORD win_flag;
} Protection_Scheme_t;
typedef struct _MapList_t {
HANDLE hMap;
void *Base;
struct _MapList_t *Next;
} MapList_t;
static const Protection_Scheme_t Protection_Scheme[] = {
{ PROT_READ, PAGE_READONLY },
{ PROT_READ|PROT_WRITE, PAGE_READWRITE },
{ PROT_READ|PROT_WRITE|PROT_EXEC, PAGE_EXECUTE_READWRITE },
{ PROT_EXEC, PAGE_EXECUTE },
{ PROT_READ|PROT_EXEC, PAGE_EXECUTE_READ },
};
static MapList_t *MapList = NULL;
void *mmap(unsigned int address, unsigned int size, unsigned int protection, unsigned int flags, int fd, int offset)
{
HANDLE hFile, hMapFile;
DWORD dwProtect, dwAccess;
void *Base;
MapList_t *Item;
unsigned int x;
/* Check if fd is valid */
if (fd == -1)
return MAP_FAILED;
/* Retrieve system handle from fd */
hFile = (HANDLE)_get_osfhandle(fd);
if (hFile == INVALID_HANDLE_VALUE)
return MAP_FAILED;
/* Search protection schemes */
for (dwProtect=PAGE_NOACCESS, x=0;
x < (sizeof(Protection_Scheme)/sizeof(Protection_Scheme_t));
x++)
{
if (Protection_Scheme[x].prot_flag == protection)
{
dwProtect = Protection_Scheme[x].win_flag;
break;
}
}
if (flags & MAP_PRIVATE) {
dwAccess = FILE_MAP_COPY;
dwProtect = PAGE_WRITECOPY;
} else
if ((protection & PROT_WRITE))
dwAccess = FILE_MAP_WRITE;
else
dwAccess = FILE_MAP_READ;
/* Create mapping object */
hMapFile = CreateFileMapping(hFile, NULL, dwProtect, 0, size, NULL);
if (hMapFile == INVALID_HANDLE_VALUE)
return MAP_FAILED;
/* Select which portions of the file we need (entire file) */
Base = MapViewOfFile(hMapFile, dwAccess, 0, offset, size);
if (Base == NULL) {
/* Free the mapping object */
CloseHandle(hMapFile);
return MAP_FAILED;
}
/* Allocate item for list mmaps... */
Item = (MapList_t *)malloc(sizeof(MapList_t));
if (Item == NULL) {
UnmapViewOfFile(Base);
CloseHandle(hMapFile);
return MAP_FAILED;
}
Item->hMap = hMapFile;
Item->Base = Base;
Item->Next = MapList;
if (MapList == NULL)
MapList = Item;
return Base;
}
int munmap(void *addr, unsigned int size)
{
MapList_t *Item, *Prev;
Prev = NULL;
Item = MapList;
while (Item != NULL) {
if (Item->Base == addr) {
UnmapViewOfFile(Item->Base);
CloseHandle(Item->hMap);
/* Delete this item from linked list */
if (Prev != NULL)
Prev->Next = Item->Next;
else
MapList = Item->Next;
free(Item);
return 0;
}
Prev = Item;
Item = Item->Next;
}
return -1;
}
#endif /* _WIN32 */
the supposedly benefit is that its said to have a much smaller footprint than malloc or virtualalloc i havent tested that but it works quite fine for replacing the same functions in linux programs ported to win32