diff --git a/MarathonRecomp/kernel/heap.cpp b/MarathonRecomp/kernel/heap.cpp index e3330ba09..de582c27e 100644 --- a/MarathonRecomp/kernel/heap.cpp +++ b/MarathonRecomp/kernel/heap.cpp @@ -60,7 +60,6 @@ size_t Heap::Size(void* ptr) uint32_t RtlAllocateHeap(uint32_t heapHandle, uint32_t flags, uint32_t size) { void* ptr = g_userHeap.Alloc(size); - // printf("RtlAllocateHeap %x, heapHandle\n", ptr); if ((flags & 0x8) != 0) memset(ptr, 0, size); @@ -71,7 +70,6 @@ uint32_t RtlAllocateHeap(uint32_t heapHandle, uint32_t flags, uint32_t size) uint32_t RtlReAllocateHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer, uint32_t size) { void* ptr = g_userHeap.Alloc(size); - // printf("RtlReAllocateHeap %x\n", ptr); if ((flags & 0x8) != 0) memset(ptr, 0, size); @@ -88,7 +86,6 @@ uint32_t RtlReAllocateHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryP uint32_t RtlFreeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer) { - // printf("RtlFreeHeap\n"); if (memoryPointer != NULL) g_userHeap.Free(g_memory.Translate(memoryPointer)); @@ -97,7 +94,6 @@ uint32_t RtlFreeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer uint32_t RtlSizeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer) { - // printf("RtlSizeHeap\n"); if (memoryPointer != NULL) return (uint32_t)g_userHeap.Size(g_memory.Translate(memoryPointer)); @@ -110,7 +106,6 @@ uint32_t XAllocMem(uint32_t size, uint32_t flags) g_userHeap.AllocPhysical(size, (1ull << ((flags >> 24) & 0xF))) : g_userHeap.Alloc(size); - // printf("XAllocMem %x (size: %x)\n", ptr, size); if ((flags & 0x40000000) != 0) memset(ptr, 0, size); @@ -120,40 +115,25 @@ uint32_t XAllocMem(uint32_t size, uint32_t flags) void XFreeMem(uint32_t baseAddress, uint32_t flags) { - // printf("XFreeMem %x\n", baseAddress); if (baseAddress != NULL) - { g_userHeap.Free(g_memory.Translate(baseAddress)); - } - else - { - printf("XFreeMem baseAddress is null %x\n", baseAddress); - // __builtin_trap(); - } } uint32_t XVirtualAlloc(void *lpAddress, unsigned int dwSize, unsigned int flAllocationType, unsigned int flProtect) { - if (lpAddress != nullptr) - { - printf("XVirtualAlloc lpAddress is not null %p\n", lpAddress); - return 0; - } - uint32_t addr = g_memory.MapVirtual(g_userHeap.Alloc(dwSize)); - printf("XVirtualAlloc %x\n", addr); - return addr; + assert(!lpAddress); + return g_memory.MapVirtual(g_userHeap.Alloc(dwSize)); } uint32_t XVirtualFree(uint32_t lpAddress, unsigned int dwSize, unsigned int dwFreeType) { - printf("XVirtualFree %x\n", lpAddress); if ((dwFreeType & 0x8000) != 0 && dwSize) - { - return 0; - } + return FALSE; + if (lpAddress) g_userHeap.Free(g_memory.Translate(lpAddress)); - return 1; + + return TRUE; } GUEST_FUNCTION_HOOK(sub_82915668, XVirtualAlloc); diff --git a/MarathonRecomp/kernel/imports.cpp b/MarathonRecomp/kernel/imports.cpp index beebbddec..82693f353 100644 --- a/MarathonRecomp/kernel/imports.cpp +++ b/MarathonRecomp/kernel/imports.cpp @@ -19,7 +19,7 @@ #include #endif -std::vector g_doNotDestroyHandles{}; +std::unordered_map g_handleDuplicates{}; struct Event final : KernelObject, HostObject { @@ -336,7 +336,6 @@ uint32_t XGetAVPack() void XamLoaderTerminateTitle() { - printf("XamLoaderTerminateTitle\n"); LOG_UTILITY("!!! STUB !!!"); } @@ -376,7 +375,7 @@ uint32_t NtCreateFile uint32_t CreateOptions ) { - printf("NtCreateFile\n"); + LOG_UTILITY("!!! STUB !!!"); return 0; } @@ -387,10 +386,13 @@ uint32_t NtClose(uint32_t handle) if (IsKernelObject(handle)) { - auto it = std::find(g_doNotDestroyHandles.begin(), g_doNotDestroyHandles.end(), handle); - if (it == g_doNotDestroyHandles.end()) { + // If the handle was duplicated, just decrement the duplication count. Otherwise, delete the object. + const auto& it = g_handleDuplicates.find(handle); + if (it == g_handleDuplicates.end() || it->second == 0) DestroyKernelObject(handle); - } + else if (--it->second == 0) + g_handleDuplicates.erase(it); + return 0; } else @@ -432,6 +434,9 @@ uint32_t XamLoaderSetLaunchData() uint32_t NtWaitForSingleObjectEx(uint32_t Handle, uint32_t WaitMode, uint32_t Alertable, be* Timeout) { + if (Handle == GUEST_INVALID_HANDLE_VALUE) + return 0xFFFFFFFF; + uint32_t timeout = GuestTimeoutToMilliseconds(Timeout); // assert(timeout == 0 || timeout == INFINITE); @@ -555,11 +560,29 @@ void __C_specific_handler_x() LOG_UTILITY("!!! STUB !!!"); } -void RtlNtStatusToDosError(int Status) +uint32_t RtlNtStatusToDosError(uint32_t Status) { - LOG_UTILITY("!!! STUB !!!"); - printf("RtlNtStatusToDosError: %x\n", Status); - // __builtin_trap(); + // See https://github.com/wine-mirror/wine/blob/master/dlls/ntdll/error.c#L47-L64 + if (Status == 0 || (Status & 0x20000000) != 0) + return Status; + + if ((Status & 0xF0000000) == 0xD0000000) + Status &= ~0x10000000; + + const uint32_t hi = (Status >> 16) & 0xFFFF; + if (hi == 0x8007 || hi == 0xC001 || hi == 0xC007) + return Status & 0xFFFF; + + switch (Status) + { + case STATUS_NOT_IMPLEMENTED: + return ERROR_CALL_NOT_IMPLEMENTED; + case STATUS_SEMAPHORE_LIMIT_EXCEEDED: + return ERROR_TOO_MANY_POSTS; + default: + LOGF_WARNING("Unimplemented NtStatus translation: {:#08x}", Status); + return Status; + } } void XexGetProcedureAddress() @@ -642,20 +665,28 @@ void NtReadFile() LOG_UTILITY("!!! STUB !!!"); } -int NtDuplicateObject(uint32_t sourceHandle, be* targetHandle, uint32_t options) +uint32_t NtDuplicateObject(uint32_t SourceHandle, be* TargetHandle, uint32_t Options) { - auto obj = GetKernelObject(sourceHandle); - // HACK: Duplicating handle doesn't supported now, so we just these handles to array to ignore of closing these handles - printf("NtDuplicateObject: %x %x %d, obj: %x\n", sourceHandle, targetHandle, options, obj); - auto it = std::find(g_doNotDestroyHandles.begin(), g_doNotDestroyHandles.end(), sourceHandle); - if (it == g_doNotDestroyHandles.end()) { - g_doNotDestroyHandles.push_back(sourceHandle); + if (SourceHandle == GUEST_INVALID_HANDLE_VALUE) + return 0xFFFFFFFF; + + if (IsKernelObject(SourceHandle)) + { + // Increment handle duplicate count. + const auto& it = g_handleDuplicates.find(SourceHandle); + if (it != g_handleDuplicates.end()) + ++it->second; + else + g_handleDuplicates[SourceHandle] = 1; + + *TargetHandle = SourceHandle; + return 0; + } + else + { + assert(false && "Unrecognized kernel object."); + return 0xFFFFFFFF; } - if (!obj) return -1; - uint32_t newHandle = 0; - newHandle = sourceHandle; - *targetHandle = newHandle; - return 0; } void NtAllocateVirtualMemory() @@ -758,13 +789,11 @@ void RtlEnterCriticalSection(XRTL_CRITICAL_SECTION* cs) void RtlImageXexHeaderField() { - printf("RtlImageXexHeaderField\n"); LOG_UTILITY("!!! STUB !!!"); } void HalReturnToFirmware() { - printf("HalReturnToFirmware\n"); LOG_UTILITY("!!! STUB !!!"); } @@ -909,7 +938,7 @@ void sprintf_x() int32_t ExRegisterTitleTerminateNotification(uint32_t* reg, uint32_t create) { - printf("ExRegisterTitleTerminateNotification: %x %d\n", reg, create); + LOG_UTILITY("!!! STUB !!!"); return 0; } @@ -1111,7 +1140,6 @@ uint32_t KeTlsGetValue(uint32_t dwTlsIndex) uint32_t KeTlsSetValue(uint32_t dwTlsIndex, uint32_t lpTlsValue) { - printf("KeTlsSetValue\n"); KeTlsGetValueRef(dwTlsIndex) = lpTlsValue; return TRUE; } diff --git a/MarathonRecomp/kernel/io/file_system.cpp b/MarathonRecomp/kernel/io/file_system.cpp index fa0a25d82..c9a8af4fb 100644 --- a/MarathonRecomp/kernel/io/file_system.cpp +++ b/MarathonRecomp/kernel/io/file_system.cpp @@ -91,7 +91,6 @@ FileHandle* XCreateFileA uint32_t dwFlagsAndAttributes ) { - printf("XCreateFileA %s\n", lpFileName); assert(((dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE | FILE_READ_DATA)) == 0) && "Unknown desired access bits."); assert(((dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) == 0) && "Unknown share mode bits."); assert(((dwCreationDisposition & ~(CREATE_NEW | CREATE_ALWAYS)) == 0) && "Unknown creation disposition bits."); @@ -148,7 +147,6 @@ FileHandle* XCreateFileA static uint32_t XGetFileSizeA(FileHandle* hFile, be* lpFileSizeHigh) { - printf("XGetFileSizeA %x\n", hFile); std::error_code ec; auto fileSize = std::filesystem::file_size(hFile->path, ec); if (!ec) @@ -190,7 +188,6 @@ uint32_t XReadFile XOVERLAPPED* lpOverlapped ) { - // printf("XReadFile %x %d\n", hFile, nNumberOfBytesToRead); uint32_t result = FALSE; if (lpOverlapped != nullptr) { @@ -248,11 +245,6 @@ uint32_t XSetFilePointer(FileHandle* hFile, int32_t lDistanceToMove, be break; } - // if (!hFile) { - printf("XSetFilePointer %x %d %d %d %d\n", hFile, lDistanceToMove, distanceToMoveHigh, dwMoveMethod, streamSeekDir); - // return INVALID_SET_FILE_POINTER; - // } - hFile->stream.clear(); hFile->stream.seekg(streamOffset, streamSeekDir); if (hFile->stream.bad()) @@ -263,7 +255,7 @@ uint32_t XSetFilePointer(FileHandle* hFile, int32_t lDistanceToMove, be std::streampos streamPos = hFile->stream.tellg(); if (lpDistanceToMoveHigh != nullptr) *lpDistanceToMoveHigh = int32_t(streamPos >> 32U); - printf("XSetFilePointer streamPos: %d\n", streamPos); + return uint32_t(streamPos); } diff --git a/MarathonRecomp/kernel/xam.cpp b/MarathonRecomp/kernel/xam.cpp index 59570162b..eac6f6b38 100644 --- a/MarathonRecomp/kernel/xam.cpp +++ b/MarathonRecomp/kernel/xam.cpp @@ -314,7 +314,6 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const uint32_t dwContentFlags, be* pdwDisposition, be* pdwLicenseMask, uint32_t dwFileCacheSize, uint64_t uliContentSize, PXXOVERLAPPED pOverlapped) { - printf("XamContentCreateEx: %d, %s %d\n", dwUserIndex, szRootName, dwContentFlags); const auto& registry = gContentRegistry[pContentData->dwContentType - 1]; const auto exists = registry.contains(StringHash(pContentData->szFileName)); const auto mode = dwContentFlags & 0xF; diff --git a/MarathonRecomp/kernel/xdm.h b/MarathonRecomp/kernel/xdm.h index b001970bf..c477df607 100644 --- a/MarathonRecomp/kernel/xdm.h +++ b/MarathonRecomp/kernel/xdm.h @@ -14,8 +14,9 @@ #define STATUS_SUCCESS 0x00000000 #define STATUS_WAIT_0 0x00000000 #define STATUS_USER_APC 0x000000C0 -#define STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047 #define STATUS_TIMEOUT 0x00000102 +#define STATUS_NOT_IMPLEMENTED 0xC0000002 +#define STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047 #define STATUS_FAIL_CHECK 0xC0000229 #define INFINITE 0xFFFFFFFF #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 @@ -40,7 +41,9 @@ #define ERROR_PATH_NOT_FOUND 0x3 #define ERROR_ACCESS_DENIED 0x5 #define ERROR_FILE_EXISTS 0x50 +#define ERROR_CALL_NOT_IMPLEMENTED 0x78 #define ERROR_BAD_ARGUMENTS 0xA0 +#define ERROR_TOO_MANY_POSTS 0x12A #define ERROR_DEVICE_NOT_CONNECTED 0x48F #define PAGE_READWRITE 0x04