Forza Horizon 2 Progress + Fixes

This commit is contained in:
Rodrigo Todescatto
2026-02-07 16:58:35 -03:00
parent d15e52a383
commit 3a40329a84
16 changed files with 734 additions and 128 deletions

View File

@@ -4,6 +4,8 @@ project(WinDurango.D3D11X VERSION 1.0.0)
set(VERSION_SUFFIX "-dev.1") # used for non-stable versions, otherwise blank set(VERSION_SUFFIX "-dev.1") # used for non-stable versions, otherwise blank
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
find_package(directxtex CONFIG REQUIRED)
set(FILES set(FILES
src/d3d11.x.cpp src/d3d11.x.cpp
src/IGraphicsUnknown.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" ) 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.Common)
target_link_libraries(WinDurango.D3D11X PRIVATE WinDurango.KernelX)
target_link_libraries(WinDurango.D3D11X PRIVATE Microsoft::DirectXTex)
target_include_directories(WinDurango.D3D11X PUBLIC target_include_directories(WinDurango.D3D11X PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.D3D11X/ ${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.D3D11X/
../WinDurango.Common/include/ ../WinDurango.Common/include/
../WinDurango.KernelX/include/WinDurango.KernelX/ ../WinDurango.KernelX/include/WinDurango.KernelX/
${CMAKE_SOURCE_DIR}/vcpkg_installed/vcpkg/pkgs/directxtex_x64-windows/include
) )
target_link_options(WinDurango.D3D11X target_link_options(WinDurango.D3D11X

View File

@@ -20,7 +20,7 @@ template <abi_t ABI> struct D3D11Runtime : public ID3D11Runtime
D3D_FEATURE_LEVEL FeatureLevels[] = {D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0}; 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); &pDevice, nullptr, &pContext);
if (FAILED(hr)) if (FAILED(hr))

View File

@@ -12,6 +12,7 @@
#include <mutex> #include <mutex>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <DirectXTex.h>
// We use that to know the OS version. // We use that to know the OS version.
abi_t g_ABI{}; abi_t g_ABI{};
@@ -72,99 +73,12 @@ void GetCombaseVersion()
g_ABI.Revision = revision; 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) inline void CalculatePitch(uint32_t Width, uint32_t Height, DXGI_FORMAT Format, uint32_t* pRowPitch, uint32_t* pSlicePitch)
{; {;
if (IsBlockCompressed(Format)) SIZE_T rowPitch = 0;
{ SIZE_T slicePitch = 0;
uint32_t BlocksWide = (Width + 3) / 4; DirectX::ComputePitch(Format, Width, Height, rowPitch, slicePitch);
uint32_t BlocksHigh = (Height + 3) / 4;
uint32_t BlockSize = BytesPerBlock(Format);
(*pRowPitch) = BlocksWide * BlockSize; (*pRowPitch) = rowPitch;
(*pSlicePitch) = (*pRowPitch) * BlocksHigh; (*pSlicePitch) = slicePitch;
}
else
{
uint32_t bpp = BytesPerPixel(Format);
(*pRowPitch) = Width * bpp;
(*pSlicePitch) = (*pRowPitch) * Height;
}
} }

View File

@@ -899,6 +899,13 @@ HRESULT D3D11DeviceX<ABI>::CreatePlacementTexture2D(D3D11_TEXTURE2D_DESC const *
initialData.clear(); initialData.clear();
return hr; return hr;
} }
else if (pVirtualAddress && pDesc2.SampleDesc.Count > 1)
{
HRESULT hr = CreateTexture2D(&pDesc2, 0, ppTexture2D);
(*ppTexture2D)->m_pAllocationStart = pVirtualAddress;
initialData.clear();
return hr;
}
else else
{ {
HRESULT hr = CreateTexture2D(&pDesc2, initialData.data(), ppTexture2D); HRESULT hr = CreateTexture2D(&pDesc2, initialData.data(), ppTexture2D);
@@ -982,7 +989,7 @@ HRESULT D3D11DeviceX<ABI>::CreateDeferredContextX(UINT Flags, gfx::ID3D11DeviceC
template <abi_t ABI> void D3D11DeviceX<ABI>::GarbageCollect(UINT Flags) template <abi_t ABI> void D3D11DeviceX<ABI>::GarbageCollect(UINT Flags)
{ {
IMPLEMENT_STUB();
} }
template <abi_t ABI> template <abi_t ABI>

View File

@@ -1838,7 +1838,7 @@ template <abi_t ABI>
void D3D11DeviceContextX<ABI>::PSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer, void D3D11DeviceContextX<ABI>::PSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); PSSetConstantBuffers(Slot, 1, &pConstantBuffer);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -1846,14 +1846,14 @@ void D3D11DeviceContextX<ABI>::PSSetPlacementShaderResource(UINT Slot,
gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView, gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); PSSetShaderResources(Slot, 1, &pShaderResourceView);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::VSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer, void D3D11DeviceContextX<ABI>::VSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); VSSetConstantBuffers(Slot, 1, &pConstantBuffer);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -1861,14 +1861,14 @@ void D3D11DeviceContextX<ABI>::VSSetPlacementShaderResource(UINT Slot,
gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView, gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); VSSetShaderResources(Slot, 1, &pShaderResourceView);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::GSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer, void D3D11DeviceContextX<ABI>::GSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); GSSetConstantBuffers(Slot, 1, &pConstantBuffer);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -1876,14 +1876,14 @@ void D3D11DeviceContextX<ABI>::GSSetPlacementShaderResource(UINT Slot,
gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView, gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); GSSetShaderResources(Slot, 1, &pShaderResourceView);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::CSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer, void D3D11DeviceContextX<ABI>::CSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); CSSetConstantBuffers(Slot, 1, &pConstantBuffer);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -1891,14 +1891,14 @@ void D3D11DeviceContextX<ABI>::CSSetPlacementShaderResource(UINT Slot,
gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView, gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); CSSetShaderResources(Slot, 1, &pShaderResourceView);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::HSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer, void D3D11DeviceContextX<ABI>::HSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); HSSetConstantBuffers(Slot, 1, &pConstantBuffer);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -1906,14 +1906,14 @@ void D3D11DeviceContextX<ABI>::HSSetPlacementShaderResource(UINT Slot,
gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView, gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); HSSetShaderResources(Slot, 1, &pShaderResourceView);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::DSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer, void D3D11DeviceContextX<ABI>::DSSetPlacementConstantBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pConstantBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); DSSetConstantBuffers(Slot, 1, &pConstantBuffer);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -1921,21 +1921,24 @@ void D3D11DeviceContextX<ABI>::DSSetPlacementShaderResource(UINT Slot,
gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView, gfx::ID3D11ShaderResourceView<ABI> *pShaderResourceView,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); DSSetShaderResources(Slot, 1, &pShaderResourceView);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::IASetPlacementVertexBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pVertexBuffer, void D3D11DeviceContextX<ABI>::IASetPlacementVertexBuffer(UINT Slot, gfx::ID3D11Buffer<ABI> *pVertexBuffer,
void *pBaseAddress, UINT Stride) void *pBaseAddress, UINT Stride)
{ {
IMPLEMENT_STUB(); UINT Offset = 0;
IASetVertexBuffers(Slot, 1, &pVertexBuffer, &Stride, &Offset);
} }
template <abi_t ABI> template <abi_t ABI>
void D3D11DeviceContextX<ABI>::IASetPlacementIndexBuffer(UINT HardwareIndexFormat, gfx::ID3D11Buffer<ABI> *pIndexBuffer, void D3D11DeviceContextX<ABI>::IASetPlacementIndexBuffer(UINT HardwareIndexFormat, gfx::ID3D11Buffer<ABI> *pIndexBuffer,
void *pBaseAddress) void *pBaseAddress)
{ {
IMPLEMENT_STUB(); HardwareIndexFormat = HardwareIndexFormat != 0 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
IASetIndexBuffer(pIndexBuffer, HardwareIndexFormat, 0);
} }
template <abi_t ABI> template <abi_t ABI>
@@ -2026,7 +2029,255 @@ template <abi_t ABI> UINT32 *D3D11DeviceContextX<ABI>::MakeCeSpace()
template <abi_t ABI> void D3D11DeviceContextX<ABI>::SetFastResources_Debug(UINT *pTableStart, UINT *pTableEnd) template <abi_t ABI> void D3D11DeviceContextX<ABI>::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<ABI> *SRV{};
gfx::ID3D11Buffer<ABI> *Buffer{};
gfx::ID3D11SamplerState<ABI> *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<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
VSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress);
break;
case 1:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
HSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress);
break;
case 2:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
DSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress);
break;
case 3:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
GSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress);
break;
case 4:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
PSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress);
break;
case 5:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
CSSetPlacementShaderResource(Slot, SRV, (void *)BaseAddress);
break;
}
}
else
{
switch (D3D11X_SET_FAST_VALUE)
{
case 0:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
VSSetFastShaderResource(Slot, SRV);
break;
case 1:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
HSSetFastShaderResource(Slot, SRV);
break;
case 2:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
DSSetFastShaderResource(Slot, SRV);
break;
case 3:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
GSSetFastShaderResource(Slot, SRV);
break;
case 4:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(ResourcePtr);
PSSetFastShaderResource(Slot, SRV);
break;
case 5:
SRV = reinterpret_cast<gfx::ID3D11ShaderResourceView<ABI> *>(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<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
HSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2);
break;
case 2:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
DSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2);
break;
case 3:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
GSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2);
break;
case 4:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
PSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2);
break;
case 5:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
CSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2);
break;
case 6:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
IASetPlacementVertexBuffer(Slot, Buffer, (void *)BaseAddress2, Stride);
break;
}
}
else
{
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
VSSetPlacementConstantBuffer(Slot, Buffer, (void *)BaseAddress2);
}
}
else if (D3D11X_SET_FAST_VALUE)
{
switch (D3D11X_SET_FAST_VALUE)
{
case 1:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
HSSetFastConstantBuffer(Slot, Buffer);
break;
case 2:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
DSSetFastConstantBuffer(Slot, Buffer);
break;
case 3:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
GSSetFastConstantBuffer(Slot, Buffer);
break;
case 4:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
PSSetFastConstantBuffer(Slot, Buffer);
break;
case 5:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
CSSetFastConstantBuffer(Slot, Buffer);
break;
case 6:
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
IASetFastVertexBuffer(Slot, Buffer, Stride);
break;
}
}
else
{
Buffer = reinterpret_cast<gfx::ID3D11Buffer<ABI> *>(ResourcePtr);
VSSetFastConstantBuffer(Slot, Buffer);
}
}
return;
}
if (v17 == 1)
{
if (D3D11X_SET_FAST_VALUE)
{
switch (D3D11X_SET_FAST_VALUE)
{
case 1:
Sampler = reinterpret_cast<gfx::ID3D11SamplerState<ABI> *>(ResourcePtr);
HSSetFastSampler(Slot, Sampler);
break;
case 2:
Sampler = reinterpret_cast<gfx::ID3D11SamplerState<ABI> *>(ResourcePtr);
DSSetFastSampler(Slot, Sampler);
break;
case 3:
Sampler = reinterpret_cast<gfx::ID3D11SamplerState<ABI> *>(ResourcePtr);
GSSetFastSampler(Slot, Sampler);
break;
case 4:
Sampler = reinterpret_cast<gfx::ID3D11SamplerState<ABI> *>(ResourcePtr);
PSSetFastSampler(Slot, Sampler);
break;
case 5:
Sampler = reinterpret_cast<gfx::ID3D11SamplerState<ABI> *>(ResourcePtr);
CSSetFastSampler(Slot, Sampler);
break;
}
}
else
{
Sampler = reinterpret_cast<gfx::ID3D11SamplerState<ABI> *>(ResourcePtr);
VSSetFastSampler(Slot, Sampler);
}
return;
}
}
return;
}
}
}
} }
template <abi_t ABI> void D3D11DeviceContextX<ABI>::BeginResourceBatch(void *pBuffer, UINT BufferSize) template <abi_t ABI> void D3D11DeviceContextX<ABI>::BeginResourceBatch(void *pBuffer, UINT BufferSize)

View File

@@ -146,9 +146,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
return DefWindowProc(hWnd, msg, wParam, lParam); return DefWindowProc(hWnd, msg, wParam, lParam);
} }
IDXGISwapChain1 *OldSwapChain{};
winrt::hstring GamePackage = winrt::Windows::ApplicationModel::Package::Current().Id().FamilyName();
template <abi_t ABI> template <abi_t ABI>
HRESULT DXGIFactory2<ABI>::CreateSwapChainForCoreWindow(xbox::IGraphicsUnknown<ABI> *pDevice, IUnknown *pWindow, HRESULT DXGIFactory2<ABI>::CreateSwapChainForCoreWindow(xbox::IGraphicsUnknown<ABI> *pDevice, IUnknown *pWindow,
DXGI_SWAP_CHAIN_DESC1 *pDesc, IDXGIOutput *pRestrictToOutput, DXGI_SWAP_CHAIN_DESC1 *pDesc, IDXGIOutput *pRestrictToOutput,

View File

@@ -2,6 +2,7 @@
#include "IIDExports.h" #include "IIDExports.h"
#include "d3d11_x.g.h" #include "d3d11_x.g.h"
#include "ID3D11Runtime.h" #include "ID3D11Runtime.h"
#include "kernelx.h"
EXTERN_C HRESULT __stdcall EraD3D10CreateBlob() 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) EXTERN_C HRESULT __stdcall D3DMapEsramMemory(UINT Flags, void *pVirtualAddress, UINT NumPages, const UINT *pPageList)
{ {
IMPLEMENT_STUB(); DWORD flAllocationType = 0;
return E_NOTIMPL;
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 struct DXGIX_FRAME_STATISTICS

View File

@@ -15,7 +15,7 @@ set(FILES
include/WinDurango.KernelX/Hooks.h 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 target_link_libraries(WinDurango.KernelX PRIVATE
WinDurango.Common WinDurango.Common

View File

@@ -67,8 +67,20 @@ typedef HWND(WINAPI *PCreateWindowInBandEx)(DWORD dwExStyle, LPCWSTR lpClassName
int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu,
HINSTANCE hInstance, LPVOID lpParam, DWORD dwBand, DWORD dwTypeFlags); 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, 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, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance,
LPVOID lpParam, DWORD dwBand, DWORD dwTypeFlags); 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;

View File

@@ -361,7 +361,7 @@ EXTERN_C BOOL __stdcall EraDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode
{ {
if (hDevice != LoganHandle) if (hDevice != LoganHandle)
{ {
return DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize,
lpBytesReturned, lpOverlapped); lpBytesReturned, lpOverlapped);
} }
else else

View File

@@ -0,0 +1,111 @@
#pragma once
#include <mmdeviceapi.h>
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;
};

View File

@@ -4,6 +4,7 @@
#include "CurrentApp.h" #include "CurrentApp.h"
#include <detours.h> #include <detours.h>
#include <wrl.h> #include <wrl.h>
#include "MMDeviceEnumerator.h"
using namespace ABI::Windows::ApplicationModel::Store; using namespace ABI::Windows::ApplicationModel::Store;
@@ -161,6 +162,22 @@ HWND __stdcall EraCreateWindowInBandEx(DWORD dwExStyle, LPCWSTR lpClassName, LPC
hMenu, hInstance, lpParam, dwBand, dwTypeFlags); 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<IMMDeviceEnumerator*>(*ppv));
return S_OK;
}
return hr;
}
inline HRESULT WINAPI EraRoGetActivationFactory(HSTRING classId, REFIID iid, void **factory) inline HRESULT WINAPI EraRoGetActivationFactory(HSTRING classId, REFIID iid, void **factory)

View File

@@ -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;
}

View File

@@ -1,5 +1,6 @@
#include "Hooks.h" #include "Hooks.h"
#include "kernelx.h" #include "kernelx.h"
#include "Logan.h"
static DWORD ReasonForCall = 0; static DWORD ReasonForCall = 0;
@@ -18,23 +19,41 @@ void KernelxInitialize(HINSTANCE hinstDLL)
if (ReasonForCall == DLL_PROCESS_ATTACH || ReasonForCall == DLL_THREAD_ATTACH) if (ReasonForCall == DLL_PROCESS_ATTACH || ReasonForCall == DLL_THREAD_ATTACH)
{ {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
XWinePatchImport(GetModuleHandleW(nullptr), GetRuntimeModule(), XWinePatchImport(GetModuleHandleW(nullptr), GetRuntimeModule(),
"?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z", "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z",
GetActivationFactoryRedirect); GetActivationFactoryRedirect);
}
HMODULE User32 = LoadLibraryA("user32.dll"); //This is needed for DXVK.
if (User32) if (!User32) User32 = LoadLibraryA("user32.dll");
if (User32)
{
FARPROC CreateWindowInBandEx = GetProcAddress(User32, "CreateWindowInBandEx");
TrueCreateWindowInBandEx = reinterpret_cast<PCreateWindowInBandEx>(CreateWindowInBandEx);
DetourAttach(&reinterpret_cast<PVOID &>(TrueCreateWindowInBandEx), EraCreateWindowInBandEx);
}
DetourAttach(&reinterpret_cast<PVOID &>(TrueCoCreateInstance), EraCoCreateInstance);
DetourAttach(&reinterpret_cast<PVOID &>(TrueDeviceIoControl), EraDeviceIoControl);
DetourTransactionCommit();
}
else if (ReasonForCall == DLL_PROCESS_DETACH || ReasonForCall == DLL_THREAD_DETACH)
{ {
FARPROC CreateWindowInBandEx = GetProcAddress(User32, "CreateWindowInBandEx"); DetourTransactionBegin();
TrueCreateWindowInBandEx = reinterpret_cast<PCreateWindowInBandEx>(CreateWindowInBandEx); DetourUpdateThread(GetCurrentThread());
DetourAttach(&reinterpret_cast<PVOID &>(TrueCreateWindowInBandEx), EraCreateWindowInBandEx); DetourDetach(&reinterpret_cast<PVOID &>(TrueCreateWindowInBandEx), EraCreateWindowInBandEx);
DetourDetach(&reinterpret_cast<PVOID &>(TrueCoCreateInstance), EraCoCreateInstance);
DetourDetach(&reinterpret_cast<PVOID &>(TrueDeviceIoControl), EraDeviceIoControl);
DetourTransactionCommit();
} }
} }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{ {
InitializeCriticalSection(&XmpAllocationHookLock); InitializeCriticalSection(&XmpAllocationHookLock);
if (DetourIsHelperProcess()) return TRUE;
ReasonForCall = ul_reason_for_call; ReasonForCall = ul_reason_for_call;

View File

@@ -1,5 +1,8 @@
#include "kernelx.h" #include "kernelx.h"
#include "Logan.h" #include "Logan.h"
#include <atlbase.h>
#include "Hooks.h"
EXTERN_C CONSOLE_TYPE __stdcall GetConsoleType() EXTERN_C CONSOLE_TYPE __stdcall GetConsoleType()
{ {
return CONSOLE_TYPE_XBOX_ONE; return CONSOLE_TYPE_XBOX_ONE;
@@ -695,6 +698,65 @@ EXTERN_C void __stdcall XMemReleaseAuxiliaryTitleMemory(_In_opt_ HANDLE hHandle)
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 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, EXTERN_C HANDLE __stdcall EraCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
@@ -711,6 +773,37 @@ EXTERN_C HANDLE __stdcall EraCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAcce
return LoganHandle; 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, return CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile); dwFlagsAndAttributes, hTemplateFile);
} }
@@ -719,6 +812,10 @@ EXTERN_C HANDLE __stdcall EraCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAcces
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{ {
USES_CONVERSION;
LPCWSTR FileName = A2W(lpFileName);
FixRelativePath(FileName);
return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile); 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, EXTERN_C HANDLE __stdcall EraCreateFile2(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
DWORD dwCreationDisposition, LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) DWORD dwCreationDisposition, LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams)
{ {
FixRelativePath(lpFileName);
return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams);
} }
EXTERN_C BOOL __stdcall EraCreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) 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) 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) 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) EXTERN_C DWORD __stdcall EraGetFileAttributesW(LPCWSTR lpFileName)
{ {
FixRelativePath(lpFileName);
return GetFileAttributesW(lpFileName); return GetFileAttributesW(lpFileName);
} }
EXTERN_C BOOL __stdcall EraGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, EXTERN_C BOOL __stdcall EraGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFileInformation) LPVOID lpFileInformation)
{ {
FixRelativePath(lpFileName);
return GetFileAttributesExW(lpFileName, fInfoLevelId, lpFileInformation); return GetFileAttributesExW(lpFileName, fInfoLevelId, lpFileInformation);
} }
EXTERN_C HANDLE __stdcall EraFindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData) EXTERN_C HANDLE __stdcall EraFindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
{ {
FixRelativePath(lpFileName);
return FindFirstFileW(lpFileName, lpFindFileData); return FindFirstFileW(lpFileName, lpFindFileData);
} }
EXTERN_C BOOL __stdcall EraDeleteFileW(LPCWSTR lpFileName) EXTERN_C BOOL __stdcall EraDeleteFileW(LPCWSTR lpFileName)
{ {
FixRelativePath(lpFileName);
return DeleteFileW(lpFileName); return DeleteFileW(lpFileName);
} }
EXTERN_C HMODULE __stdcall EraLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) EXTERN_C HMODULE __stdcall EraLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{ {
FixRelativePath(lpLibFileName);
return LoadLibraryExW(lpLibFileName, hFile, dwFlags); return LoadLibraryExW(lpLibFileName, hFile, dwFlags);
} }

View File

@@ -3,6 +3,7 @@
"version": "1.0", "version": "1.0",
"dependencies": [ "dependencies": [
"cppwinrt", "cppwinrt",
"detours" "detours",
"directxtex"
] ]
} }