├── premake5.bat ├── tests ├── OverloadFromFolder │ ├── Win32 │ │ ├── input.bin │ │ ├── update │ │ │ └── input.bin │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample.exe │ │ ├── D3D11Sample.exe │ │ ├── D3D12Sample.exe │ │ ├── D3D9Sample.exe │ │ ├── DInput8Sample.exe │ │ └── shaders12.hlsl │ └── x64 │ │ ├── input.bin │ │ ├── update │ │ └── input.bin │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample64.exe │ │ ├── D3D11Sample64.exe │ │ ├── D3D12Sample64.exe │ │ ├── D3D9Sample64.exe │ │ ├── DInput8Sample64.exe │ │ └── shaders12.hlsl ├── OverloadFromFolderVirtualPath │ ├── x64 │ │ ├── input3.bin │ │ ├── input4.bin │ │ ├── storage │ │ │ ├── input3.bin │ │ │ └── input4.bin │ │ ├── D3DX9_43.dll │ │ ├── D3D9Sample64.exe │ │ ├── D3D10Sample64.exe │ │ ├── D3D11Sample64.exe │ │ ├── D3D12Sample64.exe │ │ ├── DInput8Sample64.exe │ │ └── shaders12.hlsl │ └── Win32 │ │ ├── input3.bin │ │ ├── input4.bin │ │ ├── storage │ │ ├── input3.bin │ │ └── input4.bin │ │ ├── D3D9Sample.exe │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample.exe │ │ ├── D3D11Sample.exe │ │ ├── D3D12Sample.exe │ │ ├── DInput8Sample.exe │ │ └── shaders12.hlsl ├── ASILoading │ ├── x64 │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample64.exe │ │ ├── D3D11Sample64.exe │ │ ├── D3D12Sample64.exe │ │ ├── D3D9Sample64.exe │ │ ├── DInput8Sample64.exe │ │ └── shaders12.hlsl │ └── Win32 │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample.exe │ │ ├── D3D11Sample.exe │ │ ├── D3D12Sample.exe │ │ ├── D3D9Sample.exe │ │ ├── DInput8Sample.exe │ │ └── shaders12.hlsl ├── OverloadFromFolderZipFile │ ├── x64 │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample64.exe │ │ ├── D3D11Sample64.exe │ │ ├── D3D12Sample64.exe │ │ ├── D3D9Sample64.exe │ │ ├── packages │ │ │ └── test.zip │ │ ├── DInput8Sample64.exe │ │ └── shaders12.hlsl │ └── Win32 │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample.exe │ │ ├── D3D11Sample.exe │ │ ├── D3D12Sample.exe │ │ ├── D3D9Sample.exe │ │ ├── DInput8Sample.exe │ │ ├── packages │ │ └── test.zip │ │ └── shaders12.hlsl ├── OverloadFromFolderVirtualFile │ ├── x64 │ │ ├── D3DX9_43.dll │ │ ├── D3D9Sample64.exe │ │ ├── D3D10Sample64.exe │ │ ├── D3D11Sample64.exe │ │ ├── D3D12Sample64.exe │ │ ├── DInput8Sample64.exe │ │ └── shaders12.hlsl │ └── Win32 │ │ ├── D3D9Sample.exe │ │ ├── D3DX9_43.dll │ │ ├── D3D10Sample.exe │ │ ├── D3D11Sample.exe │ │ ├── D3D12Sample.exe │ │ ├── DInput8Sample.exe │ │ └── shaders12.hlsl ├── tests.cpp └── test.bat ├── 7za.exe ├── premake5.exe ├── source ├── xlive │ ├── resource.h │ ├── xliveless.rc │ └── xliveless.h ├── resources │ ├── UALx64.rc │ ├── UALx86.rc │ ├── icon.ico │ ├── icon1.ico │ ├── icon2.ico │ ├── binkw32.dll │ ├── wndmode.dll │ ├── VersionInfo.h │ ├── Versioninfo.rc │ ├── vorbisfile.dll │ ├── wndmode.ini │ ├── logo.svg │ └── logo2.svg ├── demo_plugins │ ├── plugins │ │ └── MessageBox.NET.dll │ ├── MessageBox.cpp │ ├── ExeUnprotect.cpp │ ├── RE7Demo.InfiniteAmmo.cpp │ ├── VirtualFileServer.cpp │ └── MonoLoader.cpp └── exception.hpp ├── .github ├── funding.yml ├── dependabot.yml └── workflows │ └── msbuild.yml ├── data └── scripts │ └── global.ini ├── release-x64.bat ├── .gitmodules ├── release-Win32.bat ├── .gitattributes ├── license ├── external ├── miniz │ └── LICENSE └── ModuleList │ └── ModuleList.hpp ├── appveyor.yml ├── release.bat ├── release.ps1 ├── .gitignore ├── release.md ├── premake5.lua └── readme.md /premake5.bat: -------------------------------------------------------------------------------- 1 | premake5 vs2022 -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/input.bin: -------------------------------------------------------------------------------- 1 | update_test_failed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/input.bin: -------------------------------------------------------------------------------- 1 | update_test_failed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/update/input.bin: -------------------------------------------------------------------------------- 1 | update_test_passed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/update/input.bin: -------------------------------------------------------------------------------- 1 | update_test_passed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/input3.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_failed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/input4.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_passed.txt -------------------------------------------------------------------------------- /7za.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/7za.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/input3.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_failed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/input4.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_passed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/storage/input3.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_passed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/storage/input4.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_failed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/storage/input3.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_passed.txt -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/storage/input4.bin: -------------------------------------------------------------------------------- 1 | virtual_path_test_failed.txt -------------------------------------------------------------------------------- /premake5.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/premake5.exe -------------------------------------------------------------------------------- /source/xlive/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/xlive/resource.h -------------------------------------------------------------------------------- /source/resources/UALx64.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/UALx64.rc -------------------------------------------------------------------------------- /source/resources/UALx86.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/UALx86.rc -------------------------------------------------------------------------------- /source/resources/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/icon.ico -------------------------------------------------------------------------------- /source/resources/icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/icon1.ico -------------------------------------------------------------------------------- /source/resources/icon2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/icon2.ico -------------------------------------------------------------------------------- /source/xlive/xliveless.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/xlive/xliveless.rc -------------------------------------------------------------------------------- /source/resources/binkw32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/binkw32.dll -------------------------------------------------------------------------------- /source/resources/wndmode.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/wndmode.dll -------------------------------------------------------------------------------- /source/resources/VersionInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/VersionInfo.h -------------------------------------------------------------------------------- /source/resources/Versioninfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/Versioninfo.rc -------------------------------------------------------------------------------- /source/resources/vorbisfile.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/resources/vorbisfile.dll -------------------------------------------------------------------------------- /tests/ASILoading/x64/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/x64/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/ASILoading/Win32/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/Win32/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/ASILoading/Win32/D3D10Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/Win32/D3D10Sample.exe -------------------------------------------------------------------------------- /tests/ASILoading/Win32/D3D11Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/Win32/D3D11Sample.exe -------------------------------------------------------------------------------- /tests/ASILoading/Win32/D3D12Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/Win32/D3D12Sample.exe -------------------------------------------------------------------------------- /tests/ASILoading/Win32/D3D9Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/Win32/D3D9Sample.exe -------------------------------------------------------------------------------- /tests/ASILoading/x64/D3D10Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/x64/D3D10Sample64.exe -------------------------------------------------------------------------------- /tests/ASILoading/x64/D3D11Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/x64/D3D11Sample64.exe -------------------------------------------------------------------------------- /tests/ASILoading/x64/D3D12Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/x64/D3D12Sample64.exe -------------------------------------------------------------------------------- /tests/ASILoading/x64/D3D9Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/x64/D3D9Sample64.exe -------------------------------------------------------------------------------- /tests/ASILoading/Win32/DInput8Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/Win32/DInput8Sample.exe -------------------------------------------------------------------------------- /tests/ASILoading/x64/DInput8Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/ASILoading/x64/DInput8Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/x64/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/Win32/D3DX9_43.dll -------------------------------------------------------------------------------- /source/demo_plugins/plugins/MessageBox.NET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/source/demo_plugins/plugins/MessageBox.NET.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/D3D10Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/Win32/D3D10Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/D3D11Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/Win32/D3D11Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/D3D12Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/Win32/D3D12Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/D3D9Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/Win32/D3D9Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/D3D10Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/x64/D3D10Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/D3D11Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/x64/D3D11Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/D3D12Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/x64/D3D12Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/D3D9Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/x64/D3D9Sample64.exe -------------------------------------------------------------------------------- /.github/funding.yml: -------------------------------------------------------------------------------- 1 | github: ThirteenAG 2 | ko_fi: thirteenag 3 | patreon: ThirteenAG 4 | custom: [https://paypal.me/SergeyP13, https://boosty.to/thirteenag/donate] -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/DInput8Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/Win32/DInput8Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/DInput8Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolder/x64/DInput8Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/x64/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/x64/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/D3D10Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/D3D10Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/D3D11Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/D3D11Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/D3D12Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/D3D12Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/D3D9Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/D3D9Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/D3D10Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/D3D10Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/D3D11Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/D3D11Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/D3D12Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/D3D12Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/D3D9Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/D3D9Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/packages/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/packages/test.zip -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/D3D9Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/Win32/D3D9Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/Win32/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/D3D9Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/x64/D3D9Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/D3D9Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/Win32/D3D9Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/D3DX9_43.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/Win32/D3DX9_43.dll -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/D3D9Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/x64/D3D9Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/DInput8Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/DInput8Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/packages/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/Win32/packages/test.zip -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/DInput8Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderZipFile/x64/DInput8Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/D3D10Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/Win32/D3D10Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/D3D11Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/Win32/D3D11Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/D3D12Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/Win32/D3D12Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/D3D10Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/x64/D3D10Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/D3D11Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/x64/D3D11Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/D3D12Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/x64/D3D12Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/D3D10Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/Win32/D3D10Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/D3D11Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/Win32/D3D11Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/D3D12Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/Win32/D3D12Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/D3D10Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/x64/D3D10Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/D3D11Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/x64/D3D11Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/D3D12Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/x64/D3D12Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/DInput8Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/Win32/DInput8Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/DInput8Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualFile/x64/DInput8Sample64.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/DInput8Sample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/Win32/DInput8Sample.exe -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/DInput8Sample64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThirteenAG/Ultimate-ASI-Loader/HEAD/tests/OverloadFromFolderVirtualPath/x64/DInput8Sample64.exe -------------------------------------------------------------------------------- /source/demo_plugins/MessageBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) 4 | { 5 | if (reason == DLL_PROCESS_ATTACH) 6 | { 7 | MessageBox(0, TEXT("ASI Loader works correctly."), TEXT("ASI Loader Test Plugin"), MB_ICONWARNING); 8 | } 9 | return TRUE; 10 | } -------------------------------------------------------------------------------- /data/scripts/global.ini: -------------------------------------------------------------------------------- 1 | [GlobalSets] 2 | LoadPlugins=1 3 | LoadFromScriptsOnly=0 4 | LoadRecursively=1 5 | DontLoadFromDllMain=1 6 | ;LoadFromAPI=GetSystemTimeAsFileTime 7 | UseD3D8to9=0 8 | DisableCrashDumps=0 9 | Direct3D8DisableMaximizedWindowedModeShim=0 10 | 11 | [FileLoader] 12 | OverloadFromFolder=update 13 | -------------------------------------------------------------------------------- /release-x64.bat: -------------------------------------------------------------------------------- 1 | set list=d3d9, d3d10, d3d11, d3d12, dinput8, dsound, version, wininet, winmm, winhttp, binkw64, bink2w64, xinput1_1, xinput1_2, xinput1_3, xinput1_4, xinput9_1_0, xinputuap 2 | mkdir dist\x64 3 | cd bin\x64\Release\ 4 | (for %%a in (%list%) do ( 5 | copy dinput8.dll %%a.dll 6 | )) 7 | cd ../../../ 8 | (for %%a in (%list%) do ( 9 | 7za a -tzip ".\bin\%%a-x64.zip" ".\bin\x64\Release\%%a.dll" 10 | )) 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/d3d8to9"] 2 | path = external/d3d8to9 3 | url = https://github.com/crosire/d3d8to9 4 | branch = main 5 | [submodule "external/MemoryModule"] 6 | path = external/MemoryModule 7 | url = https://github.com/fancycode/MemoryModule 8 | [submodule "external/minidx9"] 9 | path = external/minidx9 10 | url = https://github.com/hrydgard/minidx9 11 | [submodule "external/injector"] 12 | path = external/injector 13 | url = https://github.com/ThirteenAG/injector 14 | -------------------------------------------------------------------------------- /release-Win32.bat: -------------------------------------------------------------------------------- 1 | set list=d3d8, d3d9, d3d10, d3d11, d3d12, ddraw, dinput, dinput8, dsound, msacm32, msvfw32, version, wininet, winmm, winhttp, xlive, vorbisFile, binkw32, bink2w32, xinput1_1, xinput1_2, xinput1_3, xinput1_4, xinput9_1_0, xinputuap 2 | mkdir dist\Win32 3 | cd .\bin\Win32\Release 4 | (for %%a in (%list%) do ( 5 | copy dinput8.dll %%a.dll 6 | )) 7 | cd ../../../ 8 | (for %%a in (%list%) do ( 9 | 7za a -tzip ".\bin\%%a-Win32.zip" ".\bin\Win32\Release\%%a.dll" 10 | )) 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /source/demo_plugins/ExeUnprotect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) 4 | { 5 | if (reason == DLL_PROCESS_ATTACH) 6 | { 7 | // Unprotect the module NOW 8 | auto hExecutableInstance = (size_t)GetModuleHandle(NULL); 9 | IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)(hExecutableInstance + ((IMAGE_DOS_HEADER*)hExecutableInstance)->e_lfanew); 10 | SIZE_T size = ntHeader->OptionalHeader.SizeOfImage; 11 | DWORD oldProtect; 12 | VirtualProtect((VOID*)hExecutableInstance, size, PAGE_EXECUTE_READWRITE, &oldProtect); 13 | } 14 | return TRUE; 15 | } -------------------------------------------------------------------------------- /source/resources/wndmode.ini: -------------------------------------------------------------------------------- 1 | [WINDOWMODE] 2 | UseWindowMode=1 3 | UseGDI=1 4 | UseDirect3D=1 5 | UseDirectInput=0 6 | UseDirectDraw=0 7 | UseDDrawColorEmulate=0 8 | UseDDrawFlipBlt=0 9 | UseDDrawColorConvert=0 10 | UseDDrawPrimaryBlt=0 11 | UseDDrawAutoBlt=0 12 | UseDDrawEmulate=0 13 | UseDDrawPrimaryLost=0 14 | UseCursorMsg=0 15 | UseCursorSet=0 16 | UseCursorGet=0 17 | UseSpeedHack=0 18 | SpeedHackMultiple=10 19 | UseBackgroundResize=0 20 | UseForegroundControl=0 21 | UseFGCGetActiveWindow=0 22 | UseFGCGetForegroundWindow=0 23 | UseFGCFixedWindowPosition=0 24 | EnableExtraKey=0 25 | ShowFps=0 26 | UseCursorClip=0 27 | UseBackgroundPriority=0 28 | DDrawBltWait=-1 29 | Border=0 -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "gitsubmodule" 14 | directory: "/" 15 | schedule: 16 | interval: "daily" 17 | groups: 18 | submodules: 19 | patterns: 20 | - "*" -------------------------------------------------------------------------------- /tests/ASILoading/x64/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/ASILoading/Win32/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolder/Win32/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolder/x64/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/x64/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/x64/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/x64/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolderZipFile/Win32/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualFile/Win32/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /tests/OverloadFromFolderVirtualPath/Win32/shaders12.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ThirteenAG 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /external/miniz/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013-2014 RAD Game Tools and Valve Software 2 | Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC 3 | 4 | All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /source/demo_plugins/RE7Demo.InfiniteAmmo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | DWORD WINAPI Thread(LPVOID) 5 | { 6 | MEMORY_BASIC_INFORMATION mbi = { 0 }; 7 | uintptr_t dwEndAddr; 8 | while (true) 9 | { 10 | Sleep(1000); 11 | 12 | while (VirtualQuery((VOID *)((uintptr_t)mbi.BaseAddress + mbi.RegionSize), &mbi, sizeof(MEMORY_BASIC_INFORMATION))) 13 | { 14 | if (mbi.Protect == PAGE_EXECUTE_READWRITE) 15 | { 16 | dwEndAddr = (uintptr_t)mbi.BaseAddress + mbi.RegionSize - 1 - 4; 17 | 18 | for (uintptr_t i = (uintptr_t)mbi.BaseAddress; i <= dwEndAddr; i++) 19 | { 20 | __try 21 | { 22 | if (*(uint64_t*)i == (uint64_t)0x49244889C9480F41) 23 | { 24 | if (*(uint32_t*)(i + sizeof(uint64_t)) == (uint32_t)0x4C50428B) 25 | { 26 | *(uint32_t*)i = 0x072440C7; 27 | *(uint32_t*)(i + 4) = 0x49000000; //mov [rax+24],00000007 28 | return 0; 29 | } 30 | } 31 | } 32 | __except (true) 33 | { 34 | i = dwEndAddr; 35 | } 36 | } 37 | } 38 | } 39 | } 40 | return 0; 41 | } 42 | 43 | 44 | BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD reason, LPVOID /*lpReserved*/) 45 | { 46 | if (reason == DLL_PROCESS_ATTACH) 47 | { 48 | CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&Thread, NULL, 0, NULL); 49 | } 50 | return TRUE; 51 | } -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 9.{build}.0 2 | skip_tags: true 3 | image: Visual Studio 2022 4 | configuration: Release 5 | install: 6 | - cmd: >- 7 | git submodule update --init --recursive 8 | 9 | premake5.exe vs2022 --with-version=%APPVEYOR_BUILD_VERSION% 10 | build: 11 | project: build/Ultimate-ASI-Loader-Win32.sln 12 | verbosity: minimal 13 | before_package: 14 | - cmd: msbuild.exe build/Ultimate-ASI-Loader-x64.sln /t:Build /p:Configuration=Release;Platform=x64 15 | after_build: 16 | - cmd: >- 17 | release.bat 18 | 19 | 20 | cd tests 21 | 22 | test.bat 23 | 24 | cd .. 25 | artifacts: 26 | - path: bin\Ultimate-ASI-Loader.zip 27 | name: Ultimate-ASI-Loader.zip 28 | - path: bin\Ultimate-ASI-Loader_x64.zip 29 | name: Ultimate-ASI-Loader_x64.zip 30 | - path: bin\RE7Demo.InfiniteAmmo-x64.zip 31 | name: RE7Demo.InfiniteAmmo-x64.zip 32 | - path: bin\MessageBox-x64.zip 33 | name: MessageBox-x64.zip 34 | - path: bin\VirtualFileServer-x64.zip 35 | name: OverloadFromFolderDLL-x64.zip 36 | - path: bin\ExeUnprotect-Win32.zip 37 | name: ExeUnprotect-Win32.zip 38 | - path: bin\MessageBox-Win32.zip 39 | name: MessageBox-Win32.zip 40 | - path: bin\MonoLoader-Win32.zip 41 | name: MonoLoader-Win32.zip 42 | - path: bin\MonoLoader-x64.zip 43 | name: MonoLoader-x64.zip 44 | deploy: 45 | - provider: GitHub 46 | tag: demo-plugins 47 | release: Ultimate ASI Loader Demo Plugins 48 | description: Demo plugins to test or extend Ultimate ASI Loader's functionality. 49 | auth_token: 50 | secure: ugbti+bXX/7zqu39OyiPxgRPd2pQn2FEV/12ABees2fHfpZob0tWXzqD/zSYmibJ 51 | artifact: RE7Demo.InfiniteAmmo-x64.zip, MessageBox-x64.zip, OverloadFromFolderDLL-x64.zip, ExeUnprotect-Win32.zip, MessageBox-Win32.zip, OverloadFromFolderDLL-Win32.zip, MonoLoader-Win32.zip, MonoLoader-x64.zip, VirtualFileServer-x64.zip 52 | force_update: true 53 | on: 54 | branch: master -------------------------------------------------------------------------------- /release.bat: -------------------------------------------------------------------------------- 1 | 7za a -tzip ".\bin\Ultimate-ASI-Loader.zip" ".\bin\Win32\Release\dinput8.dll" 2 | 7za a -tzip ".\bin\Ultimate-ASI-Loader_x64.zip" ".\bin\x64\Release\dinput8.dll" 3 | 4 | type nul >"bin\place both files in RESIDENT EVIL 7 biohazard Demo folder" 5 | 7za a -tzip ".\bin\ExeUnprotect-Win32.zip" ".\bin\Win32\Release\scripts\ExeUnprotect.asi" 6 | 7za a -tzip ".\bin\RE7Demo.InfiniteAmmo-x64.zip" ".\bin\x64\Release\dinput8.dll" ".\bin\x64\Release\scripts\RE7Demo.InfiniteAmmo.asi" ".\bin\place both files in RESIDENT EVIL 7 biohazard Demo folder" 7 | 7za a -tzip ".\bin\MessageBox-Win32.zip" ".\bin\Win32\Release\scripts\MessageBox.asi" 8 | 7za a -tzip ".\bin\MessageBox-x64.zip" ".\bin\x64\Release\scripts\MessageBox_x64.asi" 9 | 7za a -tzip ".\bin\MonoLoader-Win32.zip" ".\bin\Win32\Release\scripts\MonoLoader.asi" ".\source\demo_plugins\plugins\" 10 | 7za a -tzip ".\bin\MonoLoader-x64.zip" ".\bin\x64\Release\scripts\MonoLoader_x64.asi" ".\source\demo_plugins\plugins\" 11 | 7za a -tzip ".\bin\VirtualFileServer-x64.zip" ".\bin\x64\Release\VirtualFileServer.exe" 12 | EXIT 13 | 14 | 7-Zip Extra 15 | ~~~~~~~~~~~ 16 | License for use and distribution 17 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 | 19 | Copyright (C) 1999-2016 Igor Pavlov. 20 | 21 | 7-Zip Extra files are under the GNU LGPL license. 22 | 23 | 24 | Notes: 25 | You can use 7-Zip Extra on any computer, including a computer in a commercial 26 | organization. You don't need to register or pay for 7-Zip. 27 | 28 | 29 | GNU LGPL information 30 | -------------------- 31 | 32 | This library is free software; you can redistribute it and/or 33 | modify it under the terms of the GNU Lesser General Public 34 | License as published by the Free Software Foundation; either 35 | version 2.1 of the License, or (at your option) any later version. 36 | 37 | This library is distributed in the hope that it will be useful, 38 | but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 40 | Lesser General Public License for more details. 41 | 42 | You can receive a copy of the GNU Lesser General Public License from 43 | http://www.gnu.org/ 44 | 45 | -------------------------------------------------------------------------------- /release.ps1: -------------------------------------------------------------------------------- 1 | $aliases_array_Win32 = "d3d8", "d3d9", "d3d10", "d3d11", "d3d12", "dinput8", "ddraw", "dinput", "dsound", "msacm32", "msvfw32", "version", "wininet", "winmm", "winhttp", "xlive", "vorbisFile", "binkw32", "bink2w32", "xinput1_1", "xinput1_2", "xinput1_3", "xinput1_4", "xinput9_1_0", "xinputuap" 2 | $aliases_array_x64 = "d3d9", "d3d10", "d3d11", "d3d12", "dinput8", "dsound", "version", "wininet", "winmm", "winhttp", "binkw64", "bink2w64", "xinput1_1", "xinput1_2", "xinput1_3", "xinput1_4", "xinput9_1_0", "xinputuap" 3 | $platform_array = "Win32", "x64" 4 | $hash_alrg = "SHA512" 5 | 6 | foreach ($platform in $platform_array) 7 | { 8 | mkdir "dist\$platform\dll" 9 | mkdir "dist\$platform\zip" 10 | if ($platform -eq "Win32") { 11 | Move-Item ".\bin\$platform\Release\dinput8.dll" ".\bin\$platform\Release\_dinput8.dll" 12 | foreach ($file in $aliases_array_Win32) { 13 | Copy-Item ".\bin\$platform\Release\_dinput8.dll" ".\bin\$platform\Release\$file.dll" 14 | } 15 | } 16 | else 17 | { 18 | Move-Item ".\bin\$platform\Release\dinput8.dll" ".\bin\$platform\Release\_dinput8.dll" 19 | foreach ($file in $aliases_array_x64) { 20 | Copy-Item ".\bin\$platform\Release\_dinput8.dll" ".\bin\$platform\Release\$file.dll" 21 | } 22 | } 23 | if ($platform -eq "Win32") { 24 | foreach ($file in $aliases_array_Win32) { 25 | Get-FileHash ".\bin\$platform\Release\$file.dll" -Algorithm "$hash_alrg" | Format-List | Out-File -Encoding "utf8" ".\bin\$file-$platform.$hash_alrg" 26 | Copy-Item ".\bin\$platform\Release\$file.dll", ".\bin\$file-$platform.$hash_alrg" -Destination ".\dist\$platform\dll\" 27 | $compress = @{ 28 | Path = ".\bin\$platform\Release\$file.dll", ".\bin\$file-$platform.$hash_alrg" 29 | CompressionLevel = "NoCompression" 30 | DestinationPath = ".\dist\$platform\zip\$file-$platform.zip" 31 | } 32 | Compress-Archive @compress 33 | } 34 | } 35 | else 36 | { 37 | foreach ($file in $aliases_array_x64) { 38 | Get-FileHash ".\bin\$platform\Release\$file.dll" -Algorithm "$hash_alrg" | Format-List | Out-File -Encoding "utf8" ".\bin\$file-$platform.$hash_alrg" 39 | Copy-Item ".\bin\$platform\Release\$file.dll", ".\bin\$file-$platform.$hash_alrg" -Destination ".\dist\$platform\dll\" 40 | $compress = @{ 41 | Path = ".\bin\$platform\Release\$file.dll", ".\bin\$file-$platform.$hash_alrg" 42 | CompressionLevel = "NoCompression" 43 | DestinationPath = ".\dist\$platform\zip\$file-$platform.zip" 44 | } 45 | Compress-Archive @compress 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /source/resources/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /.github/workflows/msbuild.yml: -------------------------------------------------------------------------------- 1 | name: GitHub Actions Build 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - "**/*.md" 7 | - '**/*.txt' 8 | branches: 9 | - '**' 10 | pull_request: 11 | paths-ignore: 12 | - "**/*.md" 13 | - '**/*.txt' 14 | workflow_dispatch: 15 | inputs: 16 | release: 17 | description: "Create a release" 18 | type: choice 19 | required: false 20 | default: 'false' 21 | options: 22 | - 'true' 23 | - 'false' 24 | version_increment: 25 | description: "Default semantic version release type" 26 | type: choice 27 | required: false 28 | default: 'minor' 29 | options: 30 | - 'major' 31 | - 'minor' 32 | - 'patch' 33 | 34 | env: 35 | VERINC: ${{ github.event.inputs.version_increment || 'minor' }} 36 | 37 | concurrency: 38 | group: ${{ github.ref }} 39 | cancel-in-progress: false 40 | 41 | permissions: 42 | contents: write 43 | 44 | jobs: 45 | build: 46 | runs-on: windows-latest 47 | 48 | steps: 49 | - name: Checkout Repository 50 | uses: actions/checkout@v6 51 | with: 52 | submodules: recursive 53 | 54 | - name: Add msbuild to PATH 55 | uses: microsoft/setup-msbuild@main 56 | 57 | - name: Auto Increment Version 58 | uses: MCKanpolat/auto-semver-action@v2 59 | id: versioning 60 | with: 61 | releaseType: ${{ env.VERINC }} 62 | incrementPerCommit: false 63 | github_token: ${{ secrets.GITHUB_TOKEN }} 64 | 65 | - name: Configure build 66 | run: ./premake5 vs2022 --with-version=${{ steps.versioning.outputs.version }} 67 | 68 | - name: Build 69 | run: | 70 | msbuild -m build/Ultimate-ASI-Loader-x64.sln /property:Configuration=Release /property:Platform=x64 71 | msbuild -m build/Ultimate-ASI-Loader-Win32.sln /property:Configuration=Release /property:Platform=Win32 72 | 73 | - name: Pack binaries 74 | run: | 75 | ./release.bat 76 | ./release.ps1 77 | 78 | - name: Test 79 | shell: cmd 80 | run: | 81 | cd tests 82 | test.bat 83 | 84 | - name: Upload artifact (Win32) 85 | uses: actions/upload-artifact@v6 86 | with: 87 | name: Ultimate-ASI-Loader-Win32 88 | path: dist/Win32/dll/* 89 | 90 | - name: Upload artifact (x64) 91 | uses: actions/upload-artifact@v6 92 | with: 93 | name: Ultimate-ASI-Loader-x64 94 | path: dist/x64/dll/* 95 | 96 | - name: Upload Release (Main) 97 | if: | 98 | github.event.inputs.release == 'true' && 99 | github.ref_name == 'master' && 100 | github.repository == 'ThirteenAG/Ultimate-ASI-Loader' 101 | uses: ncipollo/release-action@main 102 | with: 103 | token: ${{ secrets.GITHUB_TOKEN }} 104 | allowUpdates: false 105 | name: Ultimate ASI Loader v${{ steps.versioning.outputs.version }} 106 | bodyFile: "release.md" 107 | tag: v${{ steps.versioning.outputs.version }} 108 | artifacts: bin/Ultimate-ASI-Loader.zip, bin/Ultimate-ASI-Loader_x64.zip 109 | 110 | - name: Get release info (Win32) 111 | if: | 112 | github.event.inputs.release == 'true' && 113 | github.ref_name == 'master' && 114 | github.repository == 'ThirteenAG/Ultimate-ASI-Loader' 115 | id: release_info_x86 116 | uses: cardinalby/git-get-release-action@master 117 | env: 118 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 119 | with: 120 | tag: Win32-latest 121 | 122 | - name: Upload Release (Win32) 123 | if: | 124 | github.event.inputs.release == 'true' && 125 | github.ref_name == 'master' && 126 | github.repository == 'ThirteenAG/Ultimate-ASI-Loader' 127 | uses: ncipollo/release-action@main 128 | with: 129 | token: ${{ secrets.GITHUB_TOKEN }} 130 | allowUpdates: true 131 | name: ${{ steps.release_info_x86.outputs.name }} 132 | body: ${{ steps.release_info_x86.outputs.body }} 133 | tag: ${{ steps.release_info_x86.outputs.tag_name }} 134 | artifacts: dist/Win32/zip/*.zip 135 | 136 | - name: Get release info (Win64) 137 | if: | 138 | github.event.inputs.release == 'true' && 139 | github.ref_name == 'master' && 140 | github.repository == 'ThirteenAG/Ultimate-ASI-Loader' 141 | id: release_info_x64 142 | uses: cardinalby/git-get-release-action@master 143 | env: 144 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 145 | with: 146 | tag: x64-latest 147 | 148 | - name: Upload Release (Win64) 149 | if: | 150 | github.event.inputs.release == 'true' && 151 | github.ref_name == 'master' && 152 | github.repository == 'ThirteenAG/Ultimate-ASI-Loader' 153 | uses: ncipollo/release-action@main 154 | with: 155 | token: ${{ secrets.GITHUB_TOKEN }} 156 | allowUpdates: true 157 | name: ${{ steps.release_info_x64.outputs.name }} 158 | body: ${{ steps.release_info_x64.outputs.body }} 159 | tag: ${{ steps.release_info_x64.outputs.tag_name }} 160 | artifacts: dist/x64/zip/*.zip 161 | -------------------------------------------------------------------------------- /source/resources/logo2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /external/ModuleList/ModuleList.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | std::wstring GetModuleFileNameW(HMODULE hModule) 9 | { 10 | static constexpr auto INITIAL_BUFFER_SIZE = MAX_PATH; 11 | static constexpr auto MAX_ITERATIONS = 7; 12 | std::wstring ret; 13 | auto bufferSize = INITIAL_BUFFER_SIZE; 14 | for (size_t iterations = 0; iterations < MAX_ITERATIONS; ++iterations) 15 | { 16 | ret.resize(bufferSize); 17 | auto charsReturned = GetModuleFileNameW(hModule, &ret[0], bufferSize); 18 | if (charsReturned < ret.length()) 19 | { 20 | ret.resize(charsReturned); 21 | return ret; 22 | } 23 | else 24 | { 25 | bufferSize *= 2; 26 | } 27 | } 28 | return L""; 29 | } 30 | 31 | auto starts_with = [](const std::wstring &big_str, const std::wstring &small_str) -> auto 32 | { 33 | return big_str.compare(0, small_str.length(), small_str) == 0; 34 | }; 35 | 36 | // Stores a list of loaded modules with their names, WITHOUT extension 37 | class ModuleList 38 | { 39 | public: 40 | enum class SearchLocation 41 | { 42 | All, 43 | LocalOnly, 44 | SystemOnly, 45 | }; 46 | 47 | // Initializes module list 48 | // Needs to be called before any calls to Get or GetAll 49 | void Enumerate( SearchLocation location = SearchLocation::All ) 50 | { 51 | constexpr size_t INITIAL_SIZE = sizeof(HMODULE) * 256; 52 | HMODULE* modules = static_cast(malloc( INITIAL_SIZE )); 53 | if ( modules != nullptr ) 54 | { 55 | typedef BOOL (WINAPI * Func)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded); 56 | 57 | HMODULE hLib = LoadLibrary( TEXT("kernel32") ); 58 | assert( hLib != nullptr ); // If this fails then everything is probably broken anyway 59 | 60 | Func pEnumProcessModules = reinterpret_cast(GetProcAddress( hLib, "K32EnumProcessModules" )); 61 | if ( pEnumProcessModules == nullptr ) 62 | { 63 | // Try psapi 64 | FreeLibrary( hLib ); 65 | hLib = LoadLibrary( TEXT("psapi") ); 66 | if ( hLib != nullptr ) 67 | { 68 | pEnumProcessModules = reinterpret_cast(GetProcAddress( hLib, "EnumProcessModules" )); 69 | } 70 | } 71 | 72 | if ( pEnumProcessModules != nullptr ) 73 | { 74 | const HANDLE currentProcess = GetCurrentProcess(); 75 | DWORD cbNeeded = 0; 76 | if ( pEnumProcessModules( currentProcess, modules, INITIAL_SIZE, &cbNeeded ) != 0 ) 77 | { 78 | if ( cbNeeded > INITIAL_SIZE ) 79 | { 80 | HMODULE* newModules = static_cast(realloc( modules, cbNeeded )); 81 | if ( newModules != nullptr ) 82 | { 83 | modules = newModules; 84 | 85 | if ( pEnumProcessModules( currentProcess, modules, cbNeeded, &cbNeeded ) != 0 ) 86 | { 87 | EnumerateInternal( modules, location, cbNeeded / sizeof(HMODULE) ); 88 | } 89 | } 90 | } 91 | else 92 | { 93 | EnumerateInternal( modules, location, cbNeeded / sizeof(HMODULE) ); 94 | } 95 | } 96 | } 97 | 98 | if ( hLib != nullptr ) 99 | { 100 | FreeLibrary( hLib ); 101 | } 102 | 103 | free( modules ); 104 | } 105 | } 106 | 107 | // Recreates module list 108 | void ReEnumerate( SearchLocation location = SearchLocation::All ) 109 | { 110 | Clear(); 111 | Enumerate( location ); 112 | } 113 | 114 | // Clears module list 115 | void Clear() 116 | { 117 | m_moduleList.clear(); 118 | } 119 | 120 | // Gets handle of a loaded module with given name, NULL otherwise 121 | HMODULE Get( const wchar_t* moduleName ) const 122 | { 123 | // If vector is empty then we're trying to call it without calling Enumerate first 124 | assert( m_moduleList.size() != 0 ); 125 | 126 | auto it = std::find_if( m_moduleList.begin(), m_moduleList.end(), [&]( const auto& e ) { 127 | return _wcsicmp( moduleName, std::get<1>(e).c_str() ) == 0; 128 | } ); 129 | return it != m_moduleList.end() ? std::get<0>(*it) : nullptr; 130 | } 131 | 132 | // Gets handles to all loaded modules with given name 133 | std::vector GetAll( const wchar_t* moduleName ) const 134 | { 135 | // If vector is empty then we're trying to call it without calling Enumerate first 136 | assert( m_moduleList.size() != 0 ); 137 | 138 | std::vector results; 139 | for ( auto& e : m_moduleList ) 140 | { 141 | if ( _wcsicmp( moduleName, std::get<1>(e).c_str()) == 0 ) 142 | { 143 | results.push_back(std::get<0>(e)); 144 | } 145 | } 146 | 147 | return results; 148 | } 149 | 150 | private: 151 | void EnumerateInternal( HMODULE* modules, SearchLocation location, size_t numModules ) 152 | { 153 | const auto exeModulePath = GetModuleFileNameW(NULL).substr(0, GetModuleFileNameW(NULL).find_last_of(L"/\\")); 154 | 155 | m_moduleList.reserve(numModules); 156 | for (size_t i = 0; i < numModules; i++) 157 | { 158 | // Obtain module name, with resizing if necessary 159 | auto moduleName = GetModuleFileNameW(*modules); 160 | 161 | if (!moduleName.empty()) 162 | { 163 | const wchar_t* nameBegin = wcsrchr(moduleName.c_str(), '\\') + 1; 164 | const wchar_t* dotPos = wcsrchr(nameBegin, '.'); 165 | bool isLocal = starts_with(std::wstring(moduleName), exeModulePath); 166 | 167 | if ( (isLocal && location != SearchLocation::SystemOnly) || (!isLocal && location != SearchLocation::LocalOnly) ) 168 | { 169 | if (dotPos != nullptr) 170 | { 171 | m_moduleList.emplace_back(*modules, std::wstring(nameBegin, dotPos), isLocal); 172 | } 173 | else 174 | { 175 | m_moduleList.emplace_back(*modules, nameBegin, isLocal); 176 | } 177 | } 178 | } 179 | 180 | modules++; 181 | } 182 | } 183 | 184 | public: std::vector< std::tuple > m_moduleList; 185 | }; -------------------------------------------------------------------------------- /tests/tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | HMODULE hUAL = NULL; 8 | 9 | std::filesystem::path GetModulePath(HMODULE hModule) 10 | { 11 | static constexpr auto INITIAL_BUFFER_SIZE = MAX_PATH; 12 | static constexpr auto MAX_ITERATIONS = 7; 13 | 14 | std::u16string ret; 15 | std::filesystem::path pathret; 16 | auto bufferSize = INITIAL_BUFFER_SIZE; 17 | for (size_t iterations = 0; iterations < MAX_ITERATIONS; ++iterations) 18 | { 19 | ret.resize(bufferSize); 20 | size_t charsReturned = 0; 21 | charsReturned = GetModuleFileNameW(hModule, (LPWSTR)&ret[0], bufferSize); 22 | if (charsReturned < ret.length()) 23 | { 24 | ret.resize(charsReturned); 25 | pathret = ret; 26 | return pathret; 27 | } 28 | else 29 | { 30 | bufferSize *= 2; 31 | } 32 | } 33 | 34 | return {}; 35 | } 36 | 37 | void Init() 38 | { 39 | // ASI Loading 40 | { 41 | auto mp = GetModulePath(NULL); 42 | auto filename = mp.filename(); 43 | filename.replace_extension(L".txt"); 44 | std::ofstream outfile(filename, std::ios::out | std::ios::binary); 45 | outfile.flush(); 46 | outfile.close(); 47 | } 48 | 49 | // Overload (folder) 50 | { 51 | std::ifstream ifs; 52 | ifs.open(L"input.bin", std::ifstream::in); 53 | std::string line; 54 | std::getline(ifs, line); 55 | std::ofstream outfile(line, std::ios::out | std::ios::binary); 56 | outfile.flush(); 57 | outfile.close(); 58 | } 59 | 60 | // Overload (virtual file) 61 | { 62 | bool (WINAPI* GetOverloadPathW)(wchar_t* out, size_t out_size) = nullptr; 63 | bool (WINAPI* AddVirtualFileForOverloadW)(const wchar_t* virtualPath, const uint8_t* data, size_t size, int priority) = nullptr; 64 | 65 | GetOverloadPathW = (decltype(GetOverloadPathW))GetProcAddress(hUAL, "GetOverloadPathW"); 66 | AddVirtualFileForOverloadW = (decltype(AddVirtualFileForOverloadW))GetProcAddress(hUAL, "AddVirtualFileForOverloadW"); 67 | 68 | unsigned char hexData[28] = { // virtual_file_test_passed.txt 69 | 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x5F, 0x66, 0x69, 0x6C, 0x65, 0x5F, 0x74, 0x65, 0x73, 70 | 0x74, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x2E, 0x74, 0x78, 0x74, 71 | }; 72 | 73 | // calling AddVirtualFile for the same path should append the data 74 | AddVirtualFileForOverloadW(L"input2.bin", &hexData[0], 14, 1000); 75 | AddVirtualFileForOverloadW(L"input2.bin", &hexData[14], 14, 1000); 76 | 77 | std::ifstream ifs; 78 | ifs.open(L"input2.bin", std::ifstream::in); 79 | std::string line; 80 | std::getline(ifs, line); 81 | std::ofstream outfile(line, std::ios::out | std::ios::binary); 82 | outfile.flush(); 83 | outfile.close(); 84 | 85 | AddVirtualFileForOverloadW(L"input3.bin", &hexData[14], 14, 1000); 86 | } 87 | 88 | // Overload (zip file) 89 | { 90 | std::ifstream ifs; 91 | ifs.open(L"input3.bin", std::ifstream::in); 92 | std::string line; 93 | std::getline(ifs, line); 94 | std::ofstream outfile(line, std::ios::out | std::ios::binary); 95 | outfile.flush(); 96 | outfile.close(); 97 | } 98 | 99 | // Overload (virtual path) 100 | { 101 | bool (WINAPI* GetOverloadPathW)(wchar_t* out, size_t out_size) = nullptr; 102 | bool (WINAPI* AddVirtualPathForOverloadW)(const wchar_t* originalPath, const wchar_t* virtualPath, int priority) = nullptr; 103 | void (WINAPI* RemoveVirtualPathFromOverloadW)(const wchar_t* originalPath) = nullptr; 104 | 105 | GetOverloadPathW = (decltype(GetOverloadPathW))GetProcAddress(hUAL, "GetOverloadPathW"); 106 | AddVirtualPathForOverloadW = (decltype(AddVirtualPathForOverloadW))GetProcAddress(hUAL, "AddVirtualPathForOverloadW"); 107 | RemoveVirtualPathFromOverloadW = (decltype(RemoveVirtualPathFromOverloadW))GetProcAddress(hUAL, "RemoveVirtualPathFromOverloadW"); 108 | 109 | AddVirtualPathForOverloadW(L"input3.bin", L"storage/input3.bin", 1001); // higher priority than input3.bin above to work 110 | AddVirtualPathForOverloadW(L"input4.bin", L"storage/input4.bin", 1001); 111 | RemoveVirtualPathFromOverloadW(L"input4.bin"); 112 | 113 | std::ifstream ifs; 114 | ifs.open(L"input3.bin", std::ifstream::in); 115 | std::string line; 116 | std::getline(ifs, line); 117 | 118 | if (line == "virtual_path_test_passed.txt") 119 | { 120 | std::ifstream ifs2; 121 | ifs2.open(L"input4.bin", std::ifstream::in); 122 | std::string line2; 123 | std::getline(ifs2, line2); 124 | std::ofstream outfile2(line2, std::ios::out | std::ios::binary); 125 | outfile2.flush(); 126 | outfile2.close(); 127 | } 128 | } 129 | 130 | ExitProcess(0); 131 | } 132 | 133 | extern "C" __declspec(dllexport) void InitializeASI() 134 | { 135 | static std::once_flag flag; 136 | std::call_once(flag, []() { 137 | Init(); 138 | }); 139 | } 140 | 141 | bool IsModuleUAL(HMODULE mod) 142 | { 143 | if (GetProcAddress(mod, "IsUltimateASILoader") != NULL || (GetProcAddress(mod, "DirectInput8Create") != NULL && GetProcAddress(mod, "DirectSoundCreate8") != NULL && GetProcAddress(mod, "InternetOpenA") != NULL)) 144 | return true; 145 | return false; 146 | } 147 | 148 | bool IsUALPresent() 149 | { 150 | for (const auto& entry : std::stacktrace::current()) 151 | { 152 | HMODULE hModule = NULL; 153 | if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)entry.native_handle(), &hModule)) 154 | { 155 | if (IsModuleUAL(hModule)) 156 | { 157 | hUAL = hModule; 158 | return true; 159 | } 160 | } 161 | } 162 | return false; 163 | } 164 | 165 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) 166 | { 167 | if (reason == DLL_PROCESS_ATTACH) 168 | { 169 | if (!IsUALPresent()) 170 | { 171 | InitializeASI(); 172 | } 173 | } 174 | return TRUE; 175 | } 176 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | data/ 12 | !data/**/*.ini 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | [Rr]eleases/ 22 | x64/ 23 | x86/ 24 | bld/ 25 | [Bb]in/ 26 | [Oo]bj/ 27 | [Ll]og/ 28 | [Bb]uild/ 29 | 30 | # Visual Studio 2015 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # TFS 2012 Local Workspace 100 | $tf/ 101 | 102 | # Guidance Automation Toolkit 103 | *.gpState 104 | 105 | # ReSharper is a .NET coding add-in 106 | _ReSharper*/ 107 | *.[Rr]e[Ss]harper 108 | *.DotSettings.user 109 | 110 | # JustCode is a .NET coding add-in 111 | .JustCode 112 | 113 | # TeamCity is a build add-in 114 | _TeamCity* 115 | 116 | # DotCover is a Code Coverage Tool 117 | *.dotCover 118 | 119 | # Visual Studio code coverage results 120 | *.coverage 121 | *.coveragexml 122 | 123 | # NCrunch 124 | _NCrunch_* 125 | .*crunch*.local.xml 126 | nCrunchTemp_* 127 | 128 | # MightyMoose 129 | *.mm.* 130 | AutoTest.Net/ 131 | 132 | # Web workbench (sass) 133 | .sass-cache/ 134 | 135 | # Installshield output folder 136 | [Ee]xpress/ 137 | 138 | # DocProject is a documentation generator add-in 139 | DocProject/buildhelp/ 140 | DocProject/Help/*.HxT 141 | DocProject/Help/*.HxC 142 | DocProject/Help/*.hhc 143 | DocProject/Help/*.hhk 144 | DocProject/Help/*.hhp 145 | DocProject/Help/Html2 146 | DocProject/Help/html 147 | 148 | # Click-Once directory 149 | publish/ 150 | 151 | # Publish Web Output 152 | *.[Pp]ublish.xml 153 | *.azurePubxml 154 | # TODO: Comment the next line if you want to checkin your web deploy settings 155 | # but database connection strings (with potential passwords) will be unencrypted 156 | *.pubxml 157 | *.publishproj 158 | 159 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 160 | # checkin your Azure Web App publish settings, but sensitive information contained 161 | # in these scripts will be unencrypted 162 | PublishScripts/ 163 | 164 | # NuGet Packages 165 | *.nupkg 166 | # The packages folder can be ignored because of Package Restore 167 | **/packages/* 168 | # except build/, which is used as an MSBuild target. 169 | !**/packages/build/ 170 | # Uncomment if necessary however generally it will be regenerated when needed 171 | #!**/packages/repositories.config 172 | # NuGet v3's project.json files produces more ignorable files 173 | *.nuget.props 174 | *.nuget.targets 175 | 176 | # Microsoft Azure Build Output 177 | csx/ 178 | *.build.csdef 179 | 180 | # Microsoft Azure Emulator 181 | ecf/ 182 | rcf/ 183 | 184 | # Windows Store app package directories and files 185 | AppPackages/ 186 | BundleArtifacts/ 187 | Package.StoreAssociation.xml 188 | _pkginfo.txt 189 | 190 | # Visual Studio cache files 191 | # files ending in .cache can be ignored 192 | *.[Cc]ache 193 | # but keep track of directories ending in .cache 194 | !*.[Cc]ache/ 195 | 196 | # Others 197 | ClientBin/ 198 | ~$* 199 | *~ 200 | *.dbmdl 201 | *.dbproj.schemaview 202 | *.jfm 203 | *.pfx 204 | *.publishsettings 205 | orleans.codegen.cs 206 | 207 | # Since there are multiple workflows, uncomment next line to ignore bower_components 208 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 209 | #bower_components/ 210 | 211 | # RIA/Silverlight projects 212 | Generated_Code/ 213 | 214 | # Backup & report files from converting an old project file 215 | # to a newer Visual Studio version. Backup files are not needed, 216 | # because we have git ;-) 217 | _UpgradeReport_Files/ 218 | Backup*/ 219 | UpgradeLog*.XML 220 | UpgradeLog*.htm 221 | 222 | # SQL Server files 223 | *.mdf 224 | *.ldf 225 | *.ndf 226 | 227 | # Business Intelligence projects 228 | *.rdl.data 229 | *.bim.layout 230 | *.bim_*.settings 231 | 232 | # Microsoft Fakes 233 | FakesAssemblies/ 234 | 235 | # GhostDoc plugin setting file 236 | *.GhostDoc.xml 237 | 238 | # Node.js Tools for Visual Studio 239 | .ntvs_analysis.dat 240 | node_modules/ 241 | 242 | # Typescript v1 declaration files 243 | typings/ 244 | 245 | # Visual Studio 6 build log 246 | *.plg 247 | 248 | # Visual Studio 6 workspace options file 249 | *.opt 250 | 251 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 252 | *.vbw 253 | 254 | # Visual Studio LightSwitch build output 255 | **/*.HTMLClient/GeneratedArtifacts 256 | **/*.DesktopClient/GeneratedArtifacts 257 | **/*.DesktopClient/ModelManifest.xml 258 | **/*.Server/GeneratedArtifacts 259 | **/*.Server/ModelManifest.xml 260 | _Pvt_Extensions 261 | 262 | # Paket dependency manager 263 | .paket/paket.exe 264 | paket-files/ 265 | 266 | # FAKE - F# Make 267 | .fake/ 268 | 269 | # JetBrains Rider 270 | .idea/ 271 | *.sln.iml 272 | 273 | # CodeRush 274 | .cr/ 275 | 276 | # Python Tools for Visual Studio (PTVS) 277 | __pycache__/ 278 | *.pyc 279 | 280 | # Cake - Uncomment if you are using it 281 | # tools/** 282 | # !tools/packages.config 283 | 284 | # Telerik's JustMock configuration file 285 | *.jmconfig 286 | 287 | # BizTalk build output 288 | *.btp.cs 289 | *.btm.cs 290 | *.odx.cs 291 | *.xsd.cs 292 | 293 | # Tests 294 | tests/**/*.exe 295 | tests/**/*.dll 296 | tests/**/*.asi 297 | tests/**/*.txt 298 | !tests/**/*[Ss]ample*.exe 299 | !tests/**/**.zip 300 | !tests/**/*[Dd]3[Dd][Xx]9_43.dll 301 | !tests/**/x64 302 | -------------------------------------------------------------------------------- /tests/test.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal EnableDelayedExpansion 3 | 4 | REM Ensure script runs from its own directory 5 | cd /d "%~dp0" || ( 6 | echo Error: Failed to set working directory to %~dp0 7 | exit /b 1 8 | ) 9 | 10 | REM Define directories and executables 11 | set "BASE_DIR=%CD%" 12 | 13 | set "DIRECTORIES=ASILoading OverloadFromFolder OverloadFromFolderVirtualFile OverloadFromFolderZipFile OverloadFromFolderVirtualPath" 14 | set "TEST_FILES=ASILoading:dynamic:dynamic OverloadFromFolder:update_test_passed.txt:update_test_passed.txt OverloadFromFolderVirtualFile:virtual_file_test_passed.txt:virtual_file_test_passed.txt OverloadFromFolderZipFile:zip_file_test_passed.txt:zip_file_test_passed.txt OverloadFromFolderVirtualPath:virtual_path_test_passed.txt:virtual_path_test_passed.txt" 15 | set "X86_SAMPLES=DInput8Sample.exe D3D9Sample.exe D3D10Sample.exe D3D11Sample.exe D3D12Sample.exe" 16 | set "X64_SAMPLES=DInput8Sample64.exe D3D9Sample64.exe D3D10Sample64.exe D3D11Sample64.exe D3D12Sample64.exe" 17 | set "X86_DLLS=dinput8.dll d3d9.dll d3d10.dll d3d11.dll d3d12.dll" 18 | set "X64_DLLS=dinput8.dll d3d9.dll d3d10.dll d3d11.dll d3d12.dll" 19 | 20 | REM Process Win32 and x64 directories 21 | for %%A in (Win32 x64) do ( 22 | set "ARCH=%%A" 23 | if "!ARCH!"=="Win32" ( 24 | set "SAMPLES=%X86_SAMPLES%" 25 | set "DLLS=%X86_DLLS%" 26 | ) else ( 27 | set "SAMPLES=%X64_SAMPLES%" 28 | set "DLLS=%X64_DLLS%" 29 | ) 30 | 31 | for %%D in (%DIRECTORIES%) do ( 32 | set "D=%%D" 33 | if not exist "%%D\!ARCH!\" ( 34 | echo Error: Directory %%D\!ARCH! does not exist 35 | dir "%%D" 2>nul 36 | cd /d "%BASE_DIR%" 37 | exit /b 1 38 | ) 39 | 40 | REM Change to target directory and verify 41 | pushd "%%D\!ARCH!" || ( 42 | echo Error: Failed to change to directory %%D\!ARCH! 43 | dir "%%D" 2>nul 44 | cd /d "%BASE_DIR%" 45 | exit /b 1 46 | ) 47 | set "CURRENT_DIR=%CD%" 48 | 49 | REM Clean up existing .txt files and specific DLLs (exclude D3DX9_43.dll) 50 | del /s *.txt >nul 2>&1 51 | for %%L in (!DLLS!) do ( 52 | del /s "%%L" >nul 2>&1 53 | ) 54 | 55 | REM Copy Test_*.asi file 56 | copy "..\..\..\bin\!ARCH!\Release\Test_!ARCH!.asi" "Test_!ARCH!.asi" >nul 57 | if not exist "Test_!ARCH!.asi" ( 58 | echo Error: Test_!ARCH!.asi not found in !CURRENT_DIR! 59 | popd 60 | cd /d "%BASE_DIR%" 61 | exit /b 1 62 | ) 63 | 64 | REM Check if dinput8.dll exists 65 | if not exist "..\..\..\bin\!ARCH!\Release\dinput8.dll" ( 66 | echo Error: dinput8.dll not found in ..\..\..\bin\!ARCH!\Release 67 | popd 68 | cd /d "%BASE_DIR%" 69 | exit /b 1 70 | ) 71 | 72 | REM Counter to align executables with DLLs 73 | set "INDEX=0" 74 | for %%E in (!SAMPLES!) do ( 75 | set "E=%%E" 76 | if not exist "!E!" ( 77 | echo Error: Executable !E! not found in !CURRENT_DIR! 78 | popd 79 | cd /d "%BASE_DIR%" 80 | exit /b 1 81 | ) 82 | 83 | REM Get the corresponding DLL name by index 84 | set "CURRENT_DLL=" 85 | set "DLL_INDEX=0" 86 | for %%L in (!DLLS!) do ( 87 | if !DLL_INDEX! equ !INDEX! ( 88 | set "CURRENT_DLL=%%L" 89 | ) 90 | set /a DLL_INDEX+=1 91 | ) 92 | 93 | if not defined CURRENT_DLL ( 94 | echo Error: No DLL defined for !E! in !ARCH! 95 | popd 96 | cd /d "%BASE_DIR%" 97 | exit /b 1 98 | ) 99 | 100 | REM Copy dinput8.dll as the expected DLL name 101 | copy "..\..\..\bin\!ARCH!\Release\dinput8.dll" "!CURRENT_DLL!" >nul 102 | 103 | REM Copy VirtualFileServer.exe if not ASILoading 104 | if not "!D!"=="ASILoading" ( 105 | if not exist "..\..\..\bin\x64\Release\VirtualFileServer.exe" ( 106 | echo Error: VirtualFileServer.exe not found in ..\..\..\bin\x64\Release 107 | popd 108 | cd /d "%BASE_DIR%" 109 | exit /b 1 110 | ) 111 | copy "..\..\..\bin\x64\Release\VirtualFileServer.exe" "!CURRENT_DLL:~0,-4!.exe" >nul 112 | ) 113 | 114 | REM Get the expected test file for this directory 115 | set "TEST_FILE=" 116 | for %%T in (%TEST_FILES%) do ( 117 | for /F "tokens=1,2,3 delims=:" %%X in ("%%T") do ( 118 | if "%%X"=="%%D" ( 119 | if "%%D"=="ASILoading" ( 120 | REM Derive test file from executable name for ASILoading 121 | set "TEST_FILE=!E:~0,-4!.txt" 122 | ) else if "!ARCH!"=="Win32" ( 123 | set "TEST_FILE=%%Y" 124 | ) else ( 125 | set "TEST_FILE=%%Z" 126 | ) 127 | ) 128 | ) 129 | ) 130 | 131 | if not defined TEST_FILE ( 132 | echo Error: No test file defined for !D! in !ARCH! 133 | popd 134 | cd /d "%BASE_DIR%" 135 | exit /b 1 136 | ) 137 | 138 | REM Run the executable 139 | start /W /B "" "!E!" 140 | 141 | if exist "!TEST_FILE!" ( 142 | echo !ARCH! !D! Test for !E! PASSED 143 | del "!TEST_FILE!" 144 | taskkill /IM "!E!" /F >nul 2>&1 145 | ) else ( 146 | echo !ARCH! !D! Test for !E! FAILED 147 | for %%L in (!DLLS!) do ( 148 | del /s "%%L" >nul 2>&1 149 | ) 150 | if not "!D!"=="ASILoading" ( 151 | del "!CURRENT_DLL:~0,-4!.exe" >nul 2>&1 152 | ) 153 | popd 154 | cd /d "%BASE_DIR%" 155 | exit /b 1 156 | ) 157 | 158 | REM Clean up specific DLL and VirtualFileServer.exe (if copied), preserve D3DX9_43.dll 159 | for %%L in (!DLLS!) do ( 160 | del /s "%%L" >nul 2>&1 161 | ) 162 | if not "!D!"=="ASILoading" ( 163 | del "!CURRENT_DLL:~0,-4!.exe" >nul 2>&1 164 | ) 165 | 166 | REM Increment index for next executable-DLL pair 167 | set /a INDEX+=1 168 | ) 169 | 170 | popd 171 | ) 172 | ) 173 | 174 | echo All tests completed successfully. 175 | endlocal 176 | exit /b 0 -------------------------------------------------------------------------------- /release.md: -------------------------------------------------------------------------------- 1 | This is a DLL file that adds ASI plugin loading functionality to any game that uses any of the following libraries: 2 | 3 | | Win32 | Win64 | 4 | | :-----------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------: | 5 | | [d3d8.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d8-Win32.zip) | - | 6 | | [d3d9.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d9-Win32.zip) | [d3d9.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d9-x64.zip) | 7 | | [d3d10.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d10-Win32.zip) | [d3d10.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d10-x64.zip) | 8 | | [d3d11.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d11-Win32.zip) | [d3d11.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d11-x64.zip) | 9 | | [d3d12.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d12-Win32.zip) | [d3d12.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d12-x64.zip) | 10 | | [ddraw.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/ddraw-Win32.zip) | - | 11 | | [dinput.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/dinput-Win32.zip) | - | 12 | | [dinput8.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/dinput8-Win32.zip) | [dinput8.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/dinput8-x64.zip) | 13 | | [dsound.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/dsound-Win32.zip) | [dsound.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/dsound-x64.zip) | 14 | | [msacm32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/msacm32-Win32.zip) | - | 15 | | [msvfw32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/msvfw32-Win32.zip) | - | 16 | | [version.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/version-Win32.zip) | [version.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/version-x64.zip) | 17 | | [wininet.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/wininet-Win32.zip) | [wininet.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/wininet-x64.zip) | 18 | | [winmm.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/winmm-Win32.zip) | [winmm.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/winmm-x64.zip) | 19 | | [winhttp.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/winhttp-Win32.zip) | [winhttp.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/winhttp-x64.zip) | 20 | | [xlive.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xlive-Win32.zip) | - | 21 | | [binkw32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/binkw32-Win32.zip) | - | 22 | | [bink2w32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/bink2w32-Win32.zip) | - | 23 | | - | [binkw64.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/binkw64-x64.zip) | 24 | | - | [bink2w64.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/bink2w64-x64.zip) | 25 | | [vorbisFile.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/vorbisFile-Win32.zip) | - | 26 | | [xinput1_1.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_1-Win32.zip) | [xinput1_1.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_1-x64.zip) | 27 | | [xinput1_2.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_2-Win32.zip) | [xinput1_2.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_2-x64.zip) | 28 | | [xinput1_3.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_3-Win32.zip) | [xinput1_3.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_3-x64.zip) | 29 | | [xinput1_4.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_4-Win32.zip) | [xinput1_4.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_4-x64.zip) | 30 | | [xinput9_1_0.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput9_1_0-Win32.zip) | [xinput9_1_0.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput9_1_0-x64.zip) | 31 | | [xinputuap.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinputuap-Win32.zip) | [xinputuap.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinputuap-x64.zip) | 32 | 33 | It is possible (and sometimes necessary) to load the original DLL by renaming it to `Hooked.dll`, e.g. `d3d12Hooked.dll`. 34 | With **binkw32.dll** and **vorbisFile.dll**, it is optional, and you can simply replace the DLL. Always make a backup before replacing any files. 35 | 36 | 37 | ## INSTALLATION 38 | 39 | To install it, you just need to place the DLL into the game directory. Usually, it works as dinput8.dll, but if that doesn't work, you can rename it (see the list of supported names above). 40 | 41 | ## USAGE 42 | 43 | Put ASI files in the game's root directory or in the `scripts`, `plugins`, or `update` folder. -------------------------------------------------------------------------------- /source/demo_plugins/VirtualFileServer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // Command structure matching the updated client 12 | struct ServerCommand 13 | { 14 | enum Type : uint32_t 15 | { 16 | ADD_FILE = 1, 17 | APPEND_FILE = 2, 18 | REMOVE_FILE = 3, 19 | GET_SIZE = 4, 20 | READ_FILE = 5 21 | }; 22 | uint32_t command; 23 | uint64_t server_handle; // Used for most commands 24 | uint64_t data_size; // For ADD/APPEND/READ 25 | int32_t priority; // For ADD 26 | uint64_t offset; // For READ 27 | }; 28 | 29 | // Represents a file stored in the server's memory 30 | struct StoredFile 31 | { 32 | std::vector data; 33 | int32_t priority; 34 | }; 35 | 36 | // Global map to store files, keyed by a unique handle 37 | std::unordered_map> g_serverFileSystem; 38 | std::mutex g_fileSystemMutex; 39 | std::atomic g_nextHandle = 1; // Start handles from 1 40 | 41 | // Handles a single client connection 42 | void HandleClient(HANDLE hPipe) 43 | { 44 | DWORD clientPid = 0; 45 | DWORD bytesRead = 0; 46 | if (!ReadFile(hPipe, &clientPid, sizeof(clientPid), &bytesRead, NULL) || bytesRead != sizeof(clientPid)) 47 | { 48 | std::wcerr << L"Server: Failed to read client PID." << std::endl; 49 | return; 50 | } 51 | std::wcout << L"Server: Connected to client with PID: " << clientPid << std::endl; 52 | 53 | HANDLE hClientProcess = OpenProcess(SYNCHRONIZE, FALSE, clientPid); 54 | 55 | while (true) 56 | { 57 | if (hClientProcess != NULL && WaitForSingleObject(hClientProcess, 0) == WAIT_OBJECT_0) 58 | { 59 | std::wcout << L"Server: Client process " << clientPid << " has terminated. Closing connection." << std::endl; 60 | CloseHandle(hClientProcess); 61 | break; 62 | } 63 | 64 | ServerCommand cmd = { 0 }; 65 | bytesRead = 0; 66 | BOOL bSuccess = ReadFile(hPipe, &cmd, sizeof(ServerCommand), &bytesRead, NULL); 67 | 68 | if (!bSuccess || bytesRead == 0) 69 | { 70 | if (GetLastError() == ERROR_BROKEN_PIPE) 71 | std::wcout << L"Server: Client disconnected." << std::endl; 72 | else 73 | std::wcerr << L"Server: ReadFile failed with error " << GetLastError() << std::endl; 74 | break; 75 | } 76 | 77 | std::lock_guard lock(g_fileSystemMutex); 78 | switch (cmd.command) 79 | { 80 | case ServerCommand::ADD_FILE: 81 | { 82 | std::vector data(cmd.data_size); 83 | if (cmd.data_size > 0) 84 | { 85 | if (!ReadFile(hPipe, data.data(), (DWORD)cmd.data_size, &bytesRead, NULL) || bytesRead != cmd.data_size) 86 | { 87 | std::wcerr << L"Server: Failed to read data for ADD_FILE." << std::endl; 88 | continue; 89 | } 90 | } 91 | 92 | uint64_t newHandle = g_nextHandle.fetch_add(1); 93 | auto newFile = std::make_shared(); 94 | newFile->data = std::move(data); 95 | newFile->priority = cmd.priority; 96 | g_serverFileSystem[newHandle] = newFile; 97 | 98 | DWORD bytesWritten; 99 | if (!WriteFile(hPipe, &newHandle, sizeof(newHandle), &bytesWritten, NULL) || bytesWritten != sizeof(newHandle)) 100 | { 101 | std::wcerr << L"Server: Failed to send new handle to client." << std::endl; 102 | } 103 | std::wcout << L"Server: ADD_FILE successful. Handle: " << newHandle << std::endl; 104 | break; 105 | } 106 | case ServerCommand::APPEND_FILE: 107 | { 108 | auto it = g_serverFileSystem.find(cmd.server_handle); 109 | if (it != g_serverFileSystem.end()) 110 | { 111 | std::vector dataToAppend(cmd.data_size); 112 | if (cmd.data_size > 0) 113 | { 114 | if (!ReadFile(hPipe, dataToAppend.data(), (DWORD)cmd.data_size, &bytesRead, NULL) || bytesRead != cmd.data_size) 115 | { 116 | std::wcerr << L"Server: Failed to read data for APPEND_FILE." << std::endl; 117 | continue; 118 | } 119 | it->second->data.insert(it->second->data.end(), dataToAppend.begin(), dataToAppend.end()); 120 | std::wcout << L"Server: APPEND_FILE successful for handle: " << cmd.server_handle << std::endl; 121 | } 122 | } 123 | break; 124 | } 125 | case ServerCommand::REMOVE_FILE: 126 | { 127 | g_serverFileSystem.erase(cmd.server_handle); 128 | std::wcout << L"Server: REMOVE_FILE for handle: " << cmd.server_handle << std::endl; 129 | break; 130 | } 131 | case ServerCommand::READ_FILE: 132 | { 133 | DWORD bytesToSend = 0; 134 | std::vector buffer; 135 | auto it = g_serverFileSystem.find(cmd.server_handle); 136 | if (it != g_serverFileSystem.end()) 137 | { 138 | const auto& storedFile = it->second; 139 | if (cmd.offset < storedFile->data.size()) 140 | { 141 | uint64_t remainingBytes = storedFile->data.size() - cmd.offset; 142 | bytesToSend = static_cast(min((uint64_t)cmd.data_size, remainingBytes)); 143 | if (bytesToSend > 0) 144 | { 145 | buffer.resize(bytesToSend); 146 | memcpy(buffer.data(), storedFile->data.data() + cmd.offset, bytesToSend); 147 | } 148 | } 149 | } 150 | 151 | DWORD bytesWritten; 152 | if (!WriteFile(hPipe, &bytesToSend, sizeof(bytesToSend), &bytesWritten, NULL)) break; 153 | if (bytesToSend > 0) 154 | { 155 | if (!WriteFile(hPipe, buffer.data(), bytesToSend, &bytesWritten, NULL)) break; 156 | } 157 | break; 158 | } 159 | default: 160 | std::wcerr << L"Server: Unknown command received: " << cmd.command << std::endl; 161 | break; 162 | } 163 | } 164 | 165 | if (hClientProcess) CloseHandle(hClientProcess); 166 | DisconnectNamedPipe(hPipe); 167 | CloseHandle(hPipe); 168 | } 169 | 170 | int main() 171 | { 172 | HANDLE hMutex = CreateMutexW(NULL, TRUE, L"Global\\Ultimate-ASI-Loader-VirtualFileClientMutex"); 173 | if (!hMutex || GetLastError() != ERROR_ALREADY_EXISTS) 174 | { 175 | // Mutex does not exist, exit 176 | std::wcerr << L"Server: Client mutex not found. Exiting." << std::endl; 177 | if (hMutex) CloseHandle(hMutex); 178 | return 1; 179 | } 180 | 181 | const wchar_t* pipeName = L"\\\\.\\pipe\\Ultimate-ASI-Loader-VirtualFileServer"; 182 | std::wcout << L"Server: Starting virtual file server..." << std::endl; 183 | 184 | while (true) 185 | { 186 | HANDLE hPipe = CreateNamedPipeW( 187 | pipeName, PIPE_ACCESS_DUPLEX, 188 | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 189 | PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, NULL); 190 | 191 | if (hPipe == INVALID_HANDLE_VALUE) 192 | { 193 | std::wcerr << L"Server: CreateNamedPipe failed, GLE=" << GetLastError() << std::endl; 194 | return 1; 195 | } 196 | 197 | std::wcout << L"Server: Pipe created. Waiting for client connection..." << std::endl; 198 | 199 | if (ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED)) 200 | { 201 | std::thread(HandleClient, hPipe).detach(); 202 | } 203 | else 204 | { 205 | CloseHandle(hPipe); 206 | } 207 | } 208 | 209 | return 0; 210 | } -------------------------------------------------------------------------------- /premake5.lua: -------------------------------------------------------------------------------- 1 | newoption { 2 | trigger = "with-version", 3 | value = "STRING", 4 | description = "Current UAL version", 5 | default = "8.0.0", 6 | } 7 | 8 | -- x86 9 | workspace "Ultimate-ASI-Loader-Win32" 10 | configurations { "Release", "Debug" } 11 | architecture "x86" 12 | location "build" 13 | cppdialect "C++latest" 14 | exceptionhandling ("SEH") 15 | 16 | defines { "rsc_CompanyName=\"ThirteenAG\"" } 17 | defines { "rsc_LegalCopyright=\"MIT License\""} 18 | defines { "rsc_InternalName=\"%{prj.name}\"", "rsc_ProductName=\"%{prj.name}\"", "rsc_OriginalFilename=\"%{prj.name}.dll\"" } 19 | defines { "rsc_FileDescription=\"Ultimate ASI Loader\"" } 20 | defines { "rsc_UpdateUrl=\"https://github.com/ThirteenAG/Ultimate-ASI-Loader\"" } 21 | 22 | local major = 1 23 | local minor = 0 24 | local build = 0 25 | local revision = 0 26 | if(_OPTIONS["with-version"]) then 27 | local t = {} 28 | for i in _OPTIONS["with-version"]:gmatch("([^.]+)") do 29 | t[#t + 1], _ = i:gsub("%D+", "") 30 | end 31 | while #t < 4 do t[#t + 1] = 0 end 32 | major = math.min(tonumber(t[1]), 255) 33 | minor = math.min(tonumber(t[2]), 255) 34 | build = math.min(tonumber(t[3]), 65535) 35 | revision = math.min(tonumber(t[4]), 65535) 36 | end 37 | defines { "rsc_FileVersion_MAJOR=" .. major } 38 | defines { "rsc_FileVersion_MINOR=" .. minor } 39 | defines { "rsc_FileVersion_BUILD=" .. build } 40 | defines { "rsc_FileVersion_REVISION=" .. revision } 41 | defines { "rsc_FileVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } 42 | defines { "rsc_ProductVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } 43 | 44 | local githash = "" 45 | local f = io.popen("git rev-parse --short HEAD") 46 | if f then 47 | githash = f:read("*a"):gsub("%s+", "") 48 | f:close() 49 | end 50 | 51 | defines { "rsc_GitSHA1=\"" .. githash .. "\"" } 52 | defines { "rsc_GitSHA1W=L\"" .. githash .. "\"" } 53 | 54 | project "Ultimate-ASI-Loader-Win32" 55 | kind "SharedLib" 56 | language "C++" 57 | targetdir "bin/Win32/%{cfg.buildcfg}" 58 | targetname "dinput8" 59 | targetextension ".dll" 60 | linkoptions { "/DELAYLOAD:\"Comctl32.dll\"" } 61 | 62 | includedirs { "source" } 63 | includedirs { "external" } 64 | 65 | includedirs { "external/injector/minhook/include" } 66 | files { "external/injector/minhook/include/*.h", "external/injector/minhook/src/**.h", "external/injector/minhook/src/**.c" } 67 | includedirs { "external/injector/utility" } 68 | files { "external/injector/utility/FunctionHookMinHook.hpp", "external/injector/utility/FunctionHookMinHook.cpp" } 69 | includedirs { "external/miniz" } 70 | files { "external/miniz/miniz.c", "external/miniz/miniz.h" } 71 | 72 | files { "source/dllmain.h", "source/dllmain.cpp" } 73 | files { "source/x86.def" } 74 | files { "source/xlive/xliveless.h", "source/xlive/xliveless.cpp", "source/xlive/xliveless.rc"} 75 | files { "source/resources/Versioninfo.rc", "source/resources/UALx86.rc" } 76 | files { "external/d3d8to9/source/*.hpp", "external/d3d8to9/source/*.cpp" } 77 | files { "external/MemoryModule/*.h", "external/MemoryModule/*.c" } 78 | files { "external/ModuleList/*.hpp" } 79 | 80 | local dxsdk = os.getenv "DXSDK_DIR" 81 | if dxsdk then 82 | includedirs { dxsdk .. "/include" } 83 | libdirs { dxsdk .. "/lib/x86" } 84 | elseif os.isdir("external/minidx9") then 85 | includedirs { "external/minidx9/Include" } 86 | libdirs { "external/minidx9/Lib/x86" } 87 | else 88 | includedirs { "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/include" } 89 | libdirs { "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/lib/x86" } 90 | end 91 | 92 | characterset ("UNICODE") 93 | defines { "_CRT_SECURE_NO_WARNINGS" } 94 | 95 | filter "configurations:Debug" 96 | defines { "DEBUG" } 97 | symbols "On" 98 | 99 | filter "configurations:Release" 100 | defines { "NDEBUG", "D3D8TO9NOLOG" } 101 | optimize "On" 102 | staticruntime "On" 103 | 104 | project "MessageBox" 105 | kind "SharedLib" 106 | language "C++" 107 | targetdir "bin/Win32/%{cfg.buildcfg}/scripts" 108 | targetextension ".asi" 109 | 110 | files { "source/demo_plugins/MessageBox.cpp" } 111 | files { "source/resources/Versioninfo.rc" } 112 | 113 | characterset ("UNICODE") 114 | 115 | filter "configurations:Debug" 116 | defines { "DEBUG" } 117 | symbols "On" 118 | 119 | filter "configurations:Release" 120 | defines { "NDEBUG" } 121 | optimize "On" 122 | staticruntime "On" 123 | 124 | project "ExeUnprotect" 125 | kind "SharedLib" 126 | language "C++" 127 | targetdir "bin/Win32/%{cfg.buildcfg}/scripts" 128 | targetextension ".asi" 129 | 130 | files { "source/demo_plugins/ExeUnprotect.cpp" } 131 | files { "source/resources/Versioninfo.rc" } 132 | 133 | characterset ("UNICODE") 134 | 135 | filter "configurations:Debug" 136 | defines { "DEBUG" } 137 | symbols "On" 138 | 139 | filter "configurations:Release" 140 | defines { "NDEBUG" } 141 | optimize "On" 142 | staticruntime "On" 143 | 144 | project "MonoLoader" 145 | kind "SharedLib" 146 | language "C++" 147 | targetdir "bin/Win32/%{cfg.buildcfg}/scripts" 148 | targetextension ".asi" 149 | 150 | files { "source/demo_plugins/MonoLoader.cpp" } 151 | files { "source/resources/Versioninfo.rc" } 152 | 153 | includedirs { "external/injector/safetyhook/include" } 154 | files { "external/injector/safetyhook/include/**.hpp", "external/injector/safetyhook/src/**.cpp" } 155 | includedirs { "external/injector/zydis" } 156 | files { "external/injector/zydis/**.h", "external/injector/zydis/**.c" } 157 | 158 | characterset ("UNICODE") 159 | 160 | filter "configurations:Debug" 161 | defines { "DEBUG" } 162 | symbols "On" 163 | 164 | filter "configurations:Release" 165 | defines { "NDEBUG" } 166 | optimize "On" 167 | staticruntime "On" 168 | 169 | project "Test_Win32" 170 | kind "SharedLib" 171 | language "C++" 172 | targetdir "bin/Win32/%{cfg.buildcfg}" 173 | targetextension ".asi" 174 | 175 | files { "tests/tests.cpp" } 176 | files { "source/resources/Versioninfo.rc" } 177 | 178 | characterset ("UNICODE") 179 | 180 | filter "configurations:Debug" 181 | defines { "DEBUG" } 182 | symbols "On" 183 | 184 | filter "configurations:Release" 185 | defines { "NDEBUG" } 186 | optimize "On" 187 | staticruntime "On" 188 | 189 | -- x64 190 | workspace "Ultimate-ASI-Loader-x64" 191 | configurations { "Release", "Debug" } 192 | architecture "x86_64" 193 | location "build" 194 | cppdialect "C++latest" 195 | exceptionhandling ("SEH") 196 | 197 | defines { "rsc_CompanyName=\"ThirteenAG\"" } 198 | defines { "rsc_LegalCopyright=\"MIT License\""} 199 | defines { "rsc_InternalName=\"%{prj.name}\"", "rsc_ProductName=\"%{prj.name}\"", "rsc_OriginalFilename=\"%{prj.name}.dll\"" } 200 | defines { "rsc_FileDescription=\"Ultimate ASI Loader\"" } 201 | defines { "rsc_UpdateUrl=\"https://github.com/ThirteenAG/Ultimate-ASI-Loader\"" } 202 | 203 | local major = 1 204 | local minor = 0 205 | local build = 0 206 | local revision = 0 207 | if(_OPTIONS["with-version"]) then 208 | local t = {} 209 | for i in _OPTIONS["with-version"]:gmatch("([^.]+)") do 210 | t[#t + 1], _ = i:gsub("%D+", "") 211 | end 212 | while #t < 4 do t[#t + 1] = 0 end 213 | major = math.min(tonumber(t[1]), 255) 214 | minor = math.min(tonumber(t[2]), 255) 215 | build = math.min(tonumber(t[3]), 65535) 216 | revision = math.min(tonumber(t[4]), 65535) 217 | end 218 | defines { "rsc_FileVersion_MAJOR=" .. major } 219 | defines { "rsc_FileVersion_MINOR=" .. minor } 220 | defines { "rsc_FileVersion_BUILD=" .. build } 221 | defines { "rsc_FileVersion_REVISION=" .. revision } 222 | defines { "rsc_FileVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } 223 | defines { "rsc_ProductVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } 224 | 225 | local githash = "" 226 | local f = io.popen("git rev-parse --short HEAD") 227 | if f then 228 | githash = f:read("*a"):gsub("%s+", "") 229 | f:close() 230 | end 231 | 232 | defines { "rsc_GitSHA1=\"" .. githash .. "\"" } 233 | defines { "rsc_GitSHA1W=L\"" .. githash .. "\"" } 234 | 235 | defines { "X64" } 236 | 237 | project "Ultimate-ASI-Loader-x64" 238 | kind "SharedLib" 239 | language "C++" 240 | targetdir "bin/x64/%{cfg.buildcfg}" 241 | targetname "dinput8" 242 | targetextension ".dll" 243 | linkoptions { "/DELAYLOAD:\"Comctl32.dll\"" } 244 | 245 | includedirs { "source" } 246 | includedirs { "external" } 247 | 248 | includedirs { "external/injector/minhook/include" } 249 | files { "external/injector/minhook/include/*.h", "external/injector/minhook/src/**.h", "external/injector/minhook/src/**.c" } 250 | includedirs { "external/injector/utility" } 251 | files { "external/injector/utility/FunctionHookMinHook.hpp", "external/injector/utility/FunctionHookMinHook.cpp" } 252 | includedirs { "external/miniz" } 253 | files { "external/miniz/miniz.c", "external/miniz/miniz.h" } 254 | 255 | files { "source/dllmain.h", "source/dllmain.cpp" } 256 | files { "source/x64.def" } 257 | files { "source/resources/Versioninfo.rc", "source/resources/UALx64.rc" } 258 | 259 | characterset ("UNICODE") 260 | defines { "_CRT_SECURE_NO_WARNINGS" } 261 | 262 | filter "configurations:Debug" 263 | defines { "DEBUG" } 264 | symbols "On" 265 | 266 | filter "configurations:Release" 267 | defines { "NDEBUG" } 268 | optimize "On" 269 | staticruntime "On" 270 | 271 | project "RE7Demo.InfiniteAmmo" 272 | kind "SharedLib" 273 | language "C++" 274 | targetdir "bin/x64/%{cfg.buildcfg}/scripts" 275 | targetextension ".asi" 276 | 277 | files { "source/demo_plugins/RE7Demo.InfiniteAmmo.cpp" } 278 | files { "source/resources/Versioninfo.rc" } 279 | 280 | characterset ("UNICODE") 281 | 282 | filter "configurations:Debug" 283 | defines { "DEBUG" } 284 | symbols "On" 285 | 286 | filter "configurations:Release" 287 | defines { "NDEBUG" } 288 | optimize "On" 289 | staticruntime "On" 290 | 291 | project "MessageBox_x64" 292 | kind "SharedLib" 293 | language "C++" 294 | targetdir "bin/x64/%{cfg.buildcfg}/scripts" 295 | targetextension ".asi" 296 | 297 | files { "source/demo_plugins/MessageBox.cpp" } 298 | files { "source/resources/Versioninfo.rc" } 299 | 300 | characterset ("UNICODE") 301 | 302 | filter "configurations:Debug" 303 | defines { "DEBUG" } 304 | symbols "On" 305 | 306 | filter "configurations:Release" 307 | defines { "NDEBUG" } 308 | optimize "On" 309 | staticruntime "On" 310 | 311 | project "MonoLoader_x64" 312 | kind "SharedLib" 313 | language "C++" 314 | targetdir "bin/x64/%{cfg.buildcfg}/scripts" 315 | targetextension ".asi" 316 | 317 | files { "source/demo_plugins/MonoLoader.cpp" } 318 | files { "source/resources/Versioninfo.rc" } 319 | 320 | includedirs { "external/injector/safetyhook/include" } 321 | files { "external/injector/safetyhook/include/**.hpp", "external/injector/safetyhook/src/**.cpp" } 322 | includedirs { "external/injector/zydis" } 323 | files { "external/injector/zydis/**.h", "external/injector/zydis/**.c" } 324 | 325 | characterset ("UNICODE") 326 | 327 | filter "configurations:Debug" 328 | defines { "DEBUG" } 329 | symbols "On" 330 | 331 | filter "configurations:Release" 332 | defines { "NDEBUG" } 333 | optimize "On" 334 | staticruntime "On" 335 | 336 | project "Test_x64" 337 | kind "SharedLib" 338 | language "C++" 339 | targetdir "bin/x64/%{cfg.buildcfg}" 340 | targetextension ".asi" 341 | 342 | files { "tests/tests.cpp" } 343 | files { "source/resources/Versioninfo.rc" } 344 | 345 | characterset ("UNICODE") 346 | 347 | filter "configurations:Debug" 348 | defines { "DEBUG" } 349 | symbols "On" 350 | 351 | filter "configurations:Release" 352 | defines { "NDEBUG" } 353 | optimize "On" 354 | staticruntime "On" 355 | 356 | project "VirtualFileServer" 357 | kind "ConsoleApp" 358 | language "C++" 359 | targetdir "bin/x64/%{cfg.buildcfg}" 360 | targetextension ".exe" 361 | 362 | files { "source/demo_plugins/VirtualFileServer.cpp" } 363 | files { "source/resources/Versioninfo.rc", "source/resources/UALx64.rc" } 364 | 365 | characterset ("UNICODE") 366 | 367 | filter "configurations:Debug" 368 | defines { "DEBUG" } 369 | symbols "On" 370 | 371 | filter "configurations:Release" 372 | defines { "NDEBUG" } 373 | optimize "On" 374 | staticruntime "On" -------------------------------------------------------------------------------- /source/demo_plugins/MonoLoader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../../external/ModuleList/ModuleList.hpp" 6 | #include "safetyhook.hpp" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | HMODULE hm = NULL; 18 | HMODULE ual = NULL; 19 | 20 | template 21 | bool iequals(const T& s1, const V& s2) 22 | { 23 | T str1(s1); T str2(s2); 24 | std::transform(str1.begin(), str1.end(), str1.begin(), ::tolower); 25 | std::transform(str2.begin(), str2.end(), str2.begin(), ::tolower); 26 | return (str1 == str2); 27 | } 28 | 29 | class DllCallbackHandler 30 | { 31 | public: 32 | static inline void RegisterCallback(std::function&& fn) 33 | { 34 | RegisterDllNotification(); 35 | GetCallbackList().emplace_back(std::forward>(fn)); 36 | } 37 | private: 38 | static inline void callOnLoad(HMODULE mod) 39 | { 40 | if (!GetCallbackList().empty()) 41 | { 42 | for (auto& f : GetCallbackList()) 43 | { 44 | f(mod); 45 | } 46 | } 47 | } 48 | 49 | private: 50 | static inline std::vector>& GetCallbackList() 51 | { 52 | return onLoad; 53 | } 54 | 55 | typedef NTSTATUS(NTAPI* _LdrRegisterDllNotification) (ULONG, PVOID, PVOID, PVOID); 56 | typedef NTSTATUS(NTAPI* _LdrUnregisterDllNotification) (PVOID); 57 | 58 | typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA 59 | { 60 | ULONG Flags; //Reserved. 61 | PUNICODE_STRING FullDllName; //The full path name of the DLL module. 62 | PUNICODE_STRING BaseDllName; //The base file name of the DLL module. 63 | PVOID DllBase; //A pointer to the base address for the DLL in memory. 64 | ULONG SizeOfImage; //The size of the DLL image, in bytes. 65 | } LDR_DLL_LOADED_NOTIFICATION_DATA, LDR_DLL_UNLOADED_NOTIFICATION_DATA, * PLDR_DLL_LOADED_NOTIFICATION_DATA, * PLDR_DLL_UNLOADED_NOTIFICATION_DATA; 66 | 67 | typedef union _LDR_DLL_NOTIFICATION_DATA 68 | { 69 | LDR_DLL_LOADED_NOTIFICATION_DATA Loaded; 70 | LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded; 71 | } LDR_DLL_NOTIFICATION_DATA, * PLDR_DLL_NOTIFICATION_DATA; 72 | 73 | typedef NTSTATUS(NTAPI* PLDR_MANIFEST_PROBER_ROUTINE) (IN HMODULE DllBase, IN PCWSTR FullDllPath, OUT PHANDLE ActivationContext); 74 | typedef NTSTATUS(NTAPI* PLDR_ACTX_LANGUAGE_ROURINE) (IN HANDLE Unk, IN USHORT LangID, OUT PHANDLE ActivationContext); 75 | typedef void(NTAPI* PLDR_RELEASE_ACT_ROUTINE) (IN HANDLE ActivationContext); 76 | typedef VOID(NTAPI* fnLdrSetDllManifestProber) (IN PLDR_MANIFEST_PROBER_ROUTINE ManifestProberRoutine, 77 | IN PLDR_ACTX_LANGUAGE_ROURINE CreateActCtxLanguageRoutine, IN PLDR_RELEASE_ACT_ROUTINE ReleaseActCtxRoutine); 78 | 79 | private: 80 | static inline void CALLBACK LdrDllNotification(ULONG NotificationReason, PLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context) 81 | { 82 | static constexpr auto LDR_DLL_NOTIFICATION_REASON_LOADED = 1; 83 | static constexpr auto LDR_DLL_NOTIFICATION_REASON_UNLOADED = 2; 84 | if (NotificationReason == LDR_DLL_NOTIFICATION_REASON_LOADED) 85 | { 86 | callOnLoad((HMODULE)NotificationData->Loaded.DllBase); 87 | } 88 | } 89 | 90 | static inline NTSTATUS NTAPI ProbeCallback(IN HMODULE DllBase, IN PCWSTR FullDllPath, OUT PHANDLE ActivationContext) 91 | { 92 | std::wstring str(FullDllPath); 93 | callOnLoad(DllBase); 94 | 95 | HANDLE actx = NULL; 96 | ACTCTXW act = { 0 }; 97 | 98 | act.cbSize = sizeof(act); 99 | act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; 100 | act.lpSource = FullDllPath; 101 | act.hModule = DllBase; 102 | act.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID; 103 | *ActivationContext = 0; 104 | actx = CreateActCtxW(&act); 105 | if (actx == INVALID_HANDLE_VALUE) 106 | return 0xC000008B; //STATUS_RESOURCE_NAME_NOT_FOUND; 107 | *ActivationContext = actx; 108 | return STATUS_SUCCESS; 109 | } 110 | 111 | static inline void RegisterDllNotification() 112 | { 113 | LdrRegisterDllNotification = (_LdrRegisterDllNotification)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "LdrRegisterDllNotification"); 114 | if (LdrRegisterDllNotification) 115 | { 116 | if (!cookie) 117 | LdrRegisterDllNotification(0, LdrDllNotification, 0, &cookie); 118 | } 119 | else 120 | { 121 | LdrSetDllManifestProber = (fnLdrSetDllManifestProber)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "LdrSetDllManifestProber"); 122 | if (LdrSetDllManifestProber) 123 | { 124 | LdrSetDllManifestProber(&ProbeCallback, NULL, &ReleaseActCtx); 125 | } 126 | } 127 | } 128 | 129 | static inline void UnRegisterDllNotification() 130 | { 131 | LdrUnregisterDllNotification = (_LdrUnregisterDllNotification)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "LdrUnregisterDllNotification"); 132 | if (LdrUnregisterDllNotification && cookie) 133 | LdrUnregisterDllNotification(cookie); 134 | } 135 | 136 | private: 137 | static inline _LdrRegisterDllNotification LdrRegisterDllNotification; 138 | static inline _LdrUnregisterDllNotification LdrUnregisterDllNotification; 139 | static inline void* cookie; 140 | static inline fnLdrSetDllManifestProber LdrSetDllManifestProber; 141 | static inline std::vector> onLoad; 142 | }; 143 | 144 | using MonoObject = void; 145 | using MonoMethod = void; 146 | using MonoMethodDesc = void; 147 | using MonoDomain = void; 148 | using MonoAssembly = void; 149 | using MonoImage = void; 150 | using MonoImageOpenStatus = void; 151 | using mono_bool = bool; 152 | 153 | static std::map monoExports = { 154 | { "mono_assembly_load_from_full", nullptr }, 155 | { "mono_get_root_domain", nullptr }, 156 | { "mono_domain_assembly_open", nullptr }, 157 | { "mono_assembly_get_image", nullptr }, 158 | { "mono_runtime_invoke", nullptr }, 159 | { "mono_method_desc_new", nullptr }, 160 | { "mono_method_desc_free", nullptr }, 161 | { "mono_method_desc_search_in_image", nullptr }, 162 | }; 163 | 164 | SafetyHookInline sh_mono_assembly_load_from_full_hook{}; 165 | std::map> pluginsToLoad; 166 | MonoAssembly* mono_assembly_load_from_full_hook(MonoImage* image, const char* fname, MonoImageOpenStatus* status, mono_bool refonly) 167 | { 168 | auto ret = sh_mono_assembly_load_from_full_hook.unsafe_call(image, fname, status, refonly); 169 | 170 | static std::once_flag flag; 171 | std::call_once(flag, []() 172 | { 173 | auto mono_get_root_domain = (MonoDomain*(*)())monoExports["mono_get_root_domain"]; 174 | auto mono_domain_assembly_open = (MonoAssembly*(*)(MonoDomain* domain, const char* name))monoExports["mono_domain_assembly_open"]; 175 | auto mono_assembly_get_image = (MonoImage*(*)(MonoAssembly* assembly))monoExports["mono_assembly_get_image"]; 176 | auto mono_runtime_invoke = (MonoObject*(*)(MonoMethod* method, void* obj, void** params, MonoObject** exc))monoExports["mono_runtime_invoke"]; 177 | auto mono_method_desc_new = (MonoMethodDesc*(*)(const char* name, mono_bool include_namespace))monoExports["mono_method_desc_new"]; 178 | auto mono_method_desc_search_in_image = (MonoMethod*(*)(MonoMethodDesc* desc, MonoImage* image))monoExports["mono_method_desc_search_in_image"]; 179 | auto mono_method_desc_free = (void(*)(MonoMethodDesc* desc))monoExports["mono_method_desc_free"]; 180 | 181 | std::set invokedMethods; 182 | 183 | auto insertDefaults = [&](auto dll) 184 | { 185 | pluginsToLoad[dll].emplace(L"UltimateASILoader:InitializeASI"); 186 | pluginsToLoad[dll].emplace(L"UltimateASILoader.UltimateASILoader:InitializeASI"); 187 | }; 188 | 189 | auto split = [](std::wstring_view string, std::wstring_view delimiter) -> std::vector 190 | { 191 | auto t = [](auto&& rng) { return std::wstring_view(&*rng.begin(), std::ranges::distance(rng)); }; 192 | auto s = string | std::ranges::views::split(delimiter) | std::ranges::views::transform(t); 193 | return { s.begin(), s.end() }; 194 | }; 195 | 196 | auto parseFile = [&](std::filesystem::path file, std::filesystem::path dll = std::filesystem::path()) 197 | { 198 | std::wifstream infile(file); 199 | std::wstring line; 200 | while (std::getline(infile, line)) { 201 | if (line.empty() || line.starts_with(L"#") || line.starts_with(L";")) 202 | continue; 203 | 204 | auto subs = split(line, L"="); 205 | if (subs.size() == 2) 206 | pluginsToLoad[subs.front()].emplace(subs.back()); 207 | else if (line.contains(L":")) 208 | pluginsToLoad[dll].emplace(line); 209 | else 210 | insertDefaults(line); 211 | } 212 | }; 213 | 214 | HMODULE h; 215 | WCHAR buffer[MAX_PATH]; 216 | GetModuleFileNameW(GetModuleHandleW(NULL), buffer, ARRAYSIZE(buffer)); 217 | std::filesystem::path exePath(buffer); 218 | GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCWSTR)&monoExports, &h); 219 | GetModuleFileNameW(h, buffer, ARRAYSIZE(buffer)); 220 | std::filesystem::path modulePath(buffer); 221 | 222 | parseFile(exePath.parent_path() / L"assemblies.txt"); 223 | parseFile(std::filesystem::path(modulePath).replace_extension(".ini")); 224 | parseFile(std::filesystem::path(modulePath).replace_extension(".txt")); 225 | 226 | std::error_code ec; 227 | for (auto& folder : { L"scripts", L"plugins" }) 228 | { 229 | for (const auto& file : std::filesystem::recursive_directory_iterator(folder, std::filesystem::directory_options::skip_permission_denied, ec)) 230 | { 231 | if (!std::filesystem::is_directory(file, ec) && file.is_regular_file(ec) && iequals(file.path().extension().wstring(), L".dll")) 232 | { 233 | auto plugin_path = std::filesystem::absolute(file, ec); 234 | insertDefaults(plugin_path); 235 | parseFile(std::filesystem::path(plugin_path).replace_extension(".ini"), plugin_path); 236 | parseFile(std::filesystem::path(plugin_path).replace_extension(".txt"), plugin_path); 237 | } 238 | } 239 | } 240 | 241 | for (auto& plugin : pluginsToLoad) 242 | { 243 | auto rootDomain = mono_get_root_domain(); 244 | if (rootDomain) 245 | { 246 | auto monoAssembly = mono_domain_assembly_open(rootDomain, plugin.first.string().c_str()); 247 | if (monoAssembly) 248 | { 249 | auto image = mono_assembly_get_image(monoAssembly); 250 | for (auto& method : plugin.second) 251 | { 252 | if (!method.empty()) 253 | { 254 | for (auto inc_ns : { true, false }) 255 | { 256 | auto description = mono_method_desc_new(method.string().c_str(), inc_ns); 257 | if (description) 258 | { 259 | auto method = mono_method_desc_search_in_image(description, image); 260 | mono_method_desc_free(description); 261 | if (method && !invokedMethods.contains(method)) 262 | { 263 | void* exc = nullptr; 264 | mono_runtime_invoke(method, nullptr, nullptr, &exc); 265 | if (!exc) 266 | { 267 | invokedMethods.emplace(method); 268 | break; 269 | } 270 | } 271 | } 272 | } 273 | } 274 | } 275 | } 276 | } 277 | } 278 | }); 279 | 280 | return ret; 281 | } 282 | 283 | void GetMonoDllCB(HMODULE mod) 284 | { 285 | ModuleList dlls; 286 | dlls.Enumerate(ModuleList::SearchLocation::LocalOnly); 287 | for (auto& e : dlls.m_moduleList) 288 | { 289 | auto m = std::get(e); 290 | if (m == mod && m != ual && m != hm && m != GetModuleHandle(NULL)) 291 | { 292 | for (auto& [key, value] : monoExports) 293 | { 294 | auto v = GetProcAddress(m, key.c_str()); 295 | if (v) 296 | value = v; 297 | else 298 | break; 299 | } 300 | } 301 | } 302 | 303 | if (std::all_of(monoExports.begin(), monoExports.end(), [](const auto& it) { return it.second != nullptr; })) 304 | { 305 | sh_mono_assembly_load_from_full_hook = safetyhook::create_inline(monoExports["mono_assembly_load_from_full"], mono_assembly_load_from_full_hook); 306 | } 307 | } 308 | 309 | extern "C" __declspec(dllexport) void InitializeASI() 310 | { 311 | static std::once_flag flag; 312 | std::call_once(flag, []() 313 | { 314 | ModuleList dlls; 315 | dlls.Enumerate(ModuleList::SearchLocation::LocalOnly); 316 | for (auto& e : dlls.m_moduleList) 317 | GetMonoDllCB(std::get(e)); 318 | DllCallbackHandler::RegisterCallback(GetMonoDllCB); 319 | }); 320 | } 321 | 322 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID /*lpReserved*/) 323 | { 324 | if (reason == DLL_PROCESS_ATTACH) 325 | { 326 | hm = hModule; 327 | } 328 | else if (reason == DLL_PROCESS_DETACH) 329 | { 330 | sh_mono_assembly_load_from_full_hook.reset(); 331 | } 332 | return TRUE; 333 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![AppVeyor](https://img.shields.io/appveyor/build/ThirteenAG/Ultimate-ASI-Loader?label=AppVeyor%20Build&logo=Appveyor&logoColor=white)](https://ci.appveyor.com/project/ThirteenAG/ultimate-asi-loader) 2 | [![GitHub Actions Build](https://github.com/ThirteenAG/Ultimate-ASI-Loader/actions/workflows/msbuild.yml/badge.svg)](https://github.com/ThirteenAG/Ultimate-ASI-Loader/actions/workflows/msbuild.yml) 3 | 4 |

5 | 6 |

7 | 8 | # Ultimate ASI Loader 9 | 10 | ## DESCRIPTION 11 | 12 | This is a DLL file that adds ASI plugin loading functionality to any game that uses any of the following libraries: 13 | 14 | | Win32 | Win64 | 15 | | :-----------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------: | 16 | | [d3d8.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d8-Win32.zip) | - | 17 | | [d3d9.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d9-Win32.zip) | [d3d9.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d9-x64.zip) | 18 | | [d3d10.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d10-Win32.zip) | [d3d10.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d10-x64.zip) | 19 | | [d3d11.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d11-Win32.zip) | [d3d11.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d11-x64.zip) | 20 | | [d3d12.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/d3d12-Win32.zip) | [d3d12.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/d3d12-x64.zip) | 21 | | [ddraw.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/ddraw-Win32.zip) | - | 22 | | [dinput.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/dinput-Win32.zip) | - | 23 | | [dinput8.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/dinput8-Win32.zip) | [dinput8.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/dinput8-x64.zip) | 24 | | [dsound.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/dsound-Win32.zip) | [dsound.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/dsound-x64.zip) | 25 | | [msacm32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/msacm32-Win32.zip) | - | 26 | | [msvfw32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/msvfw32-Win32.zip) | - | 27 | | [version.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/version-Win32.zip) | [version.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/version-x64.zip) | 28 | | [wininet.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/wininet-Win32.zip) | [wininet.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/wininet-x64.zip) | 29 | | [winmm.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/winmm-Win32.zip) | [winmm.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/winmm-x64.zip) | 30 | | [winhttp.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/winhttp-Win32.zip) | [winhttp.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/winhttp-x64.zip) | 31 | | [xlive.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xlive-Win32.zip) | - | 32 | | [binkw32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/binkw32-Win32.zip) | - | 33 | | [bink2w32.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/bink2w32-Win32.zip) | - | 34 | | - | [binkw64.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/binkw64-x64.zip) | 35 | | - | [bink2w64.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/bink2w64-x64.zip) | 36 | | [vorbisFile.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/vorbisFile-Win32.zip) | - | 37 | | [xinput1_1.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_1-Win32.zip) | [xinput1_1.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_1-x64.zip) | 38 | | [xinput1_2.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_2-Win32.zip) | [xinput1_2.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_2-x64.zip) | 39 | | [xinput1_3.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_3-Win32.zip) | [xinput1_3.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_3-x64.zip) | 40 | | [xinput1_4.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput1_4-Win32.zip) | [xinput1_4.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput1_4-x64.zip) | 41 | | [xinput9_1_0.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinput9_1_0-Win32.zip) | [xinput9_1_0.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinput9_1_0-x64.zip) | 42 | | [xinputuap.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/Win32-latest/xinputuap-Win32.zip) | [xinputuap.dll](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases/download/x64-latest/xinputuap-x64.zip) | 43 | 44 | It is possible (and sometimes necessary) to load the original DLL by renaming it to `Hooked.dll`, e.g. `d3d12Hooked.dll`. 45 | With **binkw32.dll** and **vorbisFile.dll**, it is optional, and you can simply replace the DLL. Always make a backup before replacing any files. 46 | 47 | 48 | ## INSTALLATION 49 | 50 | To install it, you just need to place the DLL into the game directory. Usually, it works as dinput8.dll, but if that doesn't work, you can rename it (see the list of supported names above). 51 | 52 | ## USAGE 53 | 54 | Put ASI files in the game's root directory or in the `scripts`, `plugins`, or `update` folder. 55 | If configuration is necessary, the global.ini file can be placed in the 'scripts' or 'plugins' folder. It can be used alongside the chosen DLL, and if so, it is also possible to use the DLL name for the ini file (e.g., version.dll/version.ini). 56 | [See an example of global.ini here](https://github.com/ThirteenAG/Ultimate-ASI-Loader/blob/master/data/scripts/global.ini). 57 | 58 | ## UPDATE FOLDER (Overload From Folder) 59 | 60 | It is possible to install mods that replace files via the `update` folder, allowing you to avoid replacing original game files. 61 | 62 | For example, if a mod replaces the file located at: 63 | 64 | ``` 65 | Resident Evil 5\nativePC_MT\Image\Archive\ChapterEnd11.arc 66 | ``` 67 | 68 | With Ultimate ASI Loader installed, you can create an `update` folder and place the file at: 69 | 70 | ``` 71 | Resident Evil 5\update\nativePC_MT\Image\Archive\ChapterEnd11.arc 72 | ``` 73 | 74 | To revert the game to its initial state, simply remove the `update` folder. 75 | 76 | Please note that the `update` folder is relative to the location of the ASI loader, so you need to adjust paths accordingly. For example: 77 | 78 | ``` 79 | \Gameface\Content\Movies\1080\GTA_SA_CREDITS_FINAL_1920x1080.mp4 80 | ``` 81 | 82 | Should be adjusted to: 83 | 84 | ``` 85 | \Gameface\Binaries\Win64\update\Content\Movies\1080\GTA_SA_CREDITS_FINAL_1920x1080.mp4 86 | ``` 87 | 88 | Starting with version 7.9.0, you can use this functionality for total conversions: 89 | 90 | ![re5dx9_update](https://github.com/user-attachments/assets/a4baaa7b-d0bc-44ce-ab5e-d5fa8cc3ae43) 91 | 92 | Two or more folders must be specified, and exist, for the selector dialog to appear. Define them inside global.ini under `[FileLoader]` section using the `OverloadFromFolder` key. Use the `|` symbol as a separator. If only one folder is specified and exists, it will be used to overload files, but the selector will not appear. Without an ini file, the `update` folder is always used if it exists. Example: 93 | 94 | ```ini 95 | [FileLoader] 96 | OverloadFromFolder=update | nightmare 97 | ``` 98 | 99 | To create a custom header, create `update.txt` inside `update` or total conversion folder and insert the custom name there. 100 | 101 | `Resident Evil 5\nightmare\update.txt:` 102 | 103 | ``` 104 | Resident Evil 5 - Nightmare (Story mode mod) 105 | ``` 106 | 107 | To get the current update path, use the ASI Loader's `GetOverloadPathA` or `GetOverloadPathW` exports from the ASI plugin. 108 | 109 | ```cpp 110 | bool (WINAPI* GetOverloadPathW)(wchar_t* out, size_t out_size) = nullptr; 111 | 112 | ModuleList dlls; 113 | dlls.Enumerate(ModuleList::SearchLocation::LocalOnly); 114 | for (auto& e : dlls.m_moduleList) 115 | { 116 | auto m = std::get(e); 117 | if (IsModuleUAL(m)) { 118 | GetOverloadPathW = (decltype(GetOverloadPathW))GetProcAddress(m, "GetOverloadPathW"); 119 | break; 120 | } 121 | } 122 | 123 | std::wstring s; 124 | s.resize(MAX_PATH, L'\0'); 125 | if (!GetOverloadPathW || !GetOverloadPathW(s.data(), s.size())) 126 | s = GetExeModulePath() / L"update"; 127 | 128 | auto updatePath = std::filesystem::path(s.data()); 129 | ``` 130 | 131 | ## ADDITIONAL WINDOWED MODE FEATURE (x86 builds only, legacy feature) 132 | 133 | The 32-bit version of the ASI loader has a built-in wndmode.dll, which can be loaded if you create an empty wndmode.ini in the folder with the ASI loader's DLL. It will be automatically filled with example configuration at the first run of the game. Settings are not universal and should be changed for each specific game, but usually, it works as is. 134 | 135 | ## D3D8TO9 136 | 137 | Some mods, like [SkyGfx](https://github.com/aap/skygfx_vc), require [d3d8to9](https://github.com/crosire/d3d8to9). It is also a part of the ASI loader, so to use it, create [global.ini](https://github.com/ThirteenAG/Ultimate-ASI-Loader/edit/master/readme.md#usage) with the following content: 138 | 139 | ```ini 140 | [GlobalSets] 141 | UseD3D8to9=1 142 | ``` 143 | The ASI Loader must be named `d3d8.dll` in order for this feature to take effect. 144 | 145 | [See an example of global.ini here](https://github.com/ThirteenAG/Ultimate-ASI-Loader/blob/master/data/scripts/global.ini#L8). 146 | 147 | ## CrashDumps 148 | 149 | The ASI loader is now capable of generating crash minidumps and crash logs. To use this feature, create a folder named `CrashDumps` in the folder with the ASI loader's DLL. You can disable it via the `DisableCrashDumps=1` ini option. 150 | 151 | ## Using with UWP games 152 | 153 | 1. Enable Developer Mode (Windows Settings -> Update and Security -> For Developers -> Developer Mode) 154 | ![image](https://user-images.githubusercontent.com/4904157/136562544-6d249514-203e-40c2-808f-34786b043ec5.png) 155 | 2. Install a UWP game, for example, GTA San Andreas. 156 | ![image](https://user-images.githubusercontent.com/4904157/136558440-553ef1f6-cf69-413b-903b-fd4203d6cc1f.png) 157 | 3. Launch a UWP game through the start menu. 158 | 4. Open [UWPInjector.exe](https://github.com/Wunkolo/UWPDumper) from the UWPDumper download. 159 | ![image](https://user-images.githubusercontent.com/4904157/136558563-6e39dd67-778e-4159-bb3b-83c499017223.png) 160 | 5. Enter the Process ID that is displayed from the injector and then hit enter. 161 | 6. Wait until the game is dumped. 162 | ![image](https://user-images.githubusercontent.com/4904157/136558813-8b7c271c-2475-40b9-a432-f9640f328a43.png) 163 | 7. Go to the directory : `C:\Users\[YOUR USERNAME]\AppData\Local\Packages\[YOUR UWP GAME NAME]\TempState\DUMP` 164 | 8. Copy these files into a new folder somewhere else of your choosing. 165 | 9. Uninstall a UWP game by clicking on the start menu, right-clicking on its icon, and uninstall. 166 | ![image](https://user-images.githubusercontent.com/4904157/136559019-bdd6d278-d2ae-4acf-b119-9933baab7d96.png) 167 | 10. Go to your directory with your new dumped files (the ones you copied over) and shift + right-click in the directory and "Open Powershell window here". 168 | 11. In that folder, rename **AppxBlockMap.xml** and **AppxSignature.xml** to anything else (to bypass UWP restrictions). 169 | 12. Run the following command: `Add-AppxPackage -Register AppxManifest.xml` 170 | 13. Place the Ultimate ASI Loader DLL into the game directory. You need to find out which name works for a specific game, in the case of GTA SA I've used **d3d11.dll**, so I put **dinput8.dll** from the x86 archive and renamed it to **d3d11.dll**. 171 | 14. Create a scripts or plugins folder within the root directory and place your plugins in it. 172 | Rough code example of radio for all vehicles plugin [here](https://gist.github.com/ThirteenAG/868a964b46b82ce5cebbd4a0823c69e4). Compiled binary here - [GTASAUWP.RadioForAllVehicles.zip](https://github.com/ThirteenAG/Ultimate-ASI-Loader/files/7311505/GTASAUWP.RadioForAllVehicles.zip) 173 | 15. Click on the start menu and launch the game! 174 | 16. See your mods in action. 175 | ![ApplicationFrameHost_2021-10-08_15-57-14](https://user-images.githubusercontent.com/4904157/136561208-e989119e-1ef4-42c2-8b20-c1f81f4e0931.png) 176 | -------------------------------------------------------------------------------- /source/exception.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Unhandled Exception Tracer 4 | * by LINK/2012 5 | * 6 | * This source code is offered for use in the public domain. You may 7 | * use, modify or distribute it freely. 8 | * 9 | * This code is distributed in the hope that it will be useful but 10 | * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY 11 | * DISCLAIMED. This includes but is not limited to warranties of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #pragma comment(lib, "Dbghelp.lib") 23 | 24 | /* 25 | * Special Note: 26 | * Try not to allocate any memory in this file! 27 | * Allocation after a exception may not be a good idea... 28 | */ 29 | 30 | #define LODWORD(_qw) ((DWORD)(_qw)) 31 | #define HIDWORD(_qw) ((DWORD)(((_qw) >> 32) & 0xffffffff)) 32 | 33 | // General constants 34 | static const int sizeof_word = sizeof(void*); // Size of a CPU word (4 bytes on x86) 35 | static const int max_chars_per_print = MAX_PATH + 256; // Max characters per Print() call 36 | static const int symbol_max = 256; // Max size of a symbol (func symbol, var symbol, etc) 37 | static const int max_static_buffer = 4096; // Max static buffer for logging 38 | 39 | // Stackdump constants 40 | static const int stackdump_max_words = 60; // max number of CPU words that the stackdump should dump 41 | static const int stackdump_words_per_line = 6; // max CPU words in a single line 42 | static const int stackdump_line_count = (stackdump_max_words / stackdump_words_per_line) + 1; 43 | 44 | // Backtrace constants 45 | static const int max_backtrace_ever = 100; 46 | static const int max_backtrace = 20; 47 | 48 | // Maximum log size constants 49 | static const int max_logsize_basic = (MAX_PATH + 200); // module path + other text 50 | static const int max_logsize_regs = 32 + (4 * 4 * 28); // info + (regsPerLine * numLines * charsPerReg) 51 | static const int max_logsize_stackdump = 32 + 80 + (stackdump_line_count * 32) + (10 * stackdump_words_per_line * stackdump_line_count); 52 | static const int max_logsize_backtrace = 32 + max_backtrace_ever * (MAX_PATH + symbol_max + 90); 53 | static const int max_logsize_ever = 32 + max_logsize_basic + max_logsize_regs + max_logsize_stackdump + max_logsize_backtrace; 54 | 55 | // Internal 56 | class ExceptionTracer; 57 | class StackTrace; 58 | static HMODULE GetModuleFromAddress(LPVOID address); 59 | static const char* GetExceptionCodeString(unsigned int code); 60 | static const char* FindModuleName(HMODULE module, char* output, DWORD size); 61 | static int LogException(char* buffer, size_t max, LPEXCEPTION_POINTERS pException, bool bLogRegisters, bool bLogStack, bool bLogBacktrace); 62 | static LPTOP_LEVEL_EXCEPTION_FILTER PrevFilter = nullptr; 63 | static void(*ExceptionCallback)(const char* buffer) = nullptr; 64 | 65 | // Exportable 66 | int InstallExceptionCatcher(void(*OnException)(const char* log)); 67 | 68 | /* 69 | * ExceptionTrace 70 | * This class is responssible for tracing all possible informations about an LPEXCEPTION_POINTER 71 | */ 72 | class ExceptionTracer 73 | { 74 | public: 75 | ExceptionTracer(char* buffer, size_t max, LPEXCEPTION_POINTERS pException); 76 | void PrintUnhandledException(); 77 | void PrintRegisters(); 78 | void PrintStackdump(); 79 | void PrintBacktrace(); 80 | 81 | void EnterScope(); 82 | void LeaveScope(); 83 | void Print(const char* fmt, ...); 84 | void NewLine() { Print("\n%s", spc); } 85 | 86 | protected: 87 | EXCEPTION_POINTERS& exception; 88 | EXCEPTION_RECORD& record; 89 | CONTEXT& context; 90 | HMODULE module; 91 | 92 | char* buffer; // Logging buffer 93 | size_t len; // Logged length 94 | size_t max; // Maximum we can log in that buffer 95 | 96 | char spc[(10 * 4) + 1]; // Scope/spacing buffer, 4 spaces per scope, max 10 scopes 97 | size_t nspc; // Number spaces used up there 98 | }; 99 | 100 | /* 101 | * StackTracer 102 | * Responssible for backtracing an stack from a context 103 | */ 104 | class StackTracer 105 | { 106 | public: 107 | struct Trace 108 | { 109 | // The following values may be null (any) 110 | HMODULE module; // The module the func related to this frame is located 111 | void *pc; // Program counter at func related to this frame (EIP) 112 | void *ret; // Return address for the frame 113 | void *frame; // The frame address (EBP) 114 | void *stack; // The stack pointer at the frame (ESP) 115 | }; 116 | 117 | StackTracer(const CONTEXT& context); 118 | Trace* Walk(); 119 | 120 | private: 121 | Trace trace; 122 | DWORD old_options; 123 | CONTEXT context; 124 | STACKFRAME64 frame; 125 | }; 126 | 127 | /* 128 | * TheUnhandledExceptionFilter 129 | * Logs an unhandled exception 130 | */ 131 | static LONG CALLBACK TheUnhandledExceptionFilter(LPEXCEPTION_POINTERS pException) 132 | { 133 | // Logs exception into buffer and calls the callback 134 | auto Log = [pException](char* buffer, size_t size, bool reg, bool stack, bool trace) 135 | { 136 | if (LogException(buffer, size, (LPEXCEPTION_POINTERS)pException, reg, stack, trace)) 137 | ExceptionCallback(buffer); 138 | }; 139 | 140 | // Try to make a very descriptive exception, for that we need to malloc a huge buffer... 141 | if (auto buffer = (char*)malloc(max_logsize_ever)) 142 | { 143 | Log(buffer, max_logsize_ever, true, true, true); 144 | free(buffer); 145 | } 146 | else 147 | { 148 | // Use a static buffer, no need for any allocation 149 | static const auto size = max_logsize_basic + max_logsize_regs + max_logsize_stackdump; 150 | static char static_buf[size]; 151 | static_assert(size <= max_static_buffer, "Static buffer is too big"); 152 | 153 | Log(buffer = static_buf, sizeof(static_buf), true, true, false); 154 | } 155 | 156 | // Continue exception propagation 157 | return (PrevFilter ? PrevFilter(pException) : EXCEPTION_CONTINUE_SEARCH); // I'm not really sure about this return 158 | } 159 | 160 | /* 161 | * InstallExceptionCatcher 162 | * Installs a exception handler to call the specified callback when it happens with human readalbe information. 163 | */ 164 | int InstallExceptionCatcher(void(*cb)(const char* log)) 165 | { 166 | PrevFilter = SetUnhandledExceptionFilter(TheUnhandledExceptionFilter); 167 | ExceptionCallback = cb; 168 | return 1; 169 | } 170 | 171 | /* 172 | * LogException 173 | * Takes an LPEXCEPTION_POINTERS and transforms in a string that is put in the logging steam 174 | */ 175 | static int LogException(char* buffer, size_t max, LPEXCEPTION_POINTERS pException, bool bLogRegisters, bool bLogStack, bool bLogBacktrace) 176 | { 177 | ExceptionTracer trace(buffer, max, pException); 178 | trace.PrintUnhandledException(); 179 | trace.EnterScope(); 180 | if (bLogRegisters) trace.PrintRegisters(); 181 | if (bLogStack) trace.PrintStackdump(); 182 | if (bLogBacktrace) trace.PrintBacktrace(); 183 | trace.LeaveScope(); 184 | return 1; 185 | } 186 | 187 | /* 188 | * ExceptionTracer 189 | * Contructs a exception trace object, responssible for tracing informations about an exception 190 | */ 191 | ExceptionTracer::ExceptionTracer(char* buffer, size_t max, LPEXCEPTION_POINTERS pException) : 192 | buffer(buffer), exception(*pException), record(*pException->ExceptionRecord), context(*pException->ContextRecord) 193 | { 194 | this->buffer = buffer; 195 | this->buffer[this->len = 0] = 0; 196 | this->spc[this->nspc = 0] = 0; 197 | this->max = max; 198 | 199 | // Acquiere common information that we'll access 200 | this->module = GetModuleFromAddress(record.ExceptionAddress); 201 | } 202 | 203 | /* 204 | * Print 205 | * Prints some formated text into the logging buffer 206 | */ 207 | void ExceptionTracer::Print(const char* fmt, ...) 208 | { 209 | va_list va; 210 | va_start(va, fmt); 211 | if ((this->max - this->len) > max_chars_per_print) 212 | this->len += vsprintf(&this->buffer[len], fmt, va); 213 | va_end(va); 214 | } 215 | 216 | /* 217 | * EnterScope 218 | * Enters a new scope in the logging buffer (scope is related to indentation) 219 | * This also prints a new line 220 | */ 221 | void ExceptionTracer::EnterScope() 222 | { 223 | nspc += 4; 224 | spc[nspc - 4] = ' '; 225 | spc[nspc - 3] = ' '; 226 | spc[nspc - 2] = ' '; 227 | spc[nspc - 1] = ' '; 228 | spc[nspc - 0] = 0; 229 | NewLine(); 230 | } 231 | 232 | /* 233 | * LeaveScope 234 | * Leaves the scope 235 | */ 236 | void ExceptionTracer::LeaveScope() 237 | { 238 | assert(nspc > 0); 239 | nspc -= 4; 240 | spc[nspc] = 0; 241 | NewLine(); 242 | } 243 | 244 | /* 245 | * PrintUnhandledException 246 | * Prints the well known "Unhandled exception at ..." into the logging buffer 247 | */ 248 | void ExceptionTracer::PrintUnhandledException() 249 | { 250 | char module_name[MAX_PATH]; 251 | auto dwExceptionCode = record.ExceptionCode; 252 | uintptr_t address = (uintptr_t)record.ExceptionAddress; 253 | 254 | // Find out our module name for logging 255 | if (!this->module || !GetModuleFileNameA(this->module, module_name, sizeof(module_name))) 256 | strcpy(module_name, "unknown"); 257 | 258 | // Log the exception in a similar format similar to debuggers format 259 | Print("Unhandled exception at 0x%p in %s", address, FindModuleName(module, module_name, sizeof(module_name))); 260 | if (module) Print(" (+0x%x)", address - (uintptr_t)(module)); 261 | Print(": 0x%X: %s", dwExceptionCode, GetExceptionCodeString(dwExceptionCode)); 262 | 263 | // If exception is IN_PAGE_ERROR or ACCESS_VIOLATION, we have additional information such as an address 264 | if (dwExceptionCode == EXCEPTION_IN_PAGE_ERROR || dwExceptionCode == EXCEPTION_ACCESS_VIOLATION) 265 | { 266 | auto rw = (DWORD)record.ExceptionInformation[0]; // read or write? 267 | auto addr = (ULONG_PTR)record.ExceptionInformation[1]; // which address? 268 | 269 | Print(" %s 0x%p", 270 | rw == 0 ? "reading location" : rw == 1 ? "writing location" : rw == 8 ? "DEP at" : "", 271 | addr); 272 | 273 | // IN_PAGE_ERROR have another information... 274 | if (dwExceptionCode == EXCEPTION_IN_PAGE_ERROR) 275 | { 276 | NewLine(); 277 | Print("Underlying NTSTATUS code that resulted in the exception is 0x%p", 278 | record.ExceptionInformation[2]); 279 | } 280 | } 281 | 282 | Print("."); 283 | } 284 | 285 | /* 286 | * PrintRegisters 287 | * Prints the content of the assembly registers into the logging buffer 288 | */ 289 | void ExceptionTracer::PrintRegisters() 290 | { 291 | int regs_in_line = 0; // Amount of registers currently printed on this line 292 | 293 | // Prints a register, followed by spaces 294 | auto PrintRegister = [this, ®s_in_line](const char* reg_name, size_t reg_value, const char* spaces) 295 | { 296 | Print("%s: 0x%p%s", reg_name, reg_value, spaces); 297 | if (++regs_in_line >= 4) { this->NewLine(); regs_in_line = 0; } 298 | }; 299 | 300 | auto PrintFloatRegister = [this, ®s_in_line](const char* reg_name, int reg_num, uint32_t reg_value1, uint32_t reg_value2, uint32_t reg_value3, uint32_t reg_value4) 301 | { 302 | Print("%s%02d: 0x%08X 0x%08X 0x%08X 0x%08X [ %f %f %f %f ]", reg_name, reg_num, reg_value1, reg_value2, reg_value3, reg_value4, 303 | *(float*)®_value1, *(float*)®_value2, *(float*)®_value3, *(float*)®_value4); 304 | if (++regs_in_line >= 1) { this->NewLine(); regs_in_line = 0; } 305 | }; 306 | 307 | // Prints a general purposes register 308 | auto PrintIntRegister = [PrintRegister](const char* reg_name, size_t reg_value) 309 | { 310 | PrintRegister(reg_name, reg_value, " "); 311 | }; 312 | 313 | // Prints a segment register 314 | auto PrintSegRegister = [PrintRegister](const char* reg_name, size_t reg_value) 315 | { 316 | PrintRegister(reg_name, reg_value, " "); 317 | }; 318 | 319 | Print("Register dump:"); 320 | EnterScope(); 321 | { 322 | // Print main general purposes registers 323 | if (context.ContextFlags & CONTEXT_INTEGER) 324 | { 325 | #if !_M_X64 326 | PrintIntRegister("EAX", context.Eax); 327 | PrintIntRegister("EBX", context.Ebx); 328 | PrintIntRegister("ECX", context.Ecx); 329 | PrintIntRegister("EDX", context.Edx); 330 | PrintIntRegister("EDI", context.Edi); 331 | PrintIntRegister("ESI", context.Esi); 332 | #else 333 | PrintIntRegister("RAX", context.Rax); 334 | PrintIntRegister("RCX", context.Rcx); 335 | PrintIntRegister("RDX", context.Rdx); 336 | PrintIntRegister("RBX", context.Rbx); 337 | PrintIntRegister("RBP", context.Rbp); 338 | PrintIntRegister("RSI", context.Rsi); 339 | PrintIntRegister("RDI", context.Rdi); 340 | PrintIntRegister("R08", context.R8); 341 | PrintIntRegister("R09", context.R9); 342 | PrintIntRegister("R10", context.R10); 343 | PrintIntRegister("R11", context.R11); 344 | PrintIntRegister("R12", context.R12); 345 | PrintIntRegister("R13", context.R13); 346 | PrintIntRegister("R14", context.R14); 347 | PrintIntRegister("R15", context.R15); 348 | #endif 349 | } 350 | 351 | // Print control registers 352 | if (context.ContextFlags & CONTEXT_CONTROL) 353 | { 354 | #if !_M_X64 355 | PrintIntRegister("EBP", context.Ebp); 356 | PrintIntRegister("EIP", context.Eip); 357 | PrintIntRegister("ESP", context.Esp); 358 | PrintIntRegister("EFL", context.EFlags); 359 | this->NewLine(); this->NewLine(); regs_in_line = 0; 360 | PrintSegRegister("CS", context.SegCs); 361 | PrintSegRegister("SS", context.SegSs); 362 | #else 363 | PrintIntRegister("RIP", context.Rip); 364 | PrintIntRegister("RSP", context.Rsp); 365 | PrintIntRegister("EFL", context.EFlags); 366 | this->NewLine(); this->NewLine(); regs_in_line = 0; 367 | PrintSegRegister("CS", context.SegCs); 368 | PrintSegRegister("SS", context.SegSs); 369 | #endif 370 | } 371 | 372 | this->NewLine(); regs_in_line = 0; 373 | 374 | // Print segment registers 375 | if (context.ContextFlags & CONTEXT_SEGMENTS) 376 | { 377 | PrintSegRegister("GS", context.SegGs); 378 | PrintSegRegister("FS", context.SegFs); 379 | this->NewLine(); regs_in_line = 0; 380 | PrintSegRegister("ES", context.SegEs); 381 | PrintSegRegister("DS", context.SegDs); 382 | } 383 | 384 | this->NewLine(); this->NewLine(); regs_in_line = 0; 385 | 386 | // Print floating point registers 387 | if (context.ContextFlags & CONTEXT_FLOATING_POINT) 388 | { 389 | for (int i = 0; i < 8; i++) 390 | { 391 | #if !_M_X64 392 | auto f = *(M128A*)&(context.FloatSave.RegisterArea[i * 10]); 393 | PrintFloatRegister("ST", i, LODWORD(f.Low), HIDWORD(f.Low), LODWORD(f.High), HIDWORD(f.High)); 394 | #else 395 | PrintFloatRegister("ST", i, 396 | LODWORD(context.FltSave.FloatRegisters[i].Low), HIDWORD(context.FltSave.FloatRegisters[i].Low), 397 | LODWORD(context.FltSave.FloatRegisters[i].High), HIDWORD(context.FltSave.FloatRegisters[i].High)); 398 | #endif 399 | } 400 | 401 | this->NewLine(); 402 | 403 | for (int i = 0; i < 16; i++) 404 | { 405 | #if !_M_X64 406 | auto f = *(M128A*)&(context.ExtendedRegisters[(i + 10) * 16]); 407 | PrintFloatRegister("XMM", i, LODWORD(f.Low), HIDWORD(f.Low), LODWORD(f.High), HIDWORD(f.High)); 408 | 409 | if (i >= 7) 410 | break; 411 | #else 412 | PrintFloatRegister("XMM", i, 413 | LODWORD(context.FltSave.XmmRegisters[i].Low), HIDWORD(context.FltSave.XmmRegisters[i].Low), 414 | LODWORD(context.FltSave.XmmRegisters[i].High), HIDWORD(context.FltSave.XmmRegisters[i].High)); 415 | #endif 416 | } 417 | } 418 | } 419 | LeaveScope(); 420 | } 421 | 422 | /* 423 | * PrintStackdump 424 | * Prints the content of the stack into the logging buffer 425 | */ 426 | void ExceptionTracer::PrintStackdump() 427 | { 428 | // We need the ESP of the exception context to execute a stack dump, make sure we have access to it 429 | if ((context.ContextFlags & CONTEXT_CONTROL) == 0) 430 | return; 431 | 432 | static const auto align = sizeof_word; // Stack aligment 433 | static const auto max_words_in_line_magic = stackdump_words_per_line + 10; 434 | 435 | MEMORY_BASIC_INFORMATION mbi; 436 | #if !_M_X64 437 | uintptr_t base, bottom, top = (uintptr_t)context.Esp; 438 | #else 439 | uintptr_t base, bottom, top = (uintptr_t)context.Rsp; 440 | #endif 441 | auto words_in_line = max_words_in_line_magic; 442 | 443 | // Finds the bottom of the stack from it's base pointer 444 | // Note: mbi will get overriden on this function 445 | auto GetStackBottom = [&mbi](uintptr_t base) 446 | { 447 | VirtualQuery((void*)base, &mbi, sizeof(mbi)); // Find uncommited region of the stack 448 | VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi)); // Find guard page 449 | VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi)); // Find commited region of the stack 450 | auto last = (uintptr_t)mbi.BaseAddress; 451 | return (base + (last - base) + mbi.RegionSize); // base + distanceToLastRegion + lastRegionSize 452 | }; 453 | 454 | // Prints an CPU word at the specified stack address 455 | auto PrintWord = [this, &words_in_line](uintptr_t addr) 456 | { 457 | if (words_in_line++ >= stackdump_words_per_line) 458 | { 459 | // Print new line only if it's not the first time we enter here (i.e. words_in_line has magical value) 460 | if (words_in_line != max_words_in_line_magic + 1) NewLine(); 461 | words_in_line = 1; 462 | Print("0x%p: ", addr); 463 | } 464 | Print(" %p", *(size_t*)addr); 465 | }; 466 | 467 | Print("Stack dump:"); 468 | EnterScope(); 469 | { 470 | // Makes sure the pointer at top (ESP) is valid and readable memory 471 | if (VirtualQuery((void*)(top), &mbi, sizeof(mbi)) 472 | && (mbi.State & MEM_COMMIT) 473 | && (mbi.Protect & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READWRITE | PAGE_READONLY)) != 0) 474 | { 475 | base = (uintptr_t)mbi.AllocationBase; // Base of the stack (uncommited) 476 | bottom = GetStackBottom(base); // Bottom of the stack (commited) 477 | 478 | // Align the stack top (esp) in a 4 bytes boundary 479 | auto remainder = top % align; 480 | uintptr_t current = remainder ? top + (align - remainder) : top; 481 | 482 | // on x86 stack grows downward! (i.e. from bottom to base) 483 | for (int n = 0; n < stackdump_max_words && current < bottom; ++n, current += align) 484 | PrintWord(current); 485 | 486 | NewLine(); 487 | Print("base: 0x%p top: 0x%p bottom: 0x%p", base, top, bottom); 488 | NewLine(); 489 | } 490 | } 491 | LeaveScope(); 492 | } 493 | 494 | /* 495 | * PrintBacktrace 496 | * Prints a call backtrace into the logging buffer 497 | */ 498 | void ExceptionTracer::PrintBacktrace() 499 | { 500 | StackTracer tracer(this->context); 501 | 502 | char module_name[MAX_PATH]; 503 | char sym_buffer[sizeof(SYMBOL_INFO) + symbol_max]; 504 | 505 | int backtrace_count = 0; // Num of frames traced 506 | bool has_symbol_api = false; // True if we have the symbol API available for use 507 | DWORD old_options; // Saves old symbol API options 508 | 509 | SYMBOL_INFO& symbol = *(SYMBOL_INFO*)sym_buffer; 510 | symbol.SizeOfStruct = sizeof(SYMBOL_INFO); 511 | symbol.MaxNameLen = symbol_max; 512 | 513 | // Tries to get the symbol api 514 | if (SymInitialize(GetCurrentProcess(), 0, TRUE)) 515 | { 516 | has_symbol_api = true; 517 | old_options = SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_NO_PROMPTS | SYMOPT_FAIL_CRITICAL_ERRORS); 518 | } 519 | 520 | Print("Backtrace (may be wrong):"); 521 | EnterScope(); 522 | { 523 | // Walks on the stack until there's no frame to trace or we traced 'max_backtrace' frames 524 | while (auto trace = tracer.Walk()) 525 | { 526 | if (++backtrace_count >= max_backtrace) 527 | break; 528 | 529 | bool has_sym = false; // This EIP has a symbol associated with it? 530 | DWORD64 displacement; // EIP displacement relative to symbol 531 | 532 | // If we have access to the symbol api, try to get symbol name from pc (eip) 533 | if (has_symbol_api) 534 | has_sym = trace->pc ? !!SymFromAddr(GetCurrentProcess(), (DWORD64)trace->pc, &displacement, &symbol) : false; 535 | 536 | // Print everything up, this.... Ew, this looks awful! 537 | Print(backtrace_count == 1 ? "=>" : " "); // First line should have '=>' to specify where it crashed 538 | Print("0x%p ", trace->pc); // Print EIP at frame 539 | if (has_sym) Print("%s+0x%x ", symbol.Name, (DWORD)displacement); // Print frame func symbol 540 | Print("in %s (+0x%x) ", // Print module 541 | trace->module ? FindModuleName(trace->module, module_name, sizeof(module_name)) : "unknown", 542 | (uintptr_t)(trace->pc) - (uintptr_t)(trace->module) // Module displacement 543 | ); 544 | if (trace->frame) Print("(0x%p) ", trace->frame); // Print frame pointer 545 | 546 | NewLine(); 547 | } 548 | } 549 | LeaveScope(); 550 | 551 | // Cleanup the symbol api 552 | if (has_symbol_api) 553 | { 554 | SymSetOptions(old_options); 555 | SymCleanup(GetCurrentProcess()); 556 | } 557 | } 558 | 559 | /* 560 | * GetExceptionCodeString 561 | * Returns an description by an exception code 562 | */ 563 | static const char* GetExceptionCodeString(unsigned int code) 564 | { 565 | switch (code) 566 | { 567 | case EXCEPTION_ACCESS_VIOLATION: return "Access violation"; 568 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "Array bounds exceeded"; 569 | case EXCEPTION_BREAKPOINT: return "Breakpoint exception"; 570 | case EXCEPTION_DATATYPE_MISALIGNMENT: return "Data type misalignment exception"; 571 | case EXCEPTION_FLT_DENORMAL_OPERAND: return "Denormal float operand"; 572 | case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "Floating-point division by zero"; 573 | case EXCEPTION_FLT_INEXACT_RESULT: return "Floating-point inexact result"; 574 | case EXCEPTION_FLT_INVALID_OPERATION: return "Floating-point invalid operation"; 575 | case EXCEPTION_FLT_OVERFLOW: return "Floating-point overflow"; 576 | case EXCEPTION_FLT_STACK_CHECK: return "Floating-point stack check"; 577 | case EXCEPTION_FLT_UNDERFLOW: return "Floating-point underflow"; 578 | case EXCEPTION_ILLEGAL_INSTRUCTION: return "Illegal instruction."; 579 | case EXCEPTION_IN_PAGE_ERROR: return "In page error"; 580 | case EXCEPTION_INT_DIVIDE_BY_ZERO: return "Integer division by zero"; 581 | case EXCEPTION_INT_OVERFLOW: return "Integer overflow"; 582 | case EXCEPTION_INVALID_DISPOSITION: return "Invalid disposition"; 583 | case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "Non-continuable exception"; 584 | case EXCEPTION_PRIV_INSTRUCTION: return "Privileged instruction"; 585 | case EXCEPTION_SINGLE_STEP: return "Single step exception"; 586 | case EXCEPTION_STACK_OVERFLOW: return "Stack overflow"; 587 | default: return "NO_DESCRIPTION"; 588 | } 589 | } 590 | 591 | /* 592 | * FindModuleName 593 | * Finds module filename or "unknown" 594 | */ 595 | static const char* FindModuleName(HMODULE module, char* output, DWORD maxsize) 596 | { 597 | if (GetModuleFileNameA(module, output, maxsize)) 598 | { 599 | // Finds the filename part in the output string 600 | char* filename = strrchr(output, '\\'); 601 | if (!filename) filename = strrchr(output, '/'); 602 | 603 | // If filename found (i.e. output isn't already a filename but full path), make output be filename 604 | if (filename) 605 | { 606 | size_t size = strlen(++filename); 607 | memmove(output, filename, size); 608 | output[size] = 0; 609 | } 610 | } 611 | else 612 | { 613 | // Unknown module 614 | strcpy(output, "unknown"); 615 | } 616 | return output; 617 | } 618 | 619 | /* 620 | * GetModuleFromAddress 621 | * Finds module handle from some address inside it 622 | */ 623 | static HMODULE GetModuleFromAddress(LPVOID address) 624 | { 625 | HMODULE module; 626 | if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 627 | (char*)address, &module)) 628 | return module; 629 | return nullptr; 630 | } 631 | 632 | /* 633 | * StackTracer 634 | * Constructs the tracer, we basically need to initialize the symbol api 635 | */ 636 | StackTracer::StackTracer(const CONTEXT& context) 637 | { 638 | // Initialise basic values 639 | memset(&this->frame, 0, sizeof(frame)); 640 | memcpy(&this->context, &context, sizeof(context)); 641 | 642 | // Setup the initial frame context 643 | #if !_M_X64 644 | frame.AddrPC.Mode = AddrModeFlat; 645 | frame.AddrPC.Offset = context.Eip; 646 | frame.AddrFrame.Mode = AddrModeFlat; 647 | frame.AddrFrame.Offset = context.Ebp; 648 | frame.AddrStack.Mode = AddrModeFlat; 649 | frame.AddrStack.Offset = context.Esp; 650 | #else 651 | frame.AddrPC.Mode = AddrModeFlat; 652 | frame.AddrPC.Offset = context.Rip; 653 | frame.AddrFrame.Mode = AddrModeFlat; 654 | frame.AddrFrame.Offset = context.Rbp; 655 | frame.AddrStack.Mode = AddrModeFlat; 656 | frame.AddrStack.Offset = context.Rsp; 657 | #endif 658 | } 659 | 660 | /* 661 | * StackTracer::Walk 662 | * Walks on the stack, each walk is one frame of backtrace 663 | * Returns a frame or null if the walk on the park is not possible anymore 664 | */ 665 | StackTracer::Trace* StackTracer::Walk() 666 | { 667 | if (StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), 668 | &frame, &context, NULL, NULL, NULL, NULL)) 669 | { 670 | trace.module = GetModuleFromAddress((void*)frame.AddrPC.Offset); 671 | trace.frame = (void*)frame.AddrFrame.Offset; 672 | trace.stack = (void*)frame.AddrStack.Offset; 673 | trace.pc = (void*)frame.AddrPC.Offset; 674 | trace.ret = (void*)frame.AddrReturn.Offset; 675 | return &trace; 676 | } 677 | return nullptr; 678 | } 679 | -------------------------------------------------------------------------------- /source/xlive/xliveless.h: -------------------------------------------------------------------------------- 1 | #ifndef XLIVELESS_H 2 | #define XLIVELESS_H 3 | 4 | #define XNET_STARTUP_BYPASS_SECURITY 0x01 5 | #define XNET_STARTUP_ALLOCATE_MAX_DGRAM_SOCKETS 0x02 6 | #define XNET_STARTUP_ALLOCATE_MAX_STREAM_SOCKETS 0x04 7 | #define XNET_STARTUP_DISABLE_PEER_ENCRYPTION 0x08 8 | 9 | typedef struct 10 | { 11 | BYTE cfgSizeOfStruct; 12 | BYTE cfgFlags; 13 | BYTE cfgSockMaxDgramSockets; 14 | BYTE cfgSockMaxStreamSockets; 15 | BYTE cfgSockDefaultRecvBufsizeInK; 16 | BYTE cfgSockDefaultSendBufsizeInK; 17 | BYTE cfgKeyRegMax; 18 | BYTE cfgSecRegMax; 19 | BYTE cfgQosDataLimitDiv4; 20 | BYTE cfgQosProbeTimeoutInSeconds; 21 | BYTE cfgQosProbeRetries; 22 | BYTE cfgQosSrvMaxSimultaneousResponses; 23 | BYTE cfgQosPairWaitTimeInSeconds; 24 | } XNetStartupParams; 25 | 26 | typedef struct 27 | { 28 | IN_ADDR ina; // IP address (zero if not static/DHCP) 29 | IN_ADDR inaOnline; // Online IP address (zero if not online) 30 | WORD wPortOnline; // Online port 31 | BYTE abEnet[6]; // Ethernet MAC address 32 | BYTE abOnline[20]; // Online identification 33 | } XNADDR; 34 | 35 | typedef struct 36 | { 37 | BYTE ab[8]; // xbox to xbox key identifier 38 | } XNKID; 39 | 40 | typedef XNADDR TSADDR; 41 | #define XNET_XNKID_MASK 0xF0 // Mask of flag bits in first byte of XNKID 42 | #define XNET_XNKID_SYSTEM_LINK 0x00 // Peer to peer system link session 43 | #define XNET_XNKID_SYSTEM_LINK_XPLAT 0x40 // Peer to peer system link session for cross-platform 44 | #define XNET_XNKID_ONLINE_PEER 0x80 // Peer to peer online session 45 | #define XNET_XNKID_ONLINE_SERVER 0xC0 // Client to server online session 46 | #define XNET_XNKID_ONLINE_TITLESERVER 0xE0 // Client to title server online session 47 | #define XNetXnKidIsSystemLinkXbox(pxnkid) (((pxnkid)->ab[0] & 0xE0) == XNET_XNKID_SYSTEM_LINK) 48 | #define XNetXnKidIsSystemLinkXPlat(pxnkid) (((pxnkid)->ab[0] & 0xE0) == XNET_XNKID_SYSTEM_LINK_XPLAT) 49 | #define XNetXnKidIsSystemLink(pxnkid) (XNetXnKidIsSystemLinkXbox(pxnkid) || XNetXnKidIsSystemLinkXPlat(pxnkid)) 50 | #define XNetXnKidIsOnlinePeer(pxnkid) (((pxnkid)->ab[0] & 0xE0) == XNET_XNKID_ONLINE_PEER) 51 | #define XNetXnKidIsOnlineServer(pxnkid) (((pxnkid)->ab[0] & 0xE0) == XNET_XNKID_ONLINE_SERVER) 52 | #define XNetXnKidIsOnlineTitleServer(pxnkid) (((pxnkid)->ab[0] & 0xE0) == XNET_XNKID_ONLINE_TITLESERVER) 53 | 54 | typedef struct 55 | { 56 | BYTE ab[16]; // xbox to xbox key exchange key 57 | } XNKEY; 58 | 59 | typedef struct 60 | { 61 | INT iStatus; // WSAEINPROGRESS if pending; 0 if success; error if failed 62 | UINT cina; // Count of IP addresses for the given host 63 | IN_ADDR aina[8]; // Vector of IP addresses for the given host 64 | } XNDNS; 65 | 66 | #define XNET_XNQOSINFO_COMPLETE 0x01 // Qos has finished processing this entry 67 | #define XNET_XNQOSINFO_TARGET_CONTACTED 0x02 // Target host was successfully contacted 68 | #define XNET_XNQOSINFO_TARGET_DISABLED 0x04 // Target host has disabled its Qos listener 69 | #define XNET_XNQOSINFO_DATA_RECEIVED 0x08 // Target host supplied Qos data 70 | #define XNET_XNQOSINFO_PARTIAL_COMPLETE 0x10 // Qos has unfinished estimates for this entry 71 | 72 | typedef struct 73 | { 74 | BYTE bFlags; // See XNET_XNQOSINFO_* 75 | BYTE bReserved; // Reserved 76 | WORD cProbesXmit; // Count of Qos probes transmitted 77 | WORD cProbesRecv; // Count of Qos probes successfully received 78 | WORD cbData; // Size of Qos data supplied by target (may be zero) 79 | BYTE *pbData; // Qos data supplied by target (may be NULL) 80 | WORD wRttMinInMsecs; // Minimum round-trip time in milliseconds 81 | WORD wRttMedInMsecs; // Median round-trip time in milliseconds 82 | DWORD dwUpBitsPerSec; // Upstream bandwidth in bits per second 83 | DWORD dwDnBitsPerSec; // Downstream bandwidth in bits per second 84 | } XNQOSINFO; 85 | 86 | typedef struct 87 | { 88 | UINT cxnqos; // Count of items in axnqosinfo[] array 89 | UINT cxnqosPending; // Count of items still pending 90 | XNQOSINFO axnqosinfo[1]; // Vector of Qos results 91 | } XNQOS; 92 | 93 | typedef struct 94 | { 95 | DWORD dwSizeOfStruct; // Structure size, must be set prior to calling XNetQosGetListenStats 96 | DWORD dwNumDataRequestsReceived; // Number of client data request probes received 97 | DWORD dwNumProbesReceived; // Number of client probe requests received 98 | DWORD dwNumSlotsFullDiscards; // Number of client requests discarded because all slots are full 99 | DWORD dwNumDataRepliesSent; // Number of data replies sent 100 | DWORD dwNumDataReplyBytesSent; // Number of data reply bytes sent 101 | DWORD dwNumProbeRepliesSent; // Number of probe replies sent 102 | } XNQOSLISTENSTATS; 103 | 104 | INT WINAPI XNetStartup(const XNetStartupParams *pxnsp); 105 | //INT WINAPI XNetCleanup(); 106 | INT WINAPI XNetRandom(BYTE *pb, UINT cb); 107 | INT WINAPI XNetCreateKey(XNKID *pxnkid, XNKEY *pxnkey); 108 | INT WINAPI XNetRegisterKey(const XNKID *pxnkid, const XNKEY *pxnkey); 109 | INT WINAPI XNetUnregisterKey(const XNKID *pxnkid); 110 | INT WINAPI XNetReplaceKey(const XNKID *pxnkidUnregister, const XNKID *pxnkidReplace); 111 | INT WINAPI XNetXnAddrToInAddr(const XNADDR *pxna, const XNKID *pxnkid, IN_ADDR *pina); 112 | INT WINAPI XNetServerToInAddr(const IN_ADDR ina, DWORD dwServiceId, IN_ADDR *pina); 113 | INT WINAPI XNetTsAddrToInAddr(const TSADDR *ptsa, DWORD dwServiceId, const XNKID *pxnkid, IN_ADDR *pina); 114 | INT WINAPI XNetInAddrToXnAddr(const IN_ADDR ina, XNADDR *pxna, XNKID *pxnkid); 115 | INT WINAPI XNetInAddrToServer(const IN_ADDR ina, IN_ADDR *pina); 116 | INT WINAPI XNetInAddrToString(const IN_ADDR ina, char *pchBuf, INT cchBuf); 117 | INT WINAPI XNetUnregisterInAddr(const IN_ADDR ina); 118 | INT WINAPI XNetXnAddrToMachineId(const XNADDR *pxnaddr, ULONGLONG *pqwMachineId); 119 | #define XNET_XNADDR_PLATFORM_XBOX1 0x00000000 // Platform type is original Xbox 120 | #define XNET_XNADDR_PLATFORM_XBOX360 0x00000001 // Platform type is Xbox 360 121 | #define XNET_XNADDR_PLATFORM_WINPC 0x00000002 // Platform type is Windows PC 122 | INT WINAPI XNetGetXnAddrPlatform(const XNADDR *pxnaddr, DWORD *pdwPlatform); 123 | #define XNET_CONNECT_STATUS_IDLE 0x00000000 // Connection not started; use XNetConnect or send packet 124 | #define XNET_CONNECT_STATUS_PENDING 0x00000001 // Connecting in progress; not complete yet 125 | #define XNET_CONNECT_STATUS_CONNECTED 0x00000002 // Connection is established 126 | #define XNET_CONNECT_STATUS_LOST 0x00000003 // Connection was lost 127 | INT WINAPI XNetConnect(const IN_ADDR ina); 128 | DWORD WINAPI XNetGetConnectStatus(const IN_ADDR ina); 129 | INT WINAPI XNetDnsLookup(const char *pszHost, WSAEVENT hEvent, XNDNS **ppxndns); 130 | INT WINAPI XNetDnsRelease(XNDNS *pxndns); 131 | #define XNET_QOS_LISTEN_ENABLE 0x00000001 // Responds to queries on the given XNKID 132 | #define XNET_QOS_LISTEN_DISABLE 0x00000002 // Rejects queries on the given XNKID 133 | #define XNET_QOS_LISTEN_SET_DATA 0x00000004 // Sets the block of data to send back to queriers 134 | #define XNET_QOS_LISTEN_SET_BITSPERSEC 0x00000008 // Sets max bandwidth that query reponses may consume 135 | #define XNET_QOS_LISTEN_RELEASE 0x00000010 // Stops listening on given XNKID and releases memory 136 | #define XNET_QOS_LOOKUP_RESERVED 0x00000000 // No flags defined yet for XNetQosLookup 137 | #define XNET_QOS_SERVICE_LOOKUP_RESERVED 0x00000000 // No flags defined yet for XNetQosServiceLookup 138 | INT WINAPI XNetQosListen(const XNKID *pxnkid, 139 | const BYTE *pb, 140 | UINT cb, 141 | DWORD dwBitsPerSec, DWORD dwFlags); 142 | INT WINAPI XNetQosLookup(UINT cxna, 143 | const XNADDR *apxna[], 144 | const XNKID *apxnkid[], 145 | const XNKEY *apxnkey[], 146 | UINT cina, 147 | const IN_ADDR aina[], 148 | const DWORD adwServiceId[], 149 | UINT cProbes, DWORD dwBitsPerSec, DWORD dwFlags, WSAEVENT hEvent, XNQOS **ppxnqos); 150 | INT WINAPI XNetQosServiceLookup(DWORD dwFlags, WSAEVENT hEvent, XNQOS **ppxnqos); 151 | INT WINAPI XNetQosRelease(XNQOS *pxnqos); 152 | INT WINAPI XNetQosGetListenStats(const XNKID *pxnkid, XNQOSLISTENSTATS *pQosListenStats); 153 | #define XNET_GET_XNADDR_PENDING 0x00000000 // Address acquisition is not yet complete 154 | #define XNET_GET_XNADDR_NONE 0x00000001 // XNet is uninitialized or no debugger found 155 | #define XNET_GET_XNADDR_ETHERNET 0x00000002 // Host has ethernet address (no IP address) 156 | #define XNET_GET_XNADDR_STATIC 0x00000004 // Host has statically assigned IP address 157 | #define XNET_GET_XNADDR_DHCP 0x00000008 // Host has DHCP assigned IP address 158 | #define XNET_GET_XNADDR_PPPOE 0x00000010 // Host has PPPoE assigned IP address 159 | #define XNET_GET_XNADDR_GATEWAY 0x00000020 // Host has one or more gateways configured 160 | #define XNET_GET_XNADDR_DNS 0x00000040 // Host has one or more DNS servers configured 161 | #define XNET_GET_XNADDR_ONLINE 0x00000080 // Host is currently connected to online service 162 | #define XNET_GET_XNADDR_TROUBLESHOOT 0x00008000 // Network configuration requires troubleshooting 163 | DWORD WINAPI XNetGetTitleXnAddr(XNADDR *pxna); 164 | DWORD WINAPI XNetGetDebugXnAddr(XNADDR *pxna); 165 | #define XNET_ETHERNET_LINK_ACTIVE 0x00000001 // Ethernet cable is connected and active 166 | #define XNET_ETHERNET_LINK_100MBPS 0x00000002 // Ethernet link is set to 100 Mbps 167 | #define XNET_ETHERNET_LINK_10MBPS 0x00000004 // Ethernet link is set to 10 Mbps 168 | #define XNET_ETHERNET_LINK_FULL_DUPLEX 0x00000008 // Ethernet link is in full duplex mode 169 | #define XNET_ETHERNET_LINK_HALF_DUPLEX 0x00000010 // Ethernet link is in half duplex mode 170 | #define XNET_ETHERNET_LINK_WIRELESS 0x00000020 // Ethernet link is wireless (802.11 based) 171 | //DWORD WINAPI XNetGetEthernetLinkStatus(); 172 | #define XNET_BROADCAST_VERSION_OLDER 0x00000001 // Got broadcast packet(s) from incompatible older version of title 173 | #define XNET_BROADCAST_VERSION_NEWER 0x00000002 // Got broadcast packet(s) from incompatible newer version of title 174 | DWORD WINAPI XNetGetBroadcastVersionStatus(BOOL fReset); 175 | #define XNET_OPTID_STARTUP_PARAMS 1 176 | #define XNET_OPTID_NIC_XMIT_BYTES 2 177 | #define XNET_OPTID_NIC_XMIT_FRAMES 3 178 | #define XNET_OPTID_NIC_RECV_BYTES 4 179 | #define XNET_OPTID_NIC_RECV_FRAMES 5 180 | #define XNET_OPTID_CALLER_XMIT_BYTES 6 181 | #define XNET_OPTID_CALLER_XMIT_FRAMES 7 182 | #define XNET_OPTID_CALLER_RECV_BYTES 8 183 | #define XNET_OPTID_CALLER_RECV_FRAMES 9 184 | 185 | INT WINAPI XNetGetOpt(DWORD dwOptId, BYTE *pbValue, DWORD *pdwValueSize); 186 | INT WINAPI XNetSetOpt(DWORD dwOptId, const BYTE *pbValue, DWORD dwValueSize); 187 | 188 | #define XNID(Version, Area, Index) (DWORD)((WORD)(Area) << 25 | (WORD)(Version) << 16 | (WORD)(Index)) 189 | #define XNID_VERSION(msgid) (((msgid) >> 16) & 0x1FF) 190 | #define XNID_AREA(msgid) (((msgid) >> 25) & 0x3F) 191 | #define XNID_INDEX(msgid) ((msgid)&0xFFFF) 192 | 193 | #define XNOTIFY_SYSTEM (0x00000001) 194 | #define XNOTIFY_LIVE (0x00000002) 195 | #define XNOTIFY_FRIENDS (0x00000004) 196 | #define XNOTIFY_CUSTOM (0x00000008) 197 | #define XNOTIFY_XMP (0x00000020) 198 | #define XNOTIFY_MSGR (0x00000040) 199 | #define XNOTIFY_PARTY (0x00000080) 200 | #define XNOTIFY_ALL (XNOTIFY_SYSTEM | XNOTIFY_LIVE | XNOTIFY_FRIENDS | XNOTIFY_CUSTOM | XNOTIFY_XMP | XNOTIFY_MSGR | XNOTIFY_PARTY) 201 | 202 | #define _XNAREA_SYSTEM (0) 203 | #define _XNAREA_LIVE (1) 204 | #define _XNAREA_FRIENDS (2) 205 | #define _XNAREA_CUSTOM (3) 206 | #define _XNAREA_XMP (5) 207 | #define _XNAREA_MSGR (6) 208 | #define _XNAREA_PARTY (7) 209 | 210 | #define XN_SYS_FIRST XNID(0, _XNAREA_SYSTEM, 0x0001) 211 | #define XN_SYS_UI XNID(0, _XNAREA_SYSTEM, 0x0009) 212 | #define XN_SYS_SIGNINCHANGED XNID(0, _XNAREA_SYSTEM, 0x000a) 213 | #define XN_SYS_STORAGEDEVICESCHANGED XNID(0, _XNAREA_SYSTEM, 0x000b) 214 | #define XN_SYS_PROFILESETTINGCHANGED XNID(0, _XNAREA_SYSTEM, 0x000e) 215 | #define XN_SYS_MUTELISTCHANGED XNID(0, _XNAREA_SYSTEM, 0x0011) 216 | #define XN_SYS_INPUTDEVICESCHANGED XNID(0, _XNAREA_SYSTEM, 0x0012) 217 | #define XN_SYS_INPUTDEVICECONFIGCHANGED XNID(1, _XNAREA_SYSTEM, 0x0013) 218 | #define XN_SYS_PLAYTIMERNOTICE XNID(3, _XNAREA_SYSTEM, 0x0015) 219 | #define XN_SYS_AVATARCHANGED XNID(4, _XNAREA_SYSTEM, 0x0017) 220 | #define XN_SYS_NUIHARDWARESTATUSCHANGED XNID(6, _XNAREA_SYSTEM, 0x0019) 221 | #define XN_SYS_NUIPAUSE XNID(6, _XNAREA_SYSTEM, 0x001a) 222 | #define XN_SYS_NUIUIAPPROACH XNID(6, _XNAREA_SYSTEM, 0x001b) 223 | #define XN_SYS_DEVICEREMAP XNID(6, _XNAREA_SYSTEM, 0x001c) 224 | #define XN_SYS_NUIBINDINGCHANGED XNID(6, _XNAREA_SYSTEM, 0x001d) 225 | #define XN_SYS_AUDIOLATENCYCHANGED XNID(8, _XNAREA_SYSTEM, 0x001e) 226 | #define XN_SYS_NUICHATBINDINGCHANGED XNID(8, _XNAREA_SYSTEM, 0x001f) 227 | #define XN_SYS_INPUTACTIVITYCHANGED XNID(9, _XNAREA_SYSTEM, 0x0020) 228 | #define XN_SYS_LAST XNID(0, _XNAREA_SYSTEM, 0x0023) 229 | 230 | #define XN_LIVE_FIRST XNID(0, _XNAREA_LIVE, 0x0001) 231 | #define XN_LIVE_CONNECTIONCHANGED XNID(0, _XNAREA_LIVE, 0x0001) 232 | #define XN_LIVE_INVITE_ACCEPTED XNID(0, _XNAREA_LIVE, 0x0002) 233 | #define XN_LIVE_LINK_STATE_CHANGED XNID(0, _XNAREA_LIVE, 0x0003) 234 | #define XN_LIVE_CONTENT_INSTALLED XNID(0, _XNAREA_LIVE, 0x0007) 235 | #define XN_LIVE_MEMBERSHIP_PURCHASED XNID(0, _XNAREA_LIVE, 0x0008) 236 | #define XN_LIVE_VOICECHAT_AWAY XNID(0, _XNAREA_LIVE, 0x0009) 237 | #define XN_LIVE_PRESENCE_CHANGED XNID(0, _XNAREA_LIVE, 0x000A) 238 | #define XN_LIVE_LAST XNID(XNID_CURRENTVERSION + 1, _XNAREA_LIVE, 0x0014) 239 | 240 | #define XN_FRIENDS_FIRST XNID(0, _XNAREA_FRIENDS, 0x0001) 241 | #define XN_FRIENDS_PRESENCE_CHANGED XNID(0, _XNAREA_FRIENDS, 0x0001) 242 | #define XN_FRIENDS_FRIEND_ADDED XNID(0, _XNAREA_FRIENDS, 0x0002) 243 | #define XN_FRIENDS_FRIEND_REMOVED XNID(0, _XNAREA_FRIENDS, 0x0003) 244 | #define XN_FRIENDS_LAST XNID(XNID_CURRENTVERSION + 1, _XNAREA_FRIENDS, 0x0009) 245 | 246 | #define XN_CUSTOM_FIRST XNID(0, _XNAREA_CUSTOM, 0x0001) 247 | #define XN_CUSTOM_ACTIONPRESSED XNID(0, _XNAREA_CUSTOM, 0x0003) 248 | #define XN_CUSTOM_GAMERCARD XNID(1, _XNAREA_CUSTOM, 0x0004) 249 | #define XN_CUSTOM_LAST XNID(XNID_CURRENTVERSION + 1, _XNAREA_CUSTOM, 0x0005) 250 | 251 | #define XN_XMP_FIRST XNID(0, _XNAREA_XMP, 0x0001) 252 | #define XN_XMP_STATECHANGED XNID(0, _XNAREA_XMP, 0x0001) 253 | #define XN_XMP_PLAYBACKBEHAVIORCHANGED XNID(0, _XNAREA_XMP, 0x0002) 254 | #define XN_XMP_PLAYBACKCONTROLLERCHANGED XNID(0, _XNAREA_XMP, 0x0003) 255 | #define XN_XMP_LAST XNID(XNID_CURRENTVERSION + 1, _XNAREA_XMP, 0x000D) 256 | 257 | #define XN_PARTY_FIRST XNID(0, _XNAREA_PARTY, 0x0001) 258 | #define XN_PARTY_MEMBERS_CHANGED XNID(4, _XNAREA_PARTY, 0x0002) 259 | #define XN_PARTY_LAST XNID(XNID_CURRENTVERSION + 1, _XNAREA_PARTY, 0x0006) 260 | typedef ULONGLONG XUID; 261 | typedef XUID *PXUID; 262 | #define INVALID_XUID ((XUID)0) 263 | #define XUSER_NAME_SIZE 16 264 | #define XUSER_MAX_NAME_LENGTH (XUSER_NAME_SIZE - 1) 265 | #define XUSER_PASSWORD_SIZE 25 266 | #define XUSER_MAX_PASSWORD_LENGTH (XUSER_PASSWORD_SIZE - 1) 267 | #define XUSER_GET_SIGNIN_INFO_ONLINE_XUID_ONLY 0x00000002 268 | #define XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY 0x00000001 269 | #define XUSER_INFO_FLAG_LIVE_ENABLED 0x00000001 270 | #define XUSER_INFO_FLAG_GUEST 0x00000002 271 | 272 | typedef enum _XUSER_SIGNIN_STATE 273 | { 274 | eXUserSigninState_NotSignedIn, 275 | eXUserSigninState_SignedInLocally, 276 | eXUserSigninState_SignedInToLive 277 | } XUSER_SIGNIN_STATE; 278 | 279 | typedef struct _XUSER_SIGNIN_INFO 280 | { 281 | XUID xuid; 282 | DWORD dwInfoFlags; 283 | XUSER_SIGNIN_STATE UserSigninState; 284 | DWORD dwGuestNumber; 285 | DWORD dwSponsorUserIndex; 286 | CHAR szUserName[XUSER_NAME_SIZE]; 287 | } XUSER_SIGNIN_INFO, *PXUSER_SIGNIN_INFO; 288 | 289 | // Xbox-specific Overlapped 290 | typedef struct _XOVERLAPPED XOVERLAPPED, *PXOVERLAPPED; 291 | typedef VOID(WINAPI *PXOVERLAPPED_COMPLETION_ROUTINE)( 292 | DWORD dwErrorCode, 293 | DWORD dwNumberOfBytesTransfered, 294 | DWORD pOverlapped); 295 | 296 | typedef struct _XOVERLAPPED 297 | { 298 | ULONG_PTR InternalLow; 299 | ULONG_PTR InternalHigh; 300 | ULONG_PTR InternalContext; 301 | HANDLE hEvent; 302 | PXOVERLAPPED_COMPLETION_ROUTINE pCompletionRoutine; 303 | DWORD_PTR dwCompletionContext; 304 | DWORD dwExtendedError; 305 | } XOVERLAPPED, *PXOVERLAPPED; 306 | 307 | typedef enum _XUSER_PROFILE_SOURCE 308 | { 309 | XSOURCE_NO_VALUE = 0, 310 | XSOURCE_DEFAULT, 311 | XSOURCE_TITLE, 312 | XSOURCE_PERMISSION_DENIED 313 | } XUSER_PROFILE_SOURCE; 314 | 315 | typedef struct 316 | { 317 | BYTE type; 318 | union 319 | { 320 | LONG nData; 321 | LONGLONG i64Data; 322 | double dblData; 323 | struct 324 | { 325 | DWORD cbData; 326 | LPWSTR pwszData; 327 | } string; 328 | float fData; 329 | struct 330 | { 331 | DWORD cbData; 332 | LPBYTE pbData; 333 | } binary; 334 | FILETIME ftData; 335 | }; 336 | } XUSER_DATA, *PXUSER_DATA; 337 | 338 | typedef struct _XUSER_PROFILE_SETTING 339 | { 340 | XUSER_PROFILE_SOURCE source; 341 | union 342 | { 343 | DWORD dwUserIndex; 344 | XUID xuid; 345 | } user; 346 | DWORD dwSettingId; 347 | XUSER_DATA data; 348 | } XUSER_PROFILE_SETTING, *PXUSER_PROFILE_SETTING; 349 | 350 | typedef struct _XUSER_READ_PROFILE_SETTING_RESULT 351 | { 352 | DWORD dwSettingsLen; 353 | XUSER_PROFILE_SETTING *pSettings; 354 | } XUSER_READ_PROFILE_SETTING_RESULT, *PXUSER_READ_PROFILE_SETTING_RESULT; 355 | 356 | #define XCONTENTTYPE_SAVEDGAME 0x00000001 357 | #define XCONTENTTYPE_MARKETPLACE 0x00000002 358 | #define XCONTENTTYPE_PUBLISHER 0x00000003 359 | #define XCONTENTTYPE_GAMEDEMO 0x00080000 360 | #define XCONTENTTYPE_ARCADE 0x000D0000 361 | #define XCONTENTFLAG_NONE 0x00000000 362 | #define XCONTENTFLAG_CREATENEW CREATE_NEW 363 | #define XCONTENTFLAG_CREATEALWAYS CREATE_ALWAYS 364 | #define XCONTENTFLAG_OPENEXISTING OPEN_EXISTING 365 | #define XCONTENTFLAG_OPENALWAYS OPEN_ALWAYS 366 | #define XCONTENTFLAG_TRUNCATEEXISTING TRUNCATE_EXISTING 367 | #define XCONTENTFLAG_NOPROFILE_TRANSFER 0x00000010 368 | #define XCONTENTFLAG_NODEVICE_TRANSFER 0x00000020 369 | #define XCONTENTFLAG_STRONG_SIGNED 0x00000040 370 | #define XCONTENTFLAG_ALLOWPROFILE_TRANSFER 0x00000080 371 | #define XCONTENTFLAG_MOVEONLY_TRANSFER 0x00000800 372 | #define XCONTENTFLAG_MANAGESTORAGE 0x00000100 373 | #define XCONTENTFLAG_FORCE_SHOW_UI 0x00000200 374 | #define XCONTENTFLAG_ENUM_EXCLUDECOMMON 0x00001000 375 | #define XCONTENT_MAX_DISPLAYNAME_LENGTH 128 376 | #define XCONTENT_MAX_FILENAME_LENGTH 42 377 | #define XCONTENTDEVICE_MAX_NAME_LENGTH 27 378 | 379 | typedef DWORD XCONTENTDEVICEID, *PXCONTENTDEVICEID; 380 | typedef struct _XCONTENT_DATA 381 | { 382 | DWORD ContentNum; 383 | DWORD TitleId; 384 | DWORD ContentPackageType; 385 | BYTE ContentId[20]; 386 | } XCONTENT_DATA, *PXCONTENT_DATA; 387 | 388 | typedef struct _XUSER_ACHIEVEMENT 389 | { 390 | DWORD dwUserIndex; 391 | DWORD dwAchievementId; 392 | } XUSER_ACHIEVEMENT, *PXUSER_ACHIEVEMENT; 393 | 394 | typedef struct 395 | { 396 | XNKID sessionID; 397 | XNADDR hostAddress; 398 | XNKEY keyExchangeKey; 399 | } XSESSION_INFO, *PXSESSION_INFO; 400 | 401 | typedef enum _XSESSION_STATE 402 | { 403 | XSESSION_STATE_LOBBY = 0, 404 | XSESSION_STATE_REGISTRATION, 405 | XSESSION_STATE_INGAME, 406 | XSESSION_STATE_REPORTING, 407 | XSESSION_STATE_DELETED 408 | } XSESSION_STATE; 409 | 410 | typedef struct 411 | { 412 | XUID xuidOnline; 413 | DWORD dwUserIndex; 414 | DWORD dwFlags; 415 | } XSESSION_MEMBER; 416 | 417 | typedef struct 418 | { 419 | DWORD dwUserIndexHost; 420 | DWORD dwGameType; 421 | DWORD dwGameMode; 422 | DWORD dwFlags; 423 | DWORD dwMaxPublicSlots; 424 | DWORD dwMaxPrivateSlots; 425 | DWORD dwAvailablePublicSlots; 426 | DWORD dwAvailablePrivateSlots; 427 | DWORD dwActualMemberCount; 428 | DWORD dwReturnedMemberCount; 429 | XSESSION_STATE eState; 430 | ULONGLONG qwNonce; 431 | XSESSION_INFO sessionInfo; 432 | XNKID xnkidArbitration; 433 | XSESSION_MEMBER *pSessionMembers; 434 | } XSESSION_LOCAL_DETAILS, *PXSESSION_LOCAL_DETAILS; 435 | 436 | typedef enum 437 | { 438 | XONLINE_NAT_OPEN = 1, 439 | XONLINE_NAT_MODERATE, 440 | XONLINE_NAT_STRICT 441 | } XONLINE_NAT_TYPE; 442 | 443 | typedef struct _XUSER_PROPERTY 444 | { 445 | DWORD dwPropertyId; 446 | XUSER_DATA value; 447 | } XUSER_PROPERTY, *PXUSER_PROPERTY; 448 | 449 | typedef struct _XUSER_CONTEXT 450 | { 451 | DWORD dwContextId; 452 | DWORD dwValue; 453 | } XUSER_CONTEXT, *PXUSER_CONTEXT; 454 | 455 | typedef struct _XSESSION_SEARCHRESULT 456 | { 457 | XSESSION_INFO info; 458 | DWORD dwOpenPublicSlots; 459 | DWORD dwOpenPrivateSlots; 460 | DWORD dwFilledPublicSlots; 461 | DWORD dwFilledPrivateSlots; 462 | DWORD cProperties; 463 | DWORD cContexts; 464 | PXUSER_PROPERTY pProperties; 465 | PXUSER_CONTEXT pContexts; 466 | } XSESSION_SEARCHRESULT, *PXSESSION_SEARCHRESULT; 467 | 468 | typedef struct _XSESSION_SEARCHRESULT_HEADER 469 | { 470 | DWORD dwSearchResults; 471 | XSESSION_SEARCHRESULT *pResults; 472 | } XSESSION_SEARCHRESULT_HEADER, *PXSESSION_SEARCHRESULT_HEADER; 473 | 474 | typedef struct _XSESSION_REGISTRANT 475 | { 476 | ULONGLONG qwMachineID; 477 | DWORD bTrustworthiness; 478 | DWORD bNumUsers; 479 | XUID *rgUsers; 480 | } XSESSION_REGISTRANT; 481 | 482 | typedef struct _XSESSION_REGISTRATION_RESULTS 483 | { 484 | DWORD wNumRegistrants; 485 | XSESSION_REGISTRANT *rgRegistrants; 486 | } XSESSION_REGISTRATION_RESULTS, *PXSESSION_REGISTRATION_RESULTS; 487 | 488 | #define X_CONTEXT_PRESENCE 0x00008001 // ?? 489 | #define X_CONTEXT_GAME_TYPE 0x0000800A // DR2 490 | #define X_CONTEXT_GAME_MODE 0x0000800B 491 | #define X_CONTEXT_GAME_TYPE_RANKED 0 492 | #define X_CONTEXT_GAME_TYPE_STANDARD 1 493 | 494 | typedef enum _XPRIVILEGE_TYPE 495 | { 496 | XPRIVILEGE_MULTIPLAYER_SESSIONS = 254, 497 | XPRIVILEGE_COMMUNICATIONS = 252, 498 | XPRIVILEGE_COMMUNICATIONS_FRIENDS_ONLY = 251, 499 | XPRIVILEGE_PROFILE_VIEWING = 249, 500 | XPRIVILEGE_PROFILE_VIEWING_FRIENDS_ONLY = 248, 501 | XPRIVILEGE_USER_CREATED_CONTENT = 247, 502 | XPRIVILEGE_USER_CREATED_CONTENT_FRIENDS_ONLY = 246, 503 | XPRIVILEGE_PURCHASE_CONTENT = 245, 504 | XPRIVILEGE_PRESENCE = 244, 505 | XPRIVILEGE_PRESENCE_FRIENDS_ONLY = 243, 506 | XPRIVILEGE_SHARE_CONTENT_OUTSIDE_LIVE = 211, 507 | XPRIVILEGE_TRADE_CONTENT = 238, 508 | XPRIVILEGE_VIDEO_COMMUNICATIONS = 235, 509 | XPRIVILEGE_VIDEO_COMMUNICATIONS_FRIENDS_ONLY = 234, 510 | XPRIVILEGE_CONTENT_AUTHOR = 222 511 | } XPRIVILEGE_TYPE; 512 | 513 | typedef enum 514 | { 515 | XMARKETPLACE_OFFERING_TYPE_CONTENT = 0x00000002, 516 | XMARKETPLACE_OFFERING_TYPE_GAME_DEMO = 0x00000020, 517 | XMARKETPLACE_OFFERING_TYPE_GAME_TRAILER = 0x00000040, 518 | XMARKETPLACE_OFFERING_TYPE_THEME = 0x00000080, 519 | XMARKETPLACE_OFFERING_TYPE_TILE = 0x00000800, 520 | XMARKETPLACE_OFFERING_TYPE_ARCADE = 0x00002000, 521 | XMARKETPLACE_OFFERING_TYPE_VIDEO = 0x00004000, 522 | XMARKETPLACE_OFFERING_TYPE_CONSUMABLE = 0x00010000, 523 | XMARKETPLACE_OFFERING_TYPE_AVATARITEM = 0x00100000 524 | } XMARKETPLACE_OFFERING_TYPE; 525 | 526 | #define MAX_RICHPRESENCE_SIZE 100 527 | 528 | typedef struct _XONLINE_FRIEND 529 | { 530 | XUID xuid; 531 | CHAR szGamertag[XUSER_NAME_SIZE]; 532 | DWORD dwFriendState; 533 | XNKID sessionID; 534 | DWORD dwTitleID; 535 | FILETIME ftUserTime; 536 | XNKID xnkidInvite; 537 | FILETIME gameinviteTime; 538 | DWORD cchRichPresence; 539 | WCHAR wszRichPresence[MAX_RICHPRESENCE_SIZE]; 540 | } XONLINE_FRIEND, *PXONLINE_FRIEND; 541 | 542 | class IXHV2ENGINE 543 | { 544 | public: 545 | IXHV2ENGINE(); 546 | // 2F0 bytes = actual size 547 | // - note: check all INT return values - may not be true 548 | INT Dummy1(VOID *pThis); // 00 549 | INT Dummy2(VOID *pThis); // 04 550 | HRESULT Dummy3(VOID *pThis, int a); // 08 551 | HRESULT StartLocalProcessingModes(VOID *pThis, DWORD dwUserIndex, /* CONST PXHV_PROCESSING_MODE*/ VOID *processingModes, DWORD dwNumProcessingModes); 552 | HRESULT StopLocalProcessingModes(VOID *pThis, DWORD dwUserIndex, /*CONST PXHV_PROCESSING_MODE*/ VOID *processingModes, DWORD dwNumProcessingModes); 553 | HRESULT StartRemoteProcessingModes(VOID *pThis, int a1, int a2, int a3, int a4); 554 | HRESULT Dummy7(VOID *pThis, int a1, int a2, int a3, int a4); // 18 555 | HRESULT Dummy8(VOID *pThis, int a1); // 1C 556 | HRESULT RegisterLocalTalker(VOID *pThis, DWORD dwUserIndex); 557 | HRESULT UnregisterLocalTalker(VOID *pThis, DWORD dwUserIndex); 558 | HRESULT Dummy11(VOID *pThis, int a1, int a2, int a3, int a4, int a5); // 28 559 | HRESULT UnregisterRemoteTalker(VOID *pThis, int a1, int a2); 560 | HRESULT Dummy13(VOID *pThis, int a1, int a2); // 30 561 | INT Dummy14(VOID *pThis, int a1); // 34 562 | INT Dummy15(VOID *pThis, int a1); // 38 563 | HRESULT Dummy16(VOID *pThis, int a1, int a2); // 3C 564 | DWORD GetDataReadyFlags(VOID *pThis); 565 | HRESULT GetLocalChatData(VOID *pThis, DWORD dwUserIndex, PBYTE pbData, PDWORD pdwSize, PDWORD pdwPackets); 566 | HRESULT SetPlaybackPriority(VOID *pThis, int a1, int a2, int a3, int a4); 567 | HRESULT Dummy20(VOID *pThis, int a1, int a2, int a3, int a4); // 4C 568 | // possible does not exist 569 | HRESULT Dummy21(VOID *pThis); // 54 570 | HRESULT Dummy22(VOID *pThis); // 58 571 | HRESULT Dummy23(VOID *pThis); // 5C 572 | HRESULT Dummy24(VOID *pThis); // 60 573 | HRESULT Dummy25(VOID *pThis); // 64 574 | HRESULT Dummy26(VOID *pThis); // 68 575 | HRESULT Dummy27(VOID *pThis); // 6C 576 | HRESULT Dummy28(VOID *pThis); // 70 577 | HRESULT Dummy29(VOID *pThis); // 74 578 | HRESULT Dummy30(VOID *pThis); // 78 579 | HRESULT Dummy31(VOID *pThis); // 7C 580 | HRESULT Dummy32(VOID *pThis); // 80 581 | typedef void (IXHV2ENGINE::*HV2FUNCPTR)(void); 582 | // ugly, low-skilled hackaround 583 | HV2FUNCPTR *funcTablePtr; 584 | HV2FUNCPTR funcPtr[100]; 585 | HV2FUNCPTR func2; 586 | }; 587 | typedef IXHV2ENGINE *PIXHV2ENGINE; 588 | typedef struct 589 | { 590 | DWORD dwId; 591 | LPWSTR pwszLabel; 592 | LPWSTR pwszDescription; 593 | LPWSTR pwszUnachieved; 594 | DWORD dwImageId; 595 | DWORD dwCred; 596 | FILETIME ftAchieved; 597 | DWORD dwFlags; 598 | } XACHIEVEMENT_DETAILS, *PXACHIEVEMENT_DETAILS; 599 | 600 | #define XACHIEVEMENT_DETAILS_ACHIEVED_ONLINE 0x10000 601 | #define XACHIEVEMENT_DETAILS_ACHIEVED 0x20000 602 | 603 | typedef struct _MESSAGEBOX_RESULT 604 | { 605 | union 606 | { 607 | DWORD dwButtonPressed; 608 | WORD rgwPasscode[4]; 609 | }; 610 | } MESSAGEBOX_RESULT, *PMESSAGEBOX_RESULT; 611 | 612 | typedef enum _XSTORAGE_FACILITY 613 | { 614 | XSTORAGE_FACILITY_GAME_CLIP = 1, 615 | XSTORAGE_FACILITY_PER_TITLE = 2, 616 | XSTORAGE_FACILITY_PER_USER_TITLE = 3 617 | } XSTORAGE_FACILITY; 618 | 619 | typedef struct _XSTORAGE_DOWNLOAD_TO_MEMORY_RESULTS 620 | { 621 | DWORD dwBytesTotal; 622 | XUID xuidOwner; 623 | FILETIME ftCreated; 624 | } XSTORAGE_DOWNLOAD_TO_MEMORY_RESULTS; 625 | 626 | typedef struct 627 | { 628 | DWORD dwNewOffers; 629 | DWORD dwTotalOffers; 630 | } XOFFERING_CONTENTAVAILABLE_RESULT; 631 | 632 | #define XMARKETPLACE_CONTENT_ID_LEN 20 633 | 634 | typedef struct 635 | { 636 | ULONGLONG qwOfferID; 637 | ULONGLONG qwPreviewOfferID; 638 | DWORD dwOfferNameLength; 639 | WCHAR *wszOfferName; 640 | DWORD dwOfferType; 641 | BYTE contentId[XMARKETPLACE_CONTENT_ID_LEN]; 642 | BOOL fIsUnrestrictedLicense; 643 | DWORD dwLicenseMask; 644 | DWORD dwTitleID; 645 | DWORD dwContentCategory; 646 | DWORD dwTitleNameLength; 647 | WCHAR *wszTitleName; 648 | BOOL fUserHasPurchased; 649 | DWORD dwPackageSize; 650 | DWORD dwInstallSize; 651 | DWORD dwSellTextLength; 652 | WCHAR *wszSellText; 653 | DWORD dwAssetID; 654 | DWORD dwPurchaseQuantity; 655 | DWORD dwPointsPrice; 656 | } XMARKETPLACE_CONTENTOFFER_INFO, *PXMARKETPLACE_CONTENTOFFER_INFO; 657 | 658 | typedef struct 659 | { 660 | IN_ADDR inaServer; 661 | DWORD dwFlags; 662 | CHAR szServerInfo[200]; 663 | } XTITLESERVER_INFO, *PXTITLESERVER_INFO; 664 | 665 | typedef struct _STRING_DATA 666 | { 667 | WORD wStringSize; 668 | WCHAR *pszString; 669 | } STRING_DATA; 670 | 671 | #pragma pack(push, 1) 672 | typedef struct _STRING_VERIFY_RESPONSE 673 | { 674 | WORD wNumStrings; 675 | HRESULT *pStringResult; 676 | } STRING_VERIFY_RESPONSE; 677 | #pragma pack(pop) 678 | 679 | #define GAMEPACKETHEADERSIZE 17 680 | #define TRACE(...) 681 | #define TRACE2(...) 682 | 683 | #endif 684 | --------------------------------------------------------------------------------