Skip to content

Commit

Permalink
It compiles under windows
Browse files Browse the repository at this point in the history
  • Loading branch information
veso266 committed Oct 17, 2019
1 parent 749875e commit 7d525ad
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 9 deletions.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
TARGET = unnpk

CFLAGS += -Wall
LDFLAGS += -lz

ifeq ($(OS),Windows_NT)
LDFLAGS += -lz -lWs2_32
INCLUDELIB += -Iwindows/sys windows/sys/mman.c
else
LDFLAGS += -lz
INCLUDELIB =
endif

.PHONY: all clean

all: $(TARGET)

$(TARGET): unnpk.c
$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
$(CC) $(CFLAGS) $(INCLUDELIB) $< $(LDFLAGS) -o $@

clean:
rm -f $(TARGET)
23 changes: 16 additions & 7 deletions unnpk.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <arpa/inet.h>
#ifdef __linux__
#include <arpa/inet.h> //for ntohl
#include <sys/mman.h>
#elif _WIN32
#include <winsock2.h> //for ntohl
#include "windows/sys/mman.h"
#define mkdir(A, B) mkdir(A) //Function to create directory
#endif

#include <zlib.h>

Expand Down Expand Up @@ -477,11 +483,14 @@ static int proc_part_data_pkg_info(uint8_t *data, const uint32_t size,
hdr->revision);
else
printf("Version : %u.%u\n", hdr->ver_maj, hdr->ver_min);
gmtime_r((time_t *)&hdr->timestamp, &tm);
strftime(buf, sizeof(buf), "%c", &tm);
printf("Timestamp : %u (%s)\n", hdr->timestamp, buf);
printf("Unknown : %s\n", array2str(hdr->unk_30, sizeof(hdr->unk_30)));

#ifdef __linux__
gmtime_r((time_t *)&hdr->timestamp, &tm);
strftime(buf, sizeof(buf), "%c", &tm);
printf("Timestamp : %u (%s)\n", hdr->timestamp, buf);
#elif _WIN32
printf("Windows doesn't have gmtime_r and I am to lazy to port it to windows :(");
#endif
printf("Unknown : %s\n", array2str(hdr->unk_30, sizeof(hdr->unk_30)));
return 0;
}

Expand Down
180 changes: 180 additions & 0 deletions windows/sys/mman.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@

#include <windows.h>
#include <errno.h>
#include <io.h>

#include "mman.h"

#ifndef FILE_MAP_EXECUTE
#define FILE_MAP_EXECUTE 0x0020
#endif /* FILE_MAP_EXECUTE */

static int __map_mman_error(const DWORD err, const int deferr)
{
if (err == 0)
return 0;
//TODO: implement
return err;
}

static DWORD __map_mmap_prot_page(const int prot)
{
DWORD protect = 0;

if (prot == PROT_NONE)
return protect;

if ((prot & PROT_EXEC) != 0)
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_READWRITE : PAGE_READONLY;
}

return protect;
}

static DWORD __map_mmap_prot_file(const int prot)
{
DWORD desiredAccess = 0;

if (prot == PROT_NONE)
return desiredAccess;

if ((prot & PROT_READ) != 0)
desiredAccess |= FILE_MAP_READ;
if ((prot & PROT_WRITE) != 0)
desiredAccess |= FILE_MAP_WRITE;
if ((prot & PROT_EXEC) != 0)
desiredAccess |= FILE_MAP_EXECUTE;

return desiredAccess;
}

void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
HANDLE fm, h;

void * map = MAP_FAILED;

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4293)
#endif

const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
const DWORD protect = __map_mmap_prot_page(prot);
const DWORD desiredAccess = __map_mmap_prot_file(prot);

const off_t maxSize = off + (off_t)len;

const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);

#ifdef _MSC_VER
#pragma warning(pop)
#endif

errno = 0;

if (len == 0
/* Unsupported flag combinations */
|| (flags & MAP_FIXED) != 0
/* Usupported protection combinations */
|| prot == PROT_EXEC)
{
errno = EINVAL;
return MAP_FAILED;
}

h = ((flags & MAP_ANONYMOUS) == 0) ?
(HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;

if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return MAP_FAILED;
}

fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);

if (fm == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}

map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);

CloseHandle(fm);

if (map == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}

return map;
}

int munmap(void *addr, size_t len)
{
if (UnmapViewOfFile(addr))
return 0;

errno = __map_mman_error(GetLastError(), EPERM);

return -1;
}

int mprotect(void *addr, size_t len, int prot)
{
DWORD newProtect = __map_mmap_prot_page(prot);
DWORD oldProtect = 0;

if (VirtualProtect(addr, len, newProtect, &oldProtect))
return 0;

errno = __map_mman_error(GetLastError(), EPERM);

return -1;
}

int msync(void *addr, size_t len, int flags)
{
if (FlushViewOfFile(addr, len))
return 0;

errno = __map_mman_error(GetLastError(), EPERM);

return -1;
}

int mlock(const void *addr, size_t len)
{
if (VirtualLock((LPVOID)addr, len))
return 0;

errno = __map_mman_error(GetLastError(), EPERM);

return -1;
}

int munlock(const void *addr, size_t len)
{
if (VirtualUnlock((LPVOID)addr, len))
return 0;

errno = __map_mman_error(GetLastError(), EPERM);

return -1;
}
55 changes: 55 additions & 0 deletions windows/sys/mman.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* sys/mman.h
* mman-win32
*/

#ifndef _SYS_MMAN_H_
#define _SYS_MMAN_H_

#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif

/* All the headers include this file. */
#ifndef _MSC_VER
#include <_mingw.h>
#endif

#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif

#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4

#define MAP_FILE 0
#define MAP_SHARED 1
#define MAP_PRIVATE 2
#define MAP_TYPE 0xf
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS

#define MAP_FAILED ((void *)-1)

/* Flags for msync. */
#define MS_ASYNC 1
#define MS_SYNC 2
#define MS_INVALIDATE 4

void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
int munmap(void *addr, size_t len);
int mprotect(void *addr, size_t len, int prot);
int msync(void *addr, size_t len, int flags);
int mlock(const void *addr, size_t len);
int munlock(const void *addr, size_t len);

#ifdef __cplusplus
};
#endif

#endif /* _SYS_MMAN_H_ */

0 comments on commit 7d525ad

Please sign in to comment.