diff --git a/Common/AutoUpdate.cpp b/Common/AutoUpdate.cpp index 58cd6f06..6654514d 100644 --- a/Common/AutoUpdate.cpp +++ b/Common/AutoUpdate.cpp @@ -16,8 +16,6 @@ #define WIN32_LEAN_AND_MEAN #include -#include -#include #include #include #include @@ -128,101 +126,6 @@ bool GetURLString(char*URL, std::string &data) return true; } -HRESULT UnZipFile(BSTR sourceZip, BSTR destFolder) -{ - HRESULT hr = E_FAIL; - IShellDispatch *pISD = nullptr; - Folder *pToFolder = nullptr; - Folder *pFromFolder = nullptr; - - do - { - if (FAILED(CoInitialize(NULL))) - { - Logging::Log() << __FUNCTION__ " Failed to CoInitialize!"; - break; - } - - if (FAILED(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD)) || !pISD) - { - Logging::Log() << __FUNCTION__ " Failed to CoCreateInstance!"; - break; - } - - VARIANT vFile; - VariantInit(&vFile); - vFile.vt = VT_BSTR; - vFile.bstrVal = sourceZip; - - if (FAILED(pISD->NameSpace(vFile, &pFromFolder))) - { - Logging::Log() << __FUNCTION__ " Failed to get source NameSpace! " << sourceZip; - break; - } - - VARIANT vDir; - VariantInit(&vDir); - vDir.vt = VT_BSTR; - vDir.bstrVal = destFolder; - if (!PathFileExists(destFolder)) - { - CreateDirectory(destFolder, nullptr); - } - - // Destination is our zip file - if (FAILED(pISD->NameSpace(vDir, &pToFolder)) || !pToFolder) - { - Logging::Log() << __FUNCTION__ " Failed to get destination NameSpace! " << destFolder; - break; - } - - FolderItems *fi = nullptr; - if (FAILED(pFromFolder->Items(&fi))) - { - Logging::Log() << __FUNCTION__ " Failed to get file list from zip file!"; - break; - } - - VARIANT vOpt; - VariantInit(&vOpt); - vOpt.vt = VT_I4; - vOpt.lVal = FOF_NO_UI; - - VARIANT newV; - VariantInit(&newV); - newV.vt = VT_DISPATCH; - newV.pdispVal = fi; - - if (FAILED(pToFolder->CopyHere(newV, vOpt))) - { - Logging::Log() << __FUNCTION__ " Failed to extract files out of zip file!"; - break; - } - - hr = S_OK; - } - while (false); - - if (pToFolder) - { - pToFolder->Release(); - } - - if (pFromFolder) - { - pFromFolder->Release(); - } - - if (pISD) - { - pISD->Release(); - } - - CoUninitialize(); - - return hr; -} - DWORD MatchCount(std::string &path1, std::string &path2) { DWORD size = min(path1.size(), path2.size()); diff --git a/Common/LoadModules.cpp b/Common/LoadModules.cpp index 66907072..ffae2793 100644 --- a/Common/LoadModules.cpp +++ b/Common/LoadModules.cpp @@ -21,19 +21,15 @@ #include #include #include +#include "Resources\sh2-enhce.h" #include "LoadModules.h" -#include "External\Hooking\Hook.h" -#include "FileSystemHooks.h" +#include "Patches\Patches.h" #include "Settings.h" #include "Utils.h" #include "Logging\Logging.h" -int n = 0; -LPCWSTR exTempPath = L"~tmp_sh2_enhce"; - typedef void(WINAPI *PFN_InitializeASI)(void); - // Find asi plugins to load void FindFiles(WIN32_FIND_DATA* fd) { @@ -132,6 +128,72 @@ void InitializeASI(HMODULE hModule) p_InitializeASI(); } +void ExtractD3DX9Tools() +{ + do { + // Get Silent Hill 2 file path + wchar_t sh2path[MAX_PATH]; + if (!GetSH2FolderPath(sh2path, MAX_PATH)) + { + break; + } + + // Remove Silent Hill 2 process name from path + wchar_t *pdest = wcsrchr(sh2path, '\\'); + if (pdest) + { + wcscpy_s(pdest, MAX_PATH - wcslen(sh2path), L"\\"); + } + + // Append virtual store and Silent Hill 2 to local appdata path + wchar_t d3dx9zip[MAX_PATH]; + wcscpy(d3dx9zip, sh2path); + if (!PathAppend(d3dx9zip, L"D3DX9.zip")) + { + break; + } + + HRSRC hResource = FindResource(m_hModule, MAKEINTRESOURCE(IDR_D3DX9_TOOLS), RT_RCDATA); + if (hResource) + { + HGLOBAL hLoadedResource = LoadResource(m_hModule, hResource); + if (hLoadedResource) + { + LPVOID pLockedResource = LockResource(hLoadedResource); + if (pLockedResource) + { + DWORD dwResourceSize = SizeofResource(m_hModule, hResource); + if (dwResourceSize != 0) + { + Logging::Log() << "Extracting the " << d3dx9zip << " file..."; + + std::fstream fsModule; + fsModule.open(d3dx9zip, std::ios_base::out | std::ios_base::binary); + if (fsModule.is_open()) + { + // Write zip file to disk + fsModule.write((char*)pLockedResource, dwResourceSize); + fsModule.close(); + // Extract zip file + UnZipFile(d3dx9zip, sh2path); + // Delete zip file + DeleteFile(d3dx9zip); + // Return + return; + } + else + { + RelaunchSilentHill2(); + } + } + } + } + } + } while (false); + + Logging::Log() << __FUNCTION__ << " Error: could not extract the 'D3DX9.zip' file!"; +} + HRESULT DeleteAllfiles(LPCWSTR lpFolder) { WIN32_FIND_DATA FindFileData; diff --git a/Common/LoadModules.h b/Common/LoadModules.h index b66cc514..e4f0aeaf 100644 --- a/Common/LoadModules.h +++ b/Common/LoadModules.h @@ -2,4 +2,5 @@ void LoadASIPlugins(bool LoadFromScriptsOnly); void InitializeASI(HMODULE hModule); +void ExtractD3DX9Tools(); HRESULT DeleteAllfiles(LPCWSTR lpFolder); diff --git a/Common/Utils.cpp b/Common/Utils.cpp index 040af035..28092080 100644 --- a/Common/Utils.cpp +++ b/Common/Utils.cpp @@ -16,6 +16,8 @@ #define WIN32_LEAN_AND_MEAN #include +#include +#include #include #include #include @@ -481,6 +483,100 @@ void GetFileSize(uintmax_t fsize, char *strOutput, size_t size) strcpy_s(strOutput, size, strSize.c_str()); } +HRESULT UnZipFile(BSTR sourceZip, BSTR destFolder) +{ + HRESULT hr = E_FAIL; + IShellDispatch *pISD = nullptr; + Folder *pToFolder = nullptr; + Folder *pFromFolder = nullptr; + + do + { + if (FAILED(CoInitialize(NULL))) + { + Logging::Log() << __FUNCTION__ " Failed to CoInitialize!"; + break; + } + + if (FAILED(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD)) || !pISD) + { + Logging::Log() << __FUNCTION__ " Failed to CoCreateInstance!"; + break; + } + + VARIANT vFile; + VariantInit(&vFile); + vFile.vt = VT_BSTR; + vFile.bstrVal = sourceZip; + + if (FAILED(pISD->NameSpace(vFile, &pFromFolder))) + { + Logging::Log() << __FUNCTION__ " Failed to get source NameSpace! " << sourceZip; + break; + } + + VARIANT vDir; + VariantInit(&vDir); + vDir.vt = VT_BSTR; + vDir.bstrVal = destFolder; + if (!PathFileExists(destFolder)) + { + CreateDirectory(destFolder, nullptr); + } + + // Destination is our zip file + if (FAILED(pISD->NameSpace(vDir, &pToFolder)) || !pToFolder) + { + Logging::Log() << __FUNCTION__ " Failed to get destination NameSpace! " << destFolder; + break; + } + + FolderItems *fi = nullptr; + if (FAILED(pFromFolder->Items(&fi))) + { + Logging::Log() << __FUNCTION__ " Failed to get file list from zip file!"; + break; + } + + VARIANT vOpt; + VariantInit(&vOpt); + vOpt.vt = VT_I4; + vOpt.lVal = FOF_NO_UI; + + VARIANT newV; + VariantInit(&newV); + newV.vt = VT_DISPATCH; + newV.pdispVal = fi; + + if (FAILED(pToFolder->CopyHere(newV, vOpt))) + { + Logging::Log() << __FUNCTION__ " Failed to extract files out of zip file!"; + break; + } + + hr = S_OK; + } while (false); + + if (pToFolder) + { + pToFolder->Release(); + } + + if (pFromFolder) + { + pFromFolder->Release(); + } + + if (pISD) + { + pISD->Release(); + } + + CoUninitialize(); + + return hr; +} + bool GetModulePath(char *path, rsize_t size) { static char modpath[MAX_PATH] = { '\0' }; diff --git a/Common/Utils.h b/Common/Utils.h index e34a3fc2..b9edb503 100644 --- a/Common/Utils.h +++ b/Common/Utils.h @@ -1,6 +1,7 @@ #pragma once #include +#include void *GetAddressOfData(const void *data, size_t len, DWORD step = 1); void *GetAddressOfData(const void *data, size_t len, DWORD step, DWORD start, DWORD distance = 0x0FFFFFFF); @@ -18,6 +19,7 @@ void SetSingleCoreAffinity(); void AddHandleToVector(HMODULE dll); void UnloadAllModules(); DWORD ConvertFloat(float num); +HRESULT UnZipFile(BSTR sourceZip, BSTR destFolder); bool GetModulePath(char *path, rsize_t size); bool GetModulePath(wchar_t *path, rsize_t size); bool GetSH2FolderPath(char *path, rsize_t size); diff --git a/Patches/LaunchAsAdmin.cpp b/Patches/LaunchAsAdmin.cpp index adf0021e..e3fbdb9d 100644 --- a/Patches/LaunchAsAdmin.cpp +++ b/Patches/LaunchAsAdmin.cpp @@ -86,10 +86,19 @@ void CheckArgumentsForPID() } // Relaunch Silent Hill 2 with administrator rights -void RelaunchSilentHill2(const wchar_t *sh2path) +void RelaunchSilentHill2() { + // Only relaunch once + static bool RunOnce = false; + if (ProcessRelaunched || RunOnce) + { + return; + } + RunOnce = true; + // Check Silent Hill 2 file path - if (!ProcessRelaunched && PathFileExistsW(sh2path)) + wchar_t sh2path[MAX_PATH]; + if (GetSH2FolderPath(sh2path, MAX_PATH)) { // Get pid wchar_t parameter[40] = { '\0' }; @@ -123,14 +132,14 @@ void CheckAdminAccess() // Check if restart is needed if (NeedsRestart) { - RelaunchSilentHill2(sh2path); + RelaunchSilentHill2(); return; } // Check compatibility options if (CheckCompatibilityMode && GetEnvironmentVariableA("__COMPAT_LAYER", nullptr, 0)) { - RelaunchSilentHill2(sh2path); + RelaunchSilentHill2(); return; } @@ -150,7 +159,7 @@ void CheckAdminAccess() } else { - RelaunchSilentHill2(sh2path); + RelaunchSilentHill2(); return; } } diff --git a/Patches/Patches.h b/Patches/Patches.h index 0bfcf4c5..29a87606 100644 --- a/Patches/Patches.h +++ b/Patches/Patches.h @@ -53,6 +53,7 @@ DWORD *GetLoadingScreenPointer(); // Function patch declaration void CheckArgumentsForPID(); +void RelaunchSilentHill2(); void CheckAdminAccess(); void RemoveVirtualStoreFiles(); void RemoveCompatibilityMode(); diff --git a/Resources/BuildNo.rc b/Resources/BuildNo.rc index b9a782d7..5cd65bce 100644 --- a/Resources/BuildNo.rc +++ b/Resources/BuildNo.rc @@ -1 +1 @@ -#define BUILD_NUMBER 1859 +#define BUILD_NUMBER 1860 diff --git a/Resources/D3DX9.zip b/Resources/D3DX9.zip new file mode 100644 index 00000000..8209e19a Binary files /dev/null and b/Resources/D3DX9.zip differ diff --git a/Resources/UALx86.rc b/Resources/UALx86.rc index 133f7ae0..b4b01d4d 100644 Binary files a/Resources/UALx86.rc and b/Resources/UALx86.rc differ diff --git a/Resources/sh2-enhce.h b/Resources/sh2-enhce.h index 4e6ac7b4..e6f18af4 100644 --- a/Resources/sh2-enhce.h +++ b/Resources/sh2-enhce.h @@ -12,6 +12,8 @@ #define IDR_SEARCHTEX_DDS 301 #define IDR_AREATEX_DDS 302 +#define IDR_D3DX9_TOOLS 401 + // Main resource file details #define APP_NAME "Silent Hill 2: Enhanced Edition" #define APP_MAJOR 1 diff --git a/Wrappers/d3d8to9.cpp b/Wrappers/d3d8to9.cpp index 2c24240f..f70bba43 100644 --- a/Wrappers/d3d8to9.cpp +++ b/Wrappers/d3d8to9.cpp @@ -23,6 +23,7 @@ #include "d3d8to9.h" #include "External\Hooking\Hook.h" #include "Common\Utils.h" +#include "Common\LoadModules.h" #include "Common\Settings.h" #include "Logging\Logging.h" #include "BuildNo.rc" @@ -100,6 +101,13 @@ Direct3D8 *WINAPI Direct3DCreate8to9(UINT SDKVersion) d3dx9Module = LoadLibrary(d3dx9name); } + // Extract d3dx9 tools from binary + if (!d3dx9Module) + { + ExtractD3DX9Tools(); + d3dx9Module = LoadLibrary(L"d3dx9_43.dll"); + } + if (d3dx9Module) { Logging::Log() << "Loaded " << d3dx9name; @@ -109,21 +117,11 @@ Direct3D8 *WINAPI Direct3DCreate8to9(UINT SDKVersion) } else { + // Should never get here Logging::Log() << __FUNCTION__ << " Error: Failed to load d3dx9_xx.dll! Some features will not work correctly."; } } - // Check for required DirectX 9 runtime files - wchar_t d3dx9_path[MAX_PATH], d3dcompiler_path[MAX_PATH]; - GetSystemDirectory(d3dx9_path, MAX_PATH); - wcscat_s(d3dx9_path, L"\\d3dx9_43.dll"); - GetSystemDirectory(d3dcompiler_path, MAX_PATH); - wcscat_s(d3dcompiler_path, L"\\d3dcompiler_43.dll"); - if (!PathFileExists(d3dx9_path) || !PathFileExists(d3dcompiler_path)) - { - Logging::Log() << "Warning: Could not find expected DirectX 9.0c End-User Runtime files. Try installing from: https://www.microsoft.com/download/details.aspx?id=35"; - } - // Check if WineD3D is loaded if (GetModuleHandle(L"libwine.dll") || GetModuleHandle(L"wined3d.dll")) {