diff --git a/UnleashedRecomp/kernel/heap.h b/UnleashedRecomp/kernel/heap.h index 4e583be5..1710c298 100644 --- a/UnleashedRecomp/kernel/heap.h +++ b/UnleashedRecomp/kernel/heap.h @@ -19,7 +19,7 @@ struct Heap size_t Size(void* ptr); template - T* Alloc(Args... args) + T* Alloc(Args&&... args) { T* obj = (T*)Alloc(sizeof(T)); new (obj) T(std::forward(args)...); @@ -27,7 +27,7 @@ struct Heap } template - T* AllocPhysical(Args... args) + T* AllocPhysical(Args&&... args) { T* obj = (T*)AllocPhysical(sizeof(T), alignof(T)); new (obj) T(std::forward(args)...); diff --git a/UnleashedRecomp/kernel/imports.cpp b/UnleashedRecomp/kernel/imports.cpp index 542f0971..a9344130 100644 --- a/UnleashedRecomp/kernel/imports.cpp +++ b/UnleashedRecomp/kernel/imports.cpp @@ -23,7 +23,7 @@ inline void CloseKernelObject(XDISPATCHER_HEADER& header) return; } - ObCloseHandle(header.WaitListHead.Blink); + DestroyKernelObject(header.WaitListHead.Blink); } DWORD GuestTimeoutToMilliseconds(XLPQWORD timeout) @@ -232,12 +232,12 @@ DWORD NtCreateFile uint32_t NtClose(uint32_t handle) { - if (handle == (uint32_t)INVALID_HANDLE_VALUE) + if (handle == GUEST_INVALID_HANDLE_VALUE) return 0xFFFFFFFF; - if (CHECK_GUEST_HANDLE(handle)) + if (IsKernelObject(handle)) { - ObCloseHandle(HOST_HANDLE(handle)); + DestroyKernelObject(handle); return 0; } @@ -531,7 +531,7 @@ uint32_t KeSetAffinityThread(DWORD Thread, DWORD Affinity, XLPDWORD lpPreviousAf return 0; } -struct Event : HostObject +struct Event : KernelObject, HostObject { HANDLE handle; @@ -551,7 +551,7 @@ struct Event : HostObject } }; -struct Semaphore : HostObject +struct Semaphore : KernelObject, HostObject { HANDLE handle; @@ -866,12 +866,12 @@ void KeUnlockL2() bool KeSetEvent(XKEVENT* pEvent, DWORD Increment, bool Wait) { - return ObQueryObject(*pEvent)->Set(); + return QueryKernelObject(*pEvent)->Set(); } bool KeResetEvent(XKEVENT* pEvent) { - return ObQueryObject(*pEvent)->Reset(); + return QueryKernelObject(*pEvent)->Reset(); } DWORD KeWaitForSingleObject(XDISPATCHER_HEADER* Object, DWORD WaitReason, DWORD WaitMode, bool Alertable, XLPQWORD Timeout) @@ -884,11 +884,11 @@ DWORD KeWaitForSingleObject(XDISPATCHER_HEADER* Object, DWORD WaitReason, DWORD { case 0: case 1: - handle = ObQueryObject(*Object)->handle; + handle = QueryKernelObject(*Object)->handle; break; case 5: - handle = ObQueryObject(*Object)->handle; + handle = QueryKernelObject(*Object)->handle; break; default: @@ -1340,7 +1340,7 @@ DWORD KeWaitForMultipleObjects(DWORD Count, xpointer* Object for (size_t i = 0; i < Count; i++) { assert(Objects[i]->Type <= 1); - events[i] = ObQueryObject(*Objects[i].get())->handle; + events[i] = QueryKernelObject(*Objects[i].get())->handle; } return WaitForMultipleObjectsEx(Count, events.data(), WaitType == 0, timeout, Alertable); @@ -1355,7 +1355,7 @@ void KfLowerIrql() { } uint32_t KeReleaseSemaphore(XKSEMAPHORE* semaphore, uint32_t increment, uint32_t adjustment, uint32_t wait) { - auto* object = ObQueryObject(semaphore->Header); + auto* object = QueryKernelObject(semaphore->Header); return ReleaseSemaphore(object->handle, adjustment, nullptr) ? 0 : 0xFFFFFFFF; } @@ -1382,7 +1382,7 @@ void KeInitializeSemaphore(XKSEMAPHORE* semaphore, uint32_t count, uint32_t limi semaphore->Header.SignalState = count; semaphore->Limit = limit; - auto* object = ObQueryObject(semaphore->Header); + auto* object = QueryKernelObject(semaphore->Header); } void XMAReleaseContext() diff --git a/UnleashedRecomp/kernel/io/file_system.cpp b/UnleashedRecomp/kernel/io/file_system.cpp index 8c668806..cbac37bb 100644 --- a/UnleashedRecomp/kernel/io/file_system.cpp +++ b/UnleashedRecomp/kernel/io/file_system.cpp @@ -6,15 +6,13 @@ #include #include -static constexpr uint32_t GUEST_INVALID_HANDLE_VALUE = 0xFFFFFFFF; - -struct FileHandle +struct FileHandle : KernelObject { std::fstream stream; std::filesystem::path path; }; -struct FindHandle +struct FindHandle : KernelObject { std::filesystem::path searchPath; std::filesystem::directory_iterator iterator; @@ -37,19 +35,7 @@ struct FindHandle } }; -bool FileHandleCloser(void* handle) -{ - delete (FileHandle *)(handle); - return false; -} - -bool FindHandleCloser(void* handle) -{ - delete (FindHandle *)(handle); - return false; -} - -SWA_API uint32_t XCreateFileA +SWA_API FileHandle* XCreateFileA ( LPCSTR lpFileName, DWORD dwDesiredAccess, @@ -82,89 +68,75 @@ SWA_API uint32_t XCreateFileA #ifdef _WIN32 GuestThread::SetLastError(GetLastError()); #endif - return GUEST_INVALID_HANDLE_VALUE; + return GetInvalidKernelObject(); } - FileHandle *fileHandle = new FileHandle(); + FileHandle *fileHandle = CreateKernelObject(); fileHandle->stream = std::move(fileStream); fileHandle->path = std::move(filePath); - return GUEST_HANDLE(ObInsertObject(fileHandle, FileHandleCloser)); + return fileHandle; } -static DWORD XGetFileSizeA(uint32_t hFile, LPDWORD lpFileSizeHigh) +static DWORD XGetFileSizeA(FileHandle* hFile, LPDWORD lpFileSizeHigh) { - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle != nullptr) + std::error_code ec; + auto fileSize = std::filesystem::file_size(hFile->path, ec); + if (!ec) { - std::error_code ec; - auto fileSize = std::filesystem::file_size(handle->path, ec); - if (!ec) + if (lpFileSizeHigh != nullptr) { - if (lpFileSizeHigh != nullptr) - { - *lpFileSizeHigh = ByteSwap(DWORD(fileSize >> 32U)); - } - - return (DWORD)(fileSize); + *lpFileSizeHigh = ByteSwap(DWORD(fileSize >> 32U)); } + + return (DWORD)(fileSize); } return INVALID_FILE_SIZE; } -BOOL XGetFileSizeExA(uint32_t hFile, PLARGE_INTEGER lpFileSize) +BOOL XGetFileSizeExA(FileHandle* hFile, PLARGE_INTEGER lpFileSize) { - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle != nullptr) + std::error_code ec; + auto fileSize = std::filesystem::file_size(hFile->path, ec); + if (!ec) { - std::error_code ec; - auto fileSize = std::filesystem::file_size(handle->path, ec); - if (!ec) + if (lpFileSize != nullptr) { - if (lpFileSize != nullptr) - { - lpFileSize->QuadPart = ByteSwap(fileSize); - } - - return 1; + lpFileSize->QuadPart = ByteSwap(fileSize); } + + return TRUE; } - return 0; + return FALSE; } BOOL XReadFile ( - uint32_t hFile, + FileHandle* hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, XLPDWORD lpNumberOfBytesRead, XOVERLAPPED* lpOverlapped ) { - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle == nullptr) - { - return FALSE; - } - BOOL result = FALSE; if (lpOverlapped != nullptr) { std::streamoff streamOffset = lpOverlapped->Offset + (std::streamoff(lpOverlapped->OffsetHigh.get()) << 32U); - handle->stream.clear(); - handle->stream.seekg(streamOffset, std::ios::beg); - if (handle->stream.bad()) + hFile->stream.clear(); + hFile->stream.seekg(streamOffset, std::ios::beg); + if (hFile->stream.bad()) { return FALSE; } } DWORD numberOfBytesRead; - handle->stream.read((char *)(lpBuffer), nNumberOfBytesToRead); - if (!handle->stream.bad()) + hFile->stream.read((char *)(lpBuffer), nNumberOfBytesToRead); + if (!hFile->stream.bad()) { - numberOfBytesRead = DWORD(handle->stream.gcount()); + numberOfBytesRead = DWORD(hFile->stream.gcount()); result = TRUE; } @@ -187,14 +159,8 @@ BOOL XReadFile return result; } -DWORD XSetFilePointer(uint32_t hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) +DWORD XSetFilePointer(FileHandle* hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) { - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle == nullptr) - { - return INVALID_SET_FILE_POINTER; - } - LONG distanceToMoveHigh = lpDistanceToMoveHigh ? ByteSwap(*lpDistanceToMoveHigh) : 0; std::streamoff streamOffset = lDistanceToMove + (std::streamoff(distanceToMoveHigh) << 32U); std::fstream::seekdir streamSeekDir = {}; @@ -214,28 +180,22 @@ DWORD XSetFilePointer(uint32_t hFile, LONG lDistanceToMove, PLONG lpDistanceToMo break; } - handle->stream.clear(); - handle->stream.seekg(streamOffset, streamSeekDir); - if (handle->stream.bad()) + hFile->stream.clear(); + hFile->stream.seekg(streamOffset, streamSeekDir); + if (hFile->stream.bad()) { return INVALID_SET_FILE_POINTER; } - std::streampos streamPos = handle->stream.tellg(); + std::streampos streamPos = hFile->stream.tellg(); if (lpDistanceToMoveHigh != nullptr) *lpDistanceToMoveHigh = ByteSwap(LONG(streamPos >> 32U)); return DWORD(streamPos); } -BOOL XSetFilePointerEx(uint32_t hFile, LONG lDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) +BOOL XSetFilePointerEx(FileHandle* hFile, LONG lDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) { - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle == nullptr) - { - return FALSE; - } - std::fstream::seekdir streamSeekDir = {}; switch (dwMoveMethod) { @@ -253,27 +213,27 @@ BOOL XSetFilePointerEx(uint32_t hFile, LONG lDistanceToMove, PLARGE_INTEGER lpNe break; } - handle->stream.clear(); - handle->stream.seekg(lDistanceToMove, streamSeekDir); - if (handle->stream.bad()) + hFile->stream.clear(); + hFile->stream.seekg(lDistanceToMove, streamSeekDir); + if (hFile->stream.bad()) { return FALSE; } if (lpNewFilePointer != nullptr) { - lpNewFilePointer->QuadPart = ByteSwap(LONGLONG(handle->stream.tellg())); + lpNewFilePointer->QuadPart = ByteSwap(LONGLONG(hFile->stream.tellg())); } return TRUE; } -uint32_t XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) +FindHandle* XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) { const char *transformedPath = FileSystem::TransformPath(lpFileName); size_t transformedPathLength = strlen(transformedPath); if (transformedPathLength == 0) - return GUEST_INVALID_HANDLE_VALUE; + return (FindHandle*)GUEST_INVALID_HANDLE_VALUE; std::filesystem::path dirPath; if (strstr(transformedPath, "\\*") == (&transformedPath[transformedPathLength - 2])) @@ -291,56 +251,48 @@ uint32_t XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) } if (!std::filesystem::is_directory(dirPath)) - return GUEST_INVALID_HANDLE_VALUE; + return GetInvalidKernelObject(); std::filesystem::directory_iterator dirIterator(dirPath); if (dirIterator == std::filesystem::directory_iterator()) - return GUEST_INVALID_HANDLE_VALUE; + return GetInvalidKernelObject(); - FindHandle *findHandle = new FindHandle(); + FindHandle *findHandle = CreateKernelObject(); findHandle->searchPath = std::move(dirPath); findHandle->iterator = std::move(dirIterator); findHandle->fillFindData(lpFindFileData); - return GUEST_HANDLE(ObInsertObject(findHandle, FindHandleCloser)); + return findHandle; } -uint32_t XFindNextFileA(uint32_t Handle, LPWIN32_FIND_DATAA lpFindFileData) +BOOL XFindNextFileA(FindHandle* Handle, LPWIN32_FIND_DATAA lpFindFileData) { - FindHandle *findHandle = (FindHandle *)(ObQueryObject(HOST_HANDLE(Handle))); - if (findHandle == nullptr) - return FALSE; + Handle->iterator++; - findHandle->iterator++; - - if (findHandle->iterator == std::filesystem::directory_iterator()) + if (Handle->iterator == std::filesystem::directory_iterator()) { return FALSE; } else { - findHandle->fillFindData(lpFindFileData); + Handle->fillFindData(lpFindFileData); return TRUE; } } -BOOL XReadFileEx(uint32_t hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, XOVERLAPPED* lpOverlapped, uint32_t lpCompletionRoutine) +BOOL XReadFileEx(FileHandle* hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, XOVERLAPPED* lpOverlapped, uint32_t lpCompletionRoutine) { - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle == nullptr) - return FALSE; - BOOL result = FALSE; DWORD numberOfBytesRead; std::streamoff streamOffset = lpOverlapped->Offset + (std::streamoff(lpOverlapped->OffsetHigh.get()) << 32U); - handle->stream.clear(); - handle->stream.seekg(streamOffset, std::ios::beg); - if (handle->stream.bad()) + hFile->stream.clear(); + hFile->stream.seekg(streamOffset, std::ios::beg); + if (hFile->stream.bad()) return FALSE; - handle->stream.read((char *)(lpBuffer), nNumberOfBytesToRead); - if (!handle->stream.bad()) + hFile->stream.read((char *)(lpBuffer), nNumberOfBytesToRead); + if (!hFile->stream.bad()) { - numberOfBytesRead = DWORD(handle->stream.gcount()); + numberOfBytesRead = DWORD(hFile->stream.gcount()); result = TRUE; } @@ -367,20 +319,16 @@ DWORD XGetFileAttributesA(LPCSTR lpFileName) return INVALID_FILE_ATTRIBUTES; } -BOOL XWriteFile(uint32_t hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) +BOOL XWriteFile(FileHandle* hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { assert(lpOverlapped == nullptr && "Overlapped not implemented."); - FileHandle *handle = (FileHandle *)(ObQueryObject(HOST_HANDLE(hFile))); - if (handle == nullptr) - return FALSE; - - handle->stream.write((const char *)(lpBuffer), nNumberOfBytesToWrite); - if (handle->stream.bad()) + hFile->stream.write((const char *)(lpBuffer), nNumberOfBytesToWrite); + if (hFile->stream.bad()) return FALSE; if (lpNumberOfBytesWritten != nullptr) - *lpNumberOfBytesWritten = DWORD(handle->stream.gcount()); + *lpNumberOfBytesWritten = DWORD(hFile->stream.gcount()); return TRUE; } diff --git a/UnleashedRecomp/kernel/xam.cpp b/UnleashedRecomp/kernel/xam.cpp index 9541b4dc..f71df084 100644 --- a/UnleashedRecomp/kernel/xam.cpp +++ b/UnleashedRecomp/kernel/xam.cpp @@ -13,6 +13,79 @@ // Needed for commctrl #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +struct XamListener : KernelObject +{ + uint32_t id{}; + uint64_t areas{}; + std::vector> notifications; + + XamListener(const XamListener&) = delete; + XamListener& operator=(const XamListener&) = delete; + + XamListener(); + ~XamListener(); +}; + +struct XamEnumeratorBase : KernelObject +{ + virtual uint32_t Next(void* buffer) + { + return -1; + } +}; + +template::iterator> +struct XamEnumerator : XamEnumeratorBase +{ + uint32_t fetch; + size_t size; + TIterator position; + TIterator begin; + TIterator end; + + XamEnumerator() = default; + XamEnumerator(uint32_t fetch, size_t size, TIterator begin, TIterator end) : fetch(fetch), size(size), position(begin), begin(begin), end(end) + { + + } + + uint32_t Next(void* buffer) override + { + if (position == end) + { + return -1; + } + + if (buffer == nullptr) + { + for (size_t i = 0; i < fetch; i++) + { + if (position == end) + { + return i == 0 ? -1 : i; + } + + ++position; + } + } + + for (size_t i = 0; i < fetch; i++) + { + if (position == end) + { + return i == 0 ? -1 : i; + } + + memcpy(buffer, &*position, size); + + ++position; + buffer = (void*)((size_t)buffer + size); + } + + return fetch; + } +}; + std::array, 3> gContentRegistry{}; std::unordered_set gListeners{}; xxHashMap gRootMap; @@ -69,12 +142,11 @@ void XamRegisterContent(DWORD type, const std::string_view name, const std::stri SWA_API DWORD XamNotifyCreateListener(uint64_t qwAreas) { - int handle; - auto* listener = ObCreateObject(handle); + auto* listener = CreateKernelObject(); listener->areas = qwAreas; - return GUEST_HANDLE(handle); + return GetKernelHandle(listener); } SWA_API void XamNotifyEnqueueEvent(DWORD dwId, DWORD dwParam) @@ -90,7 +162,7 @@ SWA_API void XamNotifyEnqueueEvent(DWORD dwId, DWORD dwParam) SWA_API bool XNotifyGetNext(DWORD hNotification, DWORD dwMsgFilter, XDWORD* pdwId, XDWORD* pParam) { - auto& listener = *ObTryQueryObject(HOST_HANDLE(hNotification)); + auto& listener = *GetKernelObject(hNotification); if (dwMsgFilter) { @@ -188,19 +260,19 @@ SWA_API uint32_t XamContentCreateEnumerator(DWORD dwUserIndex, DWORD DeviceID, D const auto& registry = gContentRegistry[dwContentType - 1]; const auto& values = registry | std::views::values; - const int handle = ObInsertObject(new XamEnumerator(cItem, sizeof(_XCONTENT_DATA), values.begin(), values.end())); + auto* enumerator = CreateKernelObject>(cItem, sizeof(_XCONTENT_DATA), values.begin(), values.end()); if (pcbBuffer) *pcbBuffer = sizeof(_XCONTENT_DATA) * cItem; - *phEnum = GUEST_HANDLE(handle); + *phEnum = GetKernelHandle(enumerator); return 0; } SWA_API uint32_t XamEnumerate(uint32_t hEnum, DWORD dwFlags, PVOID pvBuffer, DWORD cbBuffer, XLPDWORD pcItemsReturned, XXOVERLAPPED* pOverlapped) { - auto* enumerator = ObTryQueryObject(HOST_HANDLE(hEnum)); + auto* enumerator = GetKernelObject(hEnum); const auto count = enumerator->Next(pvBuffer); if (count == -1) diff --git a/UnleashedRecomp/kernel/xam.h b/UnleashedRecomp/kernel/xam.h index 6fd7e262..9fe26b81 100644 --- a/UnleashedRecomp/kernel/xam.h +++ b/UnleashedRecomp/kernel/xam.h @@ -5,82 +5,6 @@ #define MSG_AREA(msgid) (((msgid) >> 16) & 0xFFFF) #define MSG_NUMBER(msgid) ((msgid) & 0xFFFF) -struct XamListener -{ - uint32_t id{}; - uint64_t areas{}; - std::vector> notifications; - - XamListener(const XamListener&) = delete; - XamListener& operator=(const XamListener&) = delete; - - XamListener(); - ~XamListener(); -}; - -class XamEnumeratorBase -{ -public: - virtual ~XamEnumeratorBase() = default; - virtual uint32_t Next(void* buffer) - { - return -1; - } -}; - -template::iterator> -class XamEnumerator : public XamEnumeratorBase -{ -public: - uint32_t fetch; - size_t size; - TIterator position; - TIterator begin; - TIterator end; - - XamEnumerator() = default; - XamEnumerator(uint32_t fetch, size_t size, TIterator begin, TIterator end) : fetch(fetch), size(size), position(begin), begin(begin), end(end) - { - - } - - uint32_t Next(void* buffer) override - { - if (position == end) - { - return -1; - } - - if (buffer == nullptr) - { - for (size_t i = 0; i < fetch; i++) - { - if (position == end) - { - return i == 0 ? -1 : i; - } - - ++position; - } - } - - for (size_t i = 0; i < fetch; i++) - { - if (position == end) - { - return i == 0 ? -1 : i; - } - - memcpy(buffer, &*position, size); - - ++position; - buffer = (void*)((size_t)buffer + size); - } - - return fetch; - } -}; - XCONTENT_DATA XamMakeContent(DWORD type, const std::string_view& name); void XamRegisterContent(const XCONTENT_DATA& data, const std::string_view& root); diff --git a/UnleashedRecomp/kernel/xdm.cpp b/UnleashedRecomp/kernel/xdm.cpp index 10a99b19..9285ec5a 100644 --- a/UnleashedRecomp/kernel/xdm.cpp +++ b/UnleashedRecomp/kernel/xdm.cpp @@ -2,47 +2,36 @@ #include "xdm.h" #include "freelist.h" -FreeList, TypeDestructor_t>> gKernelObjects; -Mutex gKernelLock; +Mutex g_kernelLock; -void* ObQueryObject(size_t handle) +void DestroyKernelObject(KernelObject* obj) { - std::lock_guard guard{ gKernelLock }; - - if (handle >= gKernelObjects.items.size()) - return nullptr; - - return std::get<0>(gKernelObjects[handle]).get(); + obj->~KernelObject(); + g_userHeap.Free(obj); } -uint32_t ObInsertObject(void* object, TypeDestructor_t destructor) +uint32_t GetKernelHandle(KernelObject* obj) { - std::lock_guard guard{ gKernelLock }; - - const auto handle = gKernelObjects.Alloc(); - - auto& holder = gKernelObjects[handle]; - - std::get<0>(holder).reset(static_cast(object)); - std::get<1>(holder) = destructor; - - return handle; + assert(obj != GetInvalidKernelObject()); + return g_memory.MapVirtual(obj); } -void ObCloseHandle(uint32_t handle) +void DestroyKernelObject(uint32_t handle) { - std::lock_guard guard{ gKernelLock }; - - auto& obj = gKernelObjects[handle]; - - if (std::get<1>(obj)(std::get<0>(obj).get())) - { - std::get<0>(obj).reset(); - } - else - { - std::get<0>(obj).release(); - } - - gKernelObjects.Free(handle); + DestroyKernelObject(GetKernelObject(handle)); +} + +bool IsKernelObject(uint32_t handle) +{ + return (handle & 0x80000000) != 0; +} + +bool IsKernelObject(void* obj) +{ + return IsKernelObject(g_memory.MapVirtual(obj)); +} + +bool IsInvalidKernelObject(void* obj) +{ + return obj == GetInvalidKernelObject(); } diff --git a/UnleashedRecomp/kernel/xdm.h b/UnleashedRecomp/kernel/xdm.h index 32ffaa4e..afd02da2 100644 --- a/UnleashedRecomp/kernel/xdm.h +++ b/UnleashedRecomp/kernel/xdm.h @@ -1,56 +1,73 @@ #pragma once -#define DUMMY_HANDLE (DWORD)('HAND') -#define OBJECT_SIGNATURE (DWORD)'XBOX' -extern Mutex gKernelLock; +#include "heap.h" +#include "memory.h" -void* ObQueryObject(size_t handle); -uint32_t ObInsertObject(void* object, TypeDestructor_t destructor); -void ObCloseHandle(uint32_t handle); +#define OBJECT_SIGNATURE (DWORD)'XBOX' +#define GUEST_INVALID_HANDLE_VALUE 0xFFFFFFFF + +struct KernelObject +{ + virtual ~KernelObject() + { + ; + } +}; + +template +inline T* CreateKernelObject(Args&&... args) +{ + static_assert(std::is_base_of_v); + return g_userHeap.AllocPhysical(std::forward(args)...); +} + +template +inline T* GetKernelObject(uint32_t handle) +{ + assert(handle != GUEST_INVALID_HANDLE_VALUE); + return reinterpret_cast(g_memory.Translate(handle)); +} + +uint32_t GetKernelHandle(KernelObject* obj); + +void DestroyKernelObject(KernelObject* obj); +void DestroyKernelObject(uint32_t handle); + +bool IsKernelObject(uint32_t handle); +bool IsKernelObject(void* obj); + +bool IsInvalidKernelObject(void* obj); + +template +inline T* GetInvalidKernelObject() +{ + return reinterpret_cast(g_memory.Translate(GUEST_INVALID_HANDLE_VALUE)); +} + +extern Mutex g_kernelLock; template -T* ObQueryObject(XDISPATCHER_HEADER& header) +inline T* QueryKernelObject(XDISPATCHER_HEADER& header) { - std::lock_guard guard{ gKernelLock }; + std::lock_guard guard{ g_kernelLock }; if (header.WaitListHead.Flink != OBJECT_SIGNATURE) { header.WaitListHead.Flink = OBJECT_SIGNATURE; - auto* obj = new T(reinterpret_cast(&header)); - header.WaitListHead.Blink = ObInsertObject(obj, DestroyObject); + auto* obj = CreateKernelObject(reinterpret_cast(&header)); + header.WaitListHead.Blink = g_memory.MapVirtual(obj); return obj; } - return static_cast(ObQueryObject(header.WaitListHead.Blink.get())); -} - -template -size_t ObInsertObject(T* object) -{ - return ObInsertObject(object, DestroyObject); -} - -template -T* ObCreateObject(int& handle) -{ - auto* obj = new T(); - handle = ::ObInsertObject(obj, DestroyObject); - - return obj; + return static_cast(g_memory.Translate(header.WaitListHead.Blink.get())); } // Get object without initialisation template -T* ObTryQueryObject(XDISPATCHER_HEADER& header) +inline T* TryQueryKernelObject(XDISPATCHER_HEADER& header) { if (header.WaitListHead.Flink != OBJECT_SIGNATURE) return nullptr; - return static_cast(ObQueryObject(header.WaitListHead.Blink)); + return static_cast(g_memory.Translate(header.WaitListHead.Blink.get())); } - -template -T* ObTryQueryObject(int handle) -{ - return static_cast(ObQueryObject(handle)); -} \ No newline at end of file