From 1585730ec1882c97dcd35dfabba0bb63078169aa Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 30 Jan 2013 02:48:34 -0800 Subject: [PATCH] Running on Windows! Minus gflags parsing right now. --- common.gypi | 2 +- src/core/mmap_win.cc | 132 ++++++++++++++++++++++++++++++++++++++++++ src/core/sources.gypi | 1 + 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/core/mmap_win.cc diff --git a/common.gypi b/common.gypi index 0b60f4282..9624a88a6 100644 --- a/common.gypi +++ b/common.gypi @@ -153,7 +153,7 @@ }, 'msvs_settings': { 'VCCLCompilerTool': { - 'Optimization': '2', + 'Optimization': '0', 'BasicRuntimeChecks': '0', # disable /RTC1 when compiling /O2 'DebugInformationFormat': '3', 'ExceptionHandling': '0', diff --git a/src/core/mmap_win.cc b/src/core/mmap_win.cc new file mode 100644 index 000000000..3dd245252 --- /dev/null +++ b/src/core/mmap_win.cc @@ -0,0 +1,132 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + + +typedef struct xe_mmap { + xe_ref_t ref; + + HANDLE file_handle; + HANDLE mmap_handle; + + void* addr; + size_t length; +} xe_mmap_t; + + +xe_mmap_ref xe_mmap_open(xe_pal_ref pal, const xe_file_mode mode, + const xechar_t *path, + const size_t offset, const size_t length) { + xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t)); + xe_ref_init((xe_ref)mmap); + + DWORD fileAccess = 0; + DWORD fileShare = 0; + DWORD createMode = 0; + DWORD mappingProtect = 0; + DWORD viewAccess = 0; + switch (mode) { + case kXEFileModeRead: + fileAccess |= GENERIC_READ; + fileShare |= FILE_SHARE_READ; + createMode |= OPEN_EXISTING; + mappingProtect |= PAGE_READONLY; + viewAccess |= FILE_MAP_READ; + break; + case kXEFileModeWrite: + fileAccess |= GENERIC_WRITE; + fileShare |= 0; + createMode |= OPEN_ALWAYS; + mappingProtect |= PAGE_READWRITE; + viewAccess |= FILE_MAP_WRITE; + break; + case kXEFileModeRead | kXEFileModeWrite: + fileAccess |= GENERIC_READ | GENERIC_WRITE; + fileShare |= 0; + createMode |= OPEN_EXISTING; + mappingProtect |= PAGE_READWRITE; + viewAccess |= FILE_MAP_READ | FILE_MAP_WRITE; + break; + } + + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + + const size_t aligned_offset = + offset & (~(systemInfo.dwAllocationGranularity - 1)); + const size_t aligned_length = + length + (offset - aligned_offset); + + HANDLE file_handle = CreateFile( + path, fileAccess, fileShare, NULL, createMode, FILE_ATTRIBUTE_NORMAL, + NULL); + XEEXPECTNOTNULL(file_handle); + + HANDLE handle = CreateFileMapping( + file_handle, NULL, mappingProtect, 0, 0, NULL); + //(DWORD)(aligned_length >> 32), (DWORD)(aligned_length & 0xFFFFFFFF), NULL); + XEEXPECTNOTNULL(handle); + + void* address = MapViewOfFile(handle, viewAccess, + (DWORD)(aligned_offset >> 32), + (DWORD)(aligned_offset & 0xFFFFFFFF), + aligned_length); + XEEXPECTNOTNULL(address); + + mmap->file_handle = file_handle; + mmap->mmap_handle = handle; + mmap->addr = address; + if (!length) { + mmap->length = length; + } else { + size_t map_length = GetFileSize(file_handle, NULL); + mmap->length = map_length; + } + + return mmap; + +XECLEANUP: + xe_mmap_release(mmap); + return NULL; +} + +void xe_mmap_dealloc(xe_mmap_ref mmap) { + if (mmap->addr) { + UnmapViewOfFile(mmap->addr); + mmap->addr = NULL; + } + + if (mmap->mmap_handle) { + CloseHandle(mmap->mmap_handle); + mmap->mmap_handle = NULL; + } + + if (mmap->file_handle) { + CloseHandle(mmap->file_handle); + mmap->file_handle = NULL; + } +} + +xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap) { + xe_ref_retain((xe_ref)mmap); + return mmap; +} + +void xe_mmap_release(xe_mmap_ref mmap) { + xe_ref_release((xe_ref)mmap, (xe_ref_dealloc_t)xe_mmap_dealloc); +} + +void* xe_mmap_get_addr(xe_mmap_ref mmap) { + return mmap->addr; +} + +size_t xe_mmap_get_length(xe_mmap_ref mmap) { + return mmap->length; +} diff --git a/src/core/sources.gypi b/src/core/sources.gypi index b16056af9..459b11a1a 100644 --- a/src/core/sources.gypi +++ b/src/core/sources.gypi @@ -15,6 +15,7 @@ }], ['OS == "win"', { 'sources': [ + 'mmap_win.cc', ], }], ],