diff --git a/projects/WinDurango.D3D11X/CMakeLists.txt b/projects/WinDurango.D3D11X/CMakeLists.txt index 7594aef..7b91182 100644 --- a/projects/WinDurango.D3D11X/CMakeLists.txt +++ b/projects/WinDurango.D3D11X/CMakeLists.txt @@ -4,6 +4,8 @@ project(WinDurango.D3D11X VERSION 1.0.0) set(VERSION_SUFFIX "-dev.1") # used for non-stable versions, otherwise blank set(CMAKE_CXX_STANDARD 20) +find_package(directxtex CONFIG REQUIRED) + set(FILES src/d3d11.x.cpp src/IGraphicsUnknown.cpp @@ -19,11 +21,14 @@ set(FILES add_library(WinDurango.D3D11X SHARED ${FILES} "include/WinDurango.D3D11X/ID3D11DeviceChild.h" "src/ID3D11DeviceChild.cpp" "include/WinDurango.D3D11X/ID3D11Resource.h" "src/ID3D11Resource.cpp" "include/WinDurango.D3D11X/ID3D11Shader.h" "src/ID3D11Shader.cpp" "include/WinDurango.D3D11X/ID3D11State.h" "src/ID3D11State.cpp" "include/WinDurango.D3D11X/ID3D11View.h" "src/ID3D11View.cpp" "include/WinDurango.D3D11X/ID3D11DeviceContext.h" "src/ID3D11DeviceContext.cpp" "include/WinDurango.D3D11X/ID3D11DMAEngineContext.h" "src/ID3D11DMAEngineContext.cpp" "include/WinDurango.D3D11X/ID3D11Device.h" "src/ID3D11Device.cpp" "include/WinDurango.D3D11X/ID3D11Runtime.h" "src/dllmain.cpp" "include/WinDurango.D3D11X/IDXGIAdapter.h" "include/WinDurango.D3D11X/IDXGIDevice.h" "include/WinDurango.D3D11X/IDXGIFactory.h" "include/WinDurango.D3D11X/IDXGISwapChain.h" "src/IDXGIAdapter.cpp" "src/IDXGIDevice.cpp" "src/IDXGIFactory.cpp" "src/IDXGISwapChain.cpp" ) target_link_libraries(WinDurango.D3D11X PRIVATE WinDurango.Common) +target_link_libraries(WinDurango.D3D11X PRIVATE WinDurango.KernelX) +target_link_libraries(WinDurango.D3D11X PRIVATE Microsoft::DirectXTex) target_include_directories(WinDurango.D3D11X PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.D3D11X/ ../WinDurango.Common/include/ ../WinDurango.KernelX/include/WinDurango.KernelX/ + ${CMAKE_SOURCE_DIR}/vcpkg_installed/vcpkg/pkgs/directxtex_x64-windows/include ) target_link_options(WinDurango.D3D11X diff --git a/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/ID3D11Runtime.h b/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/ID3D11Runtime.h index 1735b59..423dc3c 100644 --- a/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/ID3D11Runtime.h +++ b/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/ID3D11Runtime.h @@ -20,7 +20,7 @@ template struct D3D11Runtime : public ID3D11Runtime D3D_FEATURE_LEVEL FeatureLevels[] = {D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0}; - auto hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, FeatureLevels, 2, D3D11_SDK_VERSION, + auto hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_DEBUG, FeatureLevels, 2, D3D11_SDK_VERSION, &pDevice, nullptr, &pContext); if (FAILED(hr)) diff --git a/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/d3d11.x.h b/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/d3d11.x.h index 667ce27..1eb7b73 100644 --- a/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/d3d11.x.h +++ b/projects/WinDurango.D3D11X/include/WinDurango.D3D11X/d3d11.x.h @@ -12,6 +12,7 @@ #include #include #include +#include // We use that to know the OS version. abi_t g_ABI{}; @@ -72,99 +73,12 @@ void GetCombaseVersion() g_ABI.Revision = revision; } -inline bool IsBlockCompressed(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return true; - default: - return false; - } -} - -inline uint32_t BytesPerBlock(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - return 8; - - default: - return 16; - } -} - -inline uint32_t BytesPerPixel(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R8_UNORM: - return 1; - case DXGI_FORMAT_R8G8_UNORM: - return 2; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return 4; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return 4; - case DXGI_FORMAT_R16_FLOAT: - return 2; - case DXGI_FORMAT_R16G16_FLOAT: - return 4; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return 8; - case DXGI_FORMAT_R32_FLOAT: - return 4; - case DXGI_FORMAT_R32G32_FLOAT: - return 8; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return 16; - default: - return 0; - } -} - inline void CalculatePitch(uint32_t Width, uint32_t Height, DXGI_FORMAT Format, uint32_t* pRowPitch, uint32_t* pSlicePitch) {; - if (IsBlockCompressed(Format)) - { - uint32_t BlocksWide = (Width + 3) / 4; - uint32_t BlocksHigh = (Height + 3) / 4; - uint32_t BlockSize = BytesPerBlock(Format); + SIZE_T rowPitch = 0; + SIZE_T slicePitch = 0; + DirectX::ComputePitch(Format, Width, Height, rowPitch, slicePitch); - (*pRowPitch) = BlocksWide * BlockSize; - (*pSlicePitch) = (*pRowPitch) * BlocksHigh; - } - else - { - uint32_t bpp = BytesPerPixel(Format); - - (*pRowPitch) = Width * bpp; - (*pSlicePitch) = (*pRowPitch) * Height; - } + (*pRowPitch) = rowPitch; + (*pSlicePitch) = slicePitch; } diff --git a/projects/WinDurango.D3D11X/src/ID3D11Device.cpp b/projects/WinDurango.D3D11X/src/ID3D11Device.cpp index 1c3ea5d..e9bc69c 100644 --- a/projects/WinDurango.D3D11X/src/ID3D11Device.cpp +++ b/projects/WinDurango.D3D11X/src/ID3D11Device.cpp @@ -899,6 +899,13 @@ HRESULT D3D11DeviceX::CreatePlacementTexture2D(D3D11_TEXTURE2D_DESC const * initialData.clear(); return hr; } + else if (pVirtualAddress && pDesc2.SampleDesc.Count > 1) + { + HRESULT hr = CreateTexture2D(&pDesc2, 0, ppTexture2D); + (*ppTexture2D)->m_pAllocationStart = pVirtualAddress; + initialData.clear(); + return hr; + } else { HRESULT hr = CreateTexture2D(&pDesc2, initialData.data(), ppTexture2D); @@ -982,7 +989,7 @@ HRESULT D3D11DeviceX::CreateDeferredContextX(UINT Flags, gfx::ID3D11DeviceC template void D3D11DeviceX::GarbageCollect(UINT Flags) { - IMPLEMENT_STUB(); + } template diff --git a/projects/WinDurango.D3D11X/src/ID3D11DeviceContext.cpp b/projects/WinDurango.D3D11X/src/ID3D11DeviceContext.cpp index 84b2e79..12df2a5 100644 --- a/projects/WinDurango.D3D11X/src/ID3D11DeviceContext.cpp +++ b/projects/WinDurango.D3D11X/src/ID3D11DeviceContext.cpp @@ -1838,7 +1838,7 @@ template void D3D11DeviceContextX::PSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer *pConstantBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + PSSetConstantBuffers(Slot, 1, &pConstantBuffer); } template @@ -1846,14 +1846,14 @@ void D3D11DeviceContextX::PSSetPlacementShaderResource(UINT Slot, gfx::ID3D11ShaderResourceView *pShaderResourceView, void *pBaseAddress) { - IMPLEMENT_STUB(); + PSSetShaderResources(Slot, 1, &pShaderResourceView); } template void D3D11DeviceContextX::VSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer *pConstantBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + VSSetConstantBuffers(Slot, 1, &pConstantBuffer); } template @@ -1861,14 +1861,14 @@ void D3D11DeviceContextX::VSSetPlacementShaderResource(UINT Slot, gfx::ID3D11ShaderResourceView *pShaderResourceView, void *pBaseAddress) { - IMPLEMENT_STUB(); + VSSetShaderResources(Slot, 1, &pShaderResourceView); } template void D3D11DeviceContextX::GSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer *pConstantBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + GSSetConstantBuffers(Slot, 1, &pConstantBuffer); } template @@ -1876,14 +1876,14 @@ void D3D11DeviceContextX::GSSetPlacementShaderResource(UINT Slot, gfx::ID3D11ShaderResourceView *pShaderResourceView, void *pBaseAddress) { - IMPLEMENT_STUB(); + GSSetShaderResources(Slot, 1, &pShaderResourceView); } template void D3D11DeviceContextX::CSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer *pConstantBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + CSSetConstantBuffers(Slot, 1, &pConstantBuffer); } template @@ -1891,14 +1891,14 @@ void D3D11DeviceContextX::CSSetPlacementShaderResource(UINT Slot, gfx::ID3D11ShaderResourceView *pShaderResourceView, void *pBaseAddress) { - IMPLEMENT_STUB(); + CSSetShaderResources(Slot, 1, &pShaderResourceView); } template void D3D11DeviceContextX::HSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer *pConstantBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + HSSetConstantBuffers(Slot, 1, &pConstantBuffer); } template @@ -1906,14 +1906,14 @@ void D3D11DeviceContextX::HSSetPlacementShaderResource(UINT Slot, gfx::ID3D11ShaderResourceView *pShaderResourceView, void *pBaseAddress) { - IMPLEMENT_STUB(); + HSSetShaderResources(Slot, 1, &pShaderResourceView); } template void D3D11DeviceContextX::DSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer *pConstantBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + DSSetConstantBuffers(Slot, 1, &pConstantBuffer); } template @@ -1921,21 +1921,24 @@ void D3D11DeviceContextX::DSSetPlacementShaderResource(UINT Slot, gfx::ID3D11ShaderResourceView *pShaderResourceView, void *pBaseAddress) { - IMPLEMENT_STUB(); + DSSetShaderResources(Slot, 1, &pShaderResourceView); } template void D3D11DeviceContextX::IASetPlacementVertexBuffer(UINT Slot, gfx::ID3D11Buffer *pVertexBuffer, void *pBaseAddress, UINT Stride) { - IMPLEMENT_STUB(); + UINT Offset = 0; + IASetVertexBuffers(Slot, 1, &pVertexBuffer, &Stride, &Offset); } template void D3D11DeviceContextX::IASetPlacementIndexBuffer(UINT HardwareIndexFormat, gfx::ID3D11Buffer *pIndexBuffer, void *pBaseAddress) { - IMPLEMENT_STUB(); + HardwareIndexFormat = HardwareIndexFormat != 0 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; + + IASetIndexBuffer(pIndexBuffer, HardwareIndexFormat, 0); } template @@ -2026,7 +2029,255 @@ template UINT32 *D3D11DeviceContextX::MakeCeSpace() template void D3D11DeviceContextX::SetFastResources_Debug(UINT *pTableStart, UINT *pTableEnd) { - IMPLEMENT_STUB(); + UINT v10 = 0; + UINT v11 = 0; + UINT v12 = 0; + UINT v14 = 0; + UINT v16 = 0; + UINT v17 = 0; + UINT64 v23 = 0; + UINT64 v26 = 0; + int v27 = 0; + int v51 = 0; + UINT64 BaseAddress = 0; + UINT64 BaseAddress2 = 0; + UINT64 *ResourcePtr{}; + UINT v13 = 0; + UINT Slot = 0; + UINT64 Stride = 0; + UINT D3D11X_SET_FAST_VALUE = 0; + gfx::ID3D11ShaderResourceView *SRV{}; + gfx::ID3D11Buffer *Buffer{}; + gfx::ID3D11SamplerState *Sampler{}; + + for (bool i = pTableStart < pTableEnd; i; i = pTableStart < pTableEnd) + { + v10 = *pTableStart++; + v11 = (*((WORD *)&(v10) + 0)) & 0x7FF; + v12 = (UINT8)v10; + v16 = (v10 >> 28) & 7; + v13 = v10 >> 8; + Slot = (UINT8)v13; + v14 = (v10 >> 27) & 1; + v17 = v10 >> 31; + D3D11X_SET_FAST_VALUE = ((BYTE *)&v10)[2] & 0xF; + + if (v12) + { + while (1) + { + v23 = *((UINT64 *)pTableStart + 1); + ResourcePtr = *(UINT64 **)pTableStart; + pTableStart += 4; + Stride = (v23 >> 48) & 0xFFFF; + UINT64 Offset = v23 & 0x0000FFFFFFFFFFFF; + v26 = v23 - ((UINT64)(UINT)Stride << 48); + + if (ResourcePtr) + { + if (!v16) + { + v27 = v11 & 0x100; + if (v17 == 1) + { + if (!v14) + { + if ((v11 & 0x40) != 0) + { + break; + } + BaseAddress = Offset; + if (v27) + { + switch (D3D11X_SET_FAST_VALUE) + { + case 0: + SRV = reinterpret_cast *>(ResourcePtr); + VSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress); + break; + case 1: + SRV = reinterpret_cast *>(ResourcePtr); + HSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress); + break; + case 2: + SRV = reinterpret_cast *>(ResourcePtr); + DSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress); + break; + case 3: + SRV = reinterpret_cast *>(ResourcePtr); + GSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress); + break; + case 4: + SRV = reinterpret_cast *>(ResourcePtr); + PSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress); + break; + case 5: + SRV = reinterpret_cast *>(ResourcePtr); + CSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress); + break; + } + } + else + { + switch (D3D11X_SET_FAST_VALUE) + { + case 0: + SRV = reinterpret_cast *>(ResourcePtr); + VSSetFastShaderResource(Slot, SRV); + break; + case 1: + SRV = reinterpret_cast *>(ResourcePtr); + HSSetFastShaderResource(Slot, SRV); + break; + case 2: + SRV = reinterpret_cast *>(ResourcePtr); + DSSetFastShaderResource(Slot, SRV); + break; + case 3: + SRV = reinterpret_cast *>(ResourcePtr); + GSSetFastShaderResource(Slot, SRV); + break; + case 4: + SRV = reinterpret_cast *>(ResourcePtr); + PSSetFastShaderResource(Slot, SRV); + break; + case 5: + SRV = reinterpret_cast *>(ResourcePtr); + CSSetFastShaderResource(Slot, SRV); + break; + } + } + } + } + + return; + } + if (v16 == 1) + { + if (v17 == 1) + { + v51 = v11 & 0x100; + + BaseAddress2 = Offset; + if (v51) + { + if (D3D11X_SET_FAST_VALUE) + { + switch (D3D11X_SET_FAST_VALUE) + { + case 1: + Buffer = reinterpret_cast *>(ResourcePtr); + HSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2); + break; + case 2: + Buffer = reinterpret_cast *>(ResourcePtr); + DSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2); + break; + case 3: + Buffer = reinterpret_cast *>(ResourcePtr); + GSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2); + break; + case 4: + Buffer = reinterpret_cast *>(ResourcePtr); + PSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2); + break; + case 5: + Buffer = reinterpret_cast *>(ResourcePtr); + CSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2); + break; + case 6: + Buffer = reinterpret_cast *>(ResourcePtr); + IASetPlacementVertexBuffer(Slot, Buffer, (void *)BaseAddress2, Stride); + break; + } + } + else + { + Buffer = reinterpret_cast *>(ResourcePtr); + VSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2); + } + } + else if (D3D11X_SET_FAST_VALUE) + { + switch (D3D11X_SET_FAST_VALUE) + { + case 1: + Buffer = reinterpret_cast *>(ResourcePtr); + HSSetFastConstantBuffer(Slot, Buffer); + break; + case 2: + Buffer = reinterpret_cast *>(ResourcePtr); + DSSetFastConstantBuffer(Slot, Buffer); + break; + case 3: + Buffer = reinterpret_cast *>(ResourcePtr); + GSSetFastConstantBuffer(Slot, Buffer); + break; + case 4: + Buffer = reinterpret_cast *>(ResourcePtr); + PSSetFastConstantBuffer(Slot, Buffer); + break; + case 5: + Buffer = reinterpret_cast *>(ResourcePtr); + CSSetFastConstantBuffer(Slot, Buffer); + break; + case 6: + Buffer = reinterpret_cast *>(ResourcePtr); + IASetFastVertexBuffer(Slot, Buffer, Stride); + break; + } + } + else + { + Buffer = reinterpret_cast *>(ResourcePtr); + VSSetFastConstantBuffer(Slot, Buffer); + } + } + + return; + } + if (v17 == 1) + { + if (D3D11X_SET_FAST_VALUE) + { + switch (D3D11X_SET_FAST_VALUE) + { + case 1: + Sampler = reinterpret_cast *>(ResourcePtr); + HSSetFastSampler(Slot, Sampler); + break; + case 2: + Sampler = reinterpret_cast *>(ResourcePtr); + DSSetFastSampler(Slot, Sampler); + break; + case 3: + Sampler = reinterpret_cast *>(ResourcePtr); + GSSetFastSampler(Slot, Sampler); + break; + case 4: + Sampler = reinterpret_cast *>(ResourcePtr); + PSSetFastSampler(Slot, Sampler); + break; + case 5: + Sampler = reinterpret_cast *>(ResourcePtr); + CSSetFastSampler(Slot, Sampler); + break; + } + } + else + { + Sampler = reinterpret_cast *>(ResourcePtr); + VSSetFastSampler(Slot, Sampler); + } + + return; + } + } + + return; + } + } + } } template void D3D11DeviceContextX::BeginResourceBatch(void *pBuffer, UINT BufferSize) diff --git a/projects/WinDurango.D3D11X/src/IDXGIFactory.cpp b/projects/WinDurango.D3D11X/src/IDXGIFactory.cpp index 52c23cb..f9d330d 100644 --- a/projects/WinDurango.D3D11X/src/IDXGIFactory.cpp +++ b/projects/WinDurango.D3D11X/src/IDXGIFactory.cpp @@ -146,9 +146,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, msg, wParam, lParam); } -IDXGISwapChain1 *OldSwapChain{}; -winrt::hstring GamePackage = winrt::Windows::ApplicationModel::Package::Current().Id().FamilyName(); - template HRESULT DXGIFactory2::CreateSwapChainForCoreWindow(xbox::IGraphicsUnknown *pDevice, IUnknown *pWindow, DXGI_SWAP_CHAIN_DESC1 *pDesc, IDXGIOutput *pRestrictToOutput, diff --git a/projects/WinDurango.D3D11X/src/d3d11.x.cpp b/projects/WinDurango.D3D11X/src/d3d11.x.cpp index 416c74f..cdbb356 100644 --- a/projects/WinDurango.D3D11X/src/d3d11.x.cpp +++ b/projects/WinDurango.D3D11X/src/d3d11.x.cpp @@ -2,6 +2,7 @@ #include "IIDExports.h" #include "d3d11_x.g.h" #include "ID3D11Runtime.h" +#include "kernelx.h" EXTERN_C HRESULT __stdcall EraD3D10CreateBlob() { @@ -77,8 +78,14 @@ EXTERN_C HRESULT __stdcall D3DFreeGraphicsMemory(void *pAddress) EXTERN_C HRESULT __stdcall D3DMapEsramMemory(UINT Flags, void *pVirtualAddress, UINT NumPages, const UINT *pPageList) { - IMPLEMENT_STUB(); - return E_NOTIMPL; + DWORD flAllocationType = 0; + + if ((Flags & 1) != 0) + flAllocationType = MEM_LARGE_PAGES; + else if ((Flags & 2) != 0) + flAllocationType = MEM_4MB_PAGES; + + return MapTitleEsramPages(pVirtualAddress, NumPages, flAllocationType, pPageList); } struct DXGIX_FRAME_STATISTICS diff --git a/projects/WinDurango.KernelX/CMakeLists.txt b/projects/WinDurango.KernelX/CMakeLists.txt index c9cd481..e799002 100644 --- a/projects/WinDurango.KernelX/CMakeLists.txt +++ b/projects/WinDurango.KernelX/CMakeLists.txt @@ -15,7 +15,7 @@ set(FILES include/WinDurango.KernelX/Hooks.h ) -add_library(WinDurango.KernelX SHARED ${FILES} "include/WinDurango.KernelX/EraCoreApplication.h" "src/EraCoreApplication.cpp" "include/WinDurango.KernelX/EraCoreWindow.h" "src/EraCoreWindow.cpp") +add_library(WinDurango.KernelX SHARED ${FILES} "include/WinDurango.KernelX/EraCoreApplication.h" "src/EraCoreApplication.cpp" "include/WinDurango.KernelX/EraCoreWindow.h" "src/EraCoreWindow.cpp" "include/WinDurango.KernelX/MMDeviceEnumerator.h" "src/MMDeviceEnumerator.cpp") target_link_libraries(WinDurango.KernelX PRIVATE WinDurango.Common diff --git a/projects/WinDurango.KernelX/include/WinDurango.KernelX/Hooks.h b/projects/WinDurango.KernelX/include/WinDurango.KernelX/Hooks.h index 89a2fc6..2413f3b 100644 --- a/projects/WinDurango.KernelX/include/WinDurango.KernelX/Hooks.h +++ b/projects/WinDurango.KernelX/include/WinDurango.KernelX/Hooks.h @@ -67,8 +67,20 @@ typedef HWND(WINAPI *PCreateWindowInBandEx)(DWORD dwExStyle, LPCWSTR lpClassName int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam, DWORD dwBand, DWORD dwTypeFlags); -static PCreateWindowInBandEx TrueCreateWindowInBandEx = 0; +PCreateWindowInBandEx TrueCreateWindowInBandEx = 0; HWND WINAPI EraCreateWindowInBandEx(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, - LPVOID lpParam, DWORD dwBand, DWORD dwTypeFlags); \ No newline at end of file + LPVOID lpParam, DWORD dwBand, DWORD dwTypeFlags); + +HRESULT(WINAPI *TrueCoCreateInstance)(_In_ REFCLSID rclsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ DWORD dwClsContext, + _In_ REFIID riid, + _COM_Outptr_ _At_(*ppv, _Post_readable_size_(_Inexpressible_(varies))) + LPVOID FAR *ppv) = CoCreateInstance; + +HRESULT __stdcall EraCoCreateInstance(_In_ REFCLSID rclsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ DWORD dwClsContext, + _In_ REFIID riid, + _COM_Outptr_ _At_(*ppv, _Post_readable_size_(_Inexpressible_(varies))) + LPVOID FAR *ppv); + +HMODULE User32 = nullptr; \ No newline at end of file diff --git a/projects/WinDurango.KernelX/include/WinDurango.KernelX/Logan.h b/projects/WinDurango.KernelX/include/WinDurango.KernelX/Logan.h index 9d00612..e3145d3 100644 --- a/projects/WinDurango.KernelX/include/WinDurango.KernelX/Logan.h +++ b/projects/WinDurango.KernelX/include/WinDurango.KernelX/Logan.h @@ -361,7 +361,7 @@ EXTERN_C BOOL __stdcall EraDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode { if (hDevice != LoganHandle) { - return DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, + return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); } else diff --git a/projects/WinDurango.KernelX/include/WinDurango.KernelX/MMDeviceEnumerator.h b/projects/WinDurango.KernelX/include/WinDurango.KernelX/MMDeviceEnumerator.h new file mode 100644 index 0000000..49086a2 --- /dev/null +++ b/projects/WinDurango.KernelX/include/WinDurango.KernelX/MMDeviceEnumerator.h @@ -0,0 +1,111 @@ +#pragma once +#include + +class MMDeviceEnumeratorWrapper : IMMDeviceEnumerator +{ + public: + MMDeviceEnumeratorWrapper(IMMDeviceEnumerator *realEnumerator) : m_realEnumerator(realEnumerator) + { + AddRef(); + } + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) override; + ULONG STDMETHODCALLTYPE AddRef(void) override; + ULONG STDMETHODCALLTYPE Release(void) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnumAudioEndpoints( + /* [annotation][in] */ + _In_ EDataFlow dataFlow, + /* [annotation][in] */ + _In_ DWORD dwStateMask, + /* [annotation][out] */ + _Out_ IMMDeviceCollection **ppDevices) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDefaultAudioEndpoint( + /* [annotation][in] */ + _In_ EDataFlow dataFlow, + /* [annotation][in] */ + _In_ ERole role, + /* [annotation][out] */ + _Out_ IMMDevice **ppEndpoint) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDevice( + /* [annotation][in] */ + _In_ LPCWSTR pwstrId, + /* [annotation][out] */ + _Out_ IMMDevice **ppDevice) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE RegisterEndpointNotificationCallback( + /* [annotation][in] */ + _In_ IMMNotificationClient *pClient) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE UnregisterEndpointNotificationCallback( + + /* [annotation][in] */ + _In_ IMMNotificationClient *pClient) override; + + IMMDeviceEnumerator *m_realEnumerator; + ULONG m_RefCount = 0; +}; + +MIDL_INTERFACE("8B557ADC-555E-47A0-B223-43477E481DAD") +IMMXboxDeviceEnumerator : public IMMDeviceEnumerator +{ + public: + virtual HRESULT STDMETHODCALLTYPE GetHdAudioChannelCounts(UINT * pHdmiChannelCount, UINT * pSpdifChannelCount) = 0; + virtual HRESULT STDMETHODCALLTYPE RegisterChannelCountNotificationCallback(UINT * pClient) = 0; + virtual HRESULT STDMETHODCALLTYPE UnregisterChannelCountNotificationCallback(UINT * pClient) = 0; +}; + +class MMXboxDeviceEnumerator : IMMXboxDeviceEnumerator +{ + public: + MMXboxDeviceEnumerator(IMMDeviceEnumerator *realEnumerator) : m_realEnumerator(realEnumerator) + { + AddRef(); + } + + HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) override; + + ULONG STDMETHODCALLTYPE AddRef(void) override; + ULONG STDMETHODCALLTYPE Release(void) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnumAudioEndpoints( + /* [annotation][in] */ + _In_ EDataFlow dataFlow, + /* [annotation][in] */ + _In_ DWORD dwStateMask, + /* [annotation][out] */ + _Out_ IMMDeviceCollection **ppDevices) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDefaultAudioEndpoint( + /* [annotation][in] */ + _In_ EDataFlow dataFlow, + /* [annotation][in] */ + _In_ ERole role, + /* [annotation][out] */ + _Out_ IMMDevice **ppEndpoint) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDevice( + /* [annotation][in] */ + _In_ LPCWSTR pwstrId, + /* [annotation][out] */ + _Out_ IMMDevice **ppDevice) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE RegisterEndpointNotificationCallback( + /* [annotation][in] */ + _In_ IMMNotificationClient *pClient) override; + + /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE UnregisterEndpointNotificationCallback( + /* [annotation][in] */ + _In_ IMMNotificationClient *pClient) override; + + HRESULT __stdcall GetHdAudioChannelCounts(UINT *pHdmiChannelCount, UINT *pSpdifChannelCount) override; + HRESULT __stdcall RegisterChannelCountNotificationCallback(UINT *pClient) override; + HRESULT __stdcall UnregisterChannelCountNotificationCallback(UINT *pClient) override; + + IMMDeviceEnumerator *m_realEnumerator; + ULONG m_RefCount = 0; +}; \ No newline at end of file diff --git a/projects/WinDurango.KernelX/src/Hooks.cpp b/projects/WinDurango.KernelX/src/Hooks.cpp index 1da345a..86bcec2 100644 --- a/projects/WinDurango.KernelX/src/Hooks.cpp +++ b/projects/WinDurango.KernelX/src/Hooks.cpp @@ -4,6 +4,7 @@ #include "CurrentApp.h" #include #include +#include "MMDeviceEnumerator.h" using namespace ABI::Windows::ApplicationModel::Store; @@ -161,6 +162,22 @@ HWND __stdcall EraCreateWindowInBandEx(DWORD dwExStyle, LPCWSTR lpClassName, LPC hMenu, hInstance, lpParam, dwBand, dwTypeFlags); } +HRESULT __stdcall EraCoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, + LPVOID *ppv) +{ + HRESULT hr = TrueCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); + if (FAILED(hr)) + return hr; + + if (riid == __uuidof(IMMDeviceEnumerator)) + { + *ppv = new MMDeviceEnumeratorWrapper(static_cast(*ppv)); + return S_OK; + } + + return hr; +} + inline HRESULT WINAPI EraRoGetActivationFactory(HSTRING classId, REFIID iid, void **factory) diff --git a/projects/WinDurango.KernelX/src/MMDeviceEnumerator.cpp b/projects/WinDurango.KernelX/src/MMDeviceEnumerator.cpp new file mode 100644 index 0000000..da06fb4 --- /dev/null +++ b/projects/WinDurango.KernelX/src/MMDeviceEnumerator.cpp @@ -0,0 +1,121 @@ +#include "MMDeviceEnumerator.h" + +// MMDeviceEnumerator +HRESULT __stdcall MMDeviceEnumeratorWrapper::QueryInterface(REFIID riid, void **ppvObject) +{ + if (riid == __uuidof(IMMXboxDeviceEnumerator)) + { + *ppvObject = new MMXboxDeviceEnumerator(this); + AddRef(); + return S_OK; + } + + return m_realEnumerator->QueryInterface(riid, ppvObject); +} + +ULONG __stdcall MMDeviceEnumeratorWrapper::AddRef(void) +{ + m_realEnumerator->AddRef(); + return InterlockedIncrement(&m_RefCount); +} + +ULONG __stdcall MMDeviceEnumeratorWrapper::Release(void) +{ + m_realEnumerator->Release(); + ULONG RefCount = InterlockedDecrement(&m_RefCount); + if (!RefCount) + delete this; + return RefCount; +} + +HRESULT __stdcall MMDeviceEnumeratorWrapper::EnumAudioEndpoints(EDataFlow dataFlow, DWORD dwStateMask, + IMMDeviceCollection **ppDevices) +{ + return m_realEnumerator->EnumAudioEndpoints(dataFlow, dwStateMask, ppDevices); +} + +HRESULT __stdcall MMDeviceEnumeratorWrapper::GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, + IMMDevice **ppEndpoint) +{ + return m_realEnumerator->GetDefaultAudioEndpoint(dataFlow, role, ppEndpoint); +} + +HRESULT __stdcall MMDeviceEnumeratorWrapper::GetDevice(LPCWSTR pwstrId, IMMDevice **ppDevice) +{ + return m_realEnumerator->GetDevice(pwstrId, ppDevice); +} + +HRESULT __stdcall MMDeviceEnumeratorWrapper::RegisterEndpointNotificationCallback(IMMNotificationClient *pClient) +{ + return m_realEnumerator->RegisterEndpointNotificationCallback(pClient); +} + +HRESULT __stdcall MMDeviceEnumeratorWrapper::UnregisterEndpointNotificationCallback(IMMNotificationClient *pClient) +{ + return m_realEnumerator->UnregisterEndpointNotificationCallback(pClient); +} + +HRESULT __stdcall MMXboxDeviceEnumerator::QueryInterface(REFIID riid, void **ppvObject) +{ + return m_realEnumerator->QueryInterface(riid, ppvObject); +} + +// MMXboxDeviceEnumerator +ULONG __stdcall MMXboxDeviceEnumerator::AddRef(void) +{ + m_realEnumerator->AddRef(); + return InterlockedIncrement(&m_RefCount); +} + +ULONG __stdcall MMXboxDeviceEnumerator::Release(void) +{ + m_realEnumerator->Release(); + ULONG RefCount = InterlockedDecrement(&m_RefCount); + if (!RefCount) + delete this; + return RefCount; +} + +HRESULT __stdcall MMXboxDeviceEnumerator::EnumAudioEndpoints(EDataFlow dataFlow, DWORD dwStateMask, + IMMDeviceCollection **ppDevices) +{ + return m_realEnumerator->EnumAudioEndpoints(dataFlow, dwStateMask, ppDevices); +} + +HRESULT __stdcall MMXboxDeviceEnumerator::GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, + IMMDevice **ppEndpoint) +{ + return m_realEnumerator->GetDefaultAudioEndpoint(dataFlow, role, ppEndpoint); +} + +HRESULT __stdcall MMXboxDeviceEnumerator::GetDevice(LPCWSTR pwstrId, IMMDevice **ppDevice) +{ + return m_realEnumerator->GetDevice(pwstrId, ppDevice); +} + +HRESULT __stdcall MMXboxDeviceEnumerator::RegisterEndpointNotificationCallback(IMMNotificationClient *pClient) +{ + return m_realEnumerator->RegisterEndpointNotificationCallback(pClient); +} + +HRESULT __stdcall MMXboxDeviceEnumerator::UnregisterEndpointNotificationCallback(IMMNotificationClient *pClient) +{ + return m_realEnumerator->UnregisterEndpointNotificationCallback(pClient); +} + +HRESULT __stdcall MMXboxDeviceEnumerator::GetHdAudioChannelCounts(UINT *pHdmiChannelCount, UINT *pSpdifChannelCount) +{ + *pHdmiChannelCount = 8; + *pSpdifChannelCount = 2; + return S_OK; +} + +HRESULT __stdcall MMXboxDeviceEnumerator::RegisterChannelCountNotificationCallback(UINT *pClient) +{ + return S_OK; +} + +HRESULT __stdcall MMXboxDeviceEnumerator::UnregisterChannelCountNotificationCallback(UINT *pClient) +{ + return S_OK; +} \ No newline at end of file diff --git a/projects/WinDurango.KernelX/src/dllmain.cpp b/projects/WinDurango.KernelX/src/dllmain.cpp index 4035631..f9beda0 100644 --- a/projects/WinDurango.KernelX/src/dllmain.cpp +++ b/projects/WinDurango.KernelX/src/dllmain.cpp @@ -1,5 +1,6 @@ #include "Hooks.h" #include "kernelx.h" +#include "Logan.h" static DWORD ReasonForCall = 0; @@ -18,23 +19,41 @@ void KernelxInitialize(HINSTANCE hinstDLL) if (ReasonForCall == DLL_PROCESS_ATTACH || ReasonForCall == DLL_THREAD_ATTACH) { + DetourRestoreAfterWith(); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); XWinePatchImport(GetModuleHandleW(nullptr), GetRuntimeModule(), "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z", GetActivationFactoryRedirect); - } - HMODULE User32 = LoadLibraryA("user32.dll"); - if (User32) + //This is needed for DXVK. + if (!User32) User32 = LoadLibraryA("user32.dll"); + if (User32) + { + FARPROC CreateWindowInBandEx = GetProcAddress(User32, "CreateWindowInBandEx"); + TrueCreateWindowInBandEx = reinterpret_cast(CreateWindowInBandEx); + DetourAttach(&reinterpret_cast(TrueCreateWindowInBandEx), EraCreateWindowInBandEx); + } + + DetourAttach(&reinterpret_cast(TrueCoCreateInstance), EraCoCreateInstance); + DetourAttach(&reinterpret_cast(TrueDeviceIoControl), EraDeviceIoControl); + DetourTransactionCommit(); + } + else if (ReasonForCall == DLL_PROCESS_DETACH || ReasonForCall == DLL_THREAD_DETACH) { - FARPROC CreateWindowInBandEx = GetProcAddress(User32, "CreateWindowInBandEx"); - TrueCreateWindowInBandEx = reinterpret_cast(CreateWindowInBandEx); - DetourAttach(&reinterpret_cast(TrueCreateWindowInBandEx), EraCreateWindowInBandEx); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourDetach(&reinterpret_cast(TrueCreateWindowInBandEx), EraCreateWindowInBandEx); + DetourDetach(&reinterpret_cast(TrueCoCreateInstance), EraCoCreateInstance); + DetourDetach(&reinterpret_cast(TrueDeviceIoControl), EraDeviceIoControl); + DetourTransactionCommit(); } } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { InitializeCriticalSection(&XmpAllocationHookLock); + if (DetourIsHelperProcess()) return TRUE; ReasonForCall = ul_reason_for_call; diff --git a/projects/WinDurango.KernelX/src/kernelx.cpp b/projects/WinDurango.KernelX/src/kernelx.cpp index 9e76714..b409372 100644 --- a/projects/WinDurango.KernelX/src/kernelx.cpp +++ b/projects/WinDurango.KernelX/src/kernelx.cpp @@ -1,5 +1,8 @@ #include "kernelx.h" #include "Logan.h" +#include +#include "Hooks.h" + EXTERN_C CONSOLE_TYPE __stdcall GetConsoleType() { return CONSOLE_TYPE_XBOX_ONE; @@ -695,6 +698,65 @@ EXTERN_C void __stdcall XMemReleaseAuxiliaryTitleMemory(_In_opt_ HANDLE hHandle) SetLastError(ERROR_CALL_NOT_IMPLEMENTED); } + +void FixRelativePath(LPCWSTR &lpFileName) +{ + static std::wstring convert{}; + std::wstring_view fileName(lpFileName); + + if (fileName.size() == 0) + return; + + int length = fileName.length(); + + if (fileName[0] == '.' && fileName[1] == '\\') + { + static std::wstring trimPath{}; + trimPath = fileName.substr(2); + fileName = trimPath.data(); + convert = std::filesystem::current_path().c_str(); + if (length != '\\') + { + convert.append(L"\\"); + } + convert.append(fileName); + + lpFileName = convert.data(); + + return; + } + if (fileName[1] != ':') + { + convert = std::filesystem::current_path().c_str(); + convert.append(L"\\"); + convert.append(fileName); + + lpFileName = convert.data(); + } + else if ((fileName[0] == 'G' || fileName[0] == 'g') && fileName[1] == ':') + { + + static std::wstring trimPath{}; + trimPath = fileName.substr(2); + fileName = trimPath.data(); + convert = std::filesystem::current_path().c_str(); + convert.append(fileName); + + lpFileName = convert.data(); + } + else if ((fileName[0] == 'T' || fileName[0] == 't') && fileName[1] == ':') + { + + static std::wstring trimPath{}; + trimPath = fileName.substr(2); + fileName = trimPath.data(); + convert = winrt::Windows::Storage::ApplicationData::Current().TemporaryFolder().Path(); + convert.append(fileName); + + lpFileName = convert.data(); + } +} + EXTERN_C HANDLE __stdcall EraCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) @@ -711,6 +773,37 @@ EXTERN_C HANDLE __stdcall EraCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAcce return LoganHandle; } + static std::wstring convert{}; + std::wstring_view fileName(lpFileName); + + int length = fileName.length(); + if (fileName[0] == '/') + { + static std::wstring trimPath{}; + trimPath = fileName.substr(1); + fileName = trimPath.data(); + convert = std::filesystem::current_path().c_str(); + convert.append(L"\\"); + convert.append(fileName); + + lpFileName = convert.data(); + } + else if (fileName[0] == '\\') + { + } + else if (fileName[length - 1] == '/') + { + convert = std::filesystem::current_path().c_str(); + convert.append(L"\\"); + convert.append(lpFileName); + std::replace(convert.begin(), convert.end(), L'/', L'\\'); + lpFileName = convert.c_str(); + } + else + { + FixRelativePath(lpFileName); + } + return CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } @@ -719,6 +812,10 @@ EXTERN_C HANDLE __stdcall EraCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAcces LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { + USES_CONVERSION; + LPCWSTR FileName = A2W(lpFileName); + FixRelativePath(FileName); + return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } @@ -726,47 +823,94 @@ EXTERN_C HANDLE __stdcall EraCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAcces EXTERN_C HANDLE __stdcall EraCreateFile2(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) { + FixRelativePath(lpFileName); return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); } EXTERN_C BOOL __stdcall EraCreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { - return CreateDirectoryA(lpPathName, lpSecurityAttributes); + USES_CONVERSION; + LPCWSTR PathName = A2W(lpPathName); + FixRelativePath(PathName); + + return CreateDirectoryW(PathName, lpSecurityAttributes); } EXTERN_C HMODULE __stdcall EraLoadLibraryExA(LPCSTR lpLibFileName, _Reserved_ HANDLE hFile, _In_ DWORD dwFlags) { - return LoadLibraryExA(lpLibFileName, hFile, dwFlags); + USES_CONVERSION; + LPCWSTR LibName = A2W(lpLibFileName); + + static std::wstring convert{}; + std::wstring_view fileName(LibName); + + if (fileName.size() != 0 && fileName[0] == 'G' && fileName[1] == ':') + { + static std::wstring trimPath{}; + trimPath = fileName.substr(2); + fileName = trimPath.data(); + convert = std::filesystem::current_path().c_str(); + convert.append(fileName); + } + + HMODULE result = LoadLibraryExW(LibName, hFile, dwFlags); + + PatchNeededImports(result, GetRuntimeModule(), "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z", + GetActivationFactoryRedirect); + return result; } EXTERN_C HMODULE __stdcall EraLoadLibraryW(LPCWSTR lpLibFileName) { - return LoadLibraryW(lpLibFileName); + static std::wstring convert{}; + std::wstring_view fileName(lpLibFileName); + + if (fileName[0] == 'G' && fileName[1] == ':' && fileName.size() != 0) + { + + static std::wstring trimPath{}; + trimPath = fileName.substr(2); + fileName = trimPath.data(); + convert = std::filesystem::current_path().c_str(); + convert.append(fileName); + + lpLibFileName = convert.data(); + } + + HMODULE result = LoadLibraryW(lpLibFileName); + PatchNeededImports(result, GetRuntimeModule(), "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z", + GetActivationFactoryRedirect); + return result; } EXTERN_C DWORD __stdcall EraGetFileAttributesW(LPCWSTR lpFileName) { + FixRelativePath(lpFileName); return GetFileAttributesW(lpFileName); } EXTERN_C BOOL __stdcall EraGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation) { + FixRelativePath(lpFileName); return GetFileAttributesExW(lpFileName, fInfoLevelId, lpFileInformation); } EXTERN_C HANDLE __stdcall EraFindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData) { + FixRelativePath(lpFileName); return FindFirstFileW(lpFileName, lpFindFileData); } EXTERN_C BOOL __stdcall EraDeleteFileW(LPCWSTR lpFileName) { + FixRelativePath(lpFileName); return DeleteFileW(lpFileName); } EXTERN_C HMODULE __stdcall EraLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { + FixRelativePath(lpLibFileName); return LoadLibraryExW(lpLibFileName, hFile, dwFlags); } diff --git a/vcpkg.json b/vcpkg.json index 6116de6..f3b43fe 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,6 +3,7 @@ "version": "1.0", "dependencies": [ "cppwinrt", - "detours" + "detours", + "directxtex" ] }