#ifdef __cplusplus // ADVPACK.DLL delay load class CRunSetupHook { public: #ifdef WX86 #define DELAYRSCAPI(_fn, _args, _nargs) \ DWORD _fn _args { \ HRESULT hres = Init(); \ DWORD dwRet = (DWORD)hres; \ if (SUCCEEDED(hres)) { \ dwRet = _pfn##_fn _nargs; \ } \ return dwRet; } \ DWORD (STDAPICALLTYPE* _pfn##_fn) _args; \ DWORD _fn##X86 _args { \ HRESULT hres = InitX86(); \ DWORD dwRet = (DWORD)hres; \ if (SUCCEEDED(hres)) { \ dwRet = _pfn##_fn##X86 _nargs; \ } \ return dwRet; } \ DWORD (STDAPICALLTYPE* _pfn##_fn##X86) _args; #else #define DELAYRSCAPI(_fn, _args, _nargs) \ DWORD _fn _args { \ HRESULT hres = Init(); \ DWORD dwRet = (DWORD)hres; \ if (SUCCEEDED(hres)) { \ dwRet = _pfn##_fn _nargs; \ } \ return dwRet; } \ DWORD (STDAPICALLTYPE* _pfn##_fn) _args; #endif HRESULT Init(void); #ifdef WX86 HRESULT InitX86(void); typedef BOOL (*pfnUnloadFn)(HMODULE hMod); pfnUnloadFn pfnUnload; #endif CRunSetupHook(); ~CRunSetupHook(); BOOL m_fInited; HMODULE m_hMod; #ifdef WX86 BOOL m_fInitedX86; HMODULE m_hModX86; HMODULE m_hModWx86; #endif DELAYRSCAPI( RunSetupCommand, (HWND hWnd, LPSTR szCmdName, LPSTR szInfSection, LPSTR szDir, LPSTR szTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved), (hWnd, szCmdName, szInfSection, szDir, szTitle, phEXE, dwFlags,pvReserved)); DELAYRSCAPI( NeedReboot, (DWORD dwRebootCheck), (dwRebootCheck)); DELAYRSCAPI( NeedRebootInit, (), ()); DELAYRSCAPI( TranslateInfString, (PCSTR pszInfFilename, PCSTR pszInstallSection, PCSTR pszTranslateSection, PCSTR pszTranslateKey, PSTR pszBuffer, DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved), (pszInfFilename, pszInstallSection, pszTranslateSection, pszTranslateKey, pszBuffer, dwBufferSize, pdwRequiredSize, pvReserved)); DELAYRSCAPI( AdvInstallFile, (HWND hwnd, LPCSTR lpszSourceDir, LPCSTR lpszSourceFile, LPCSTR lpszDestDir, LPCSTR lpszDestFile, DWORD dwFlags, DWORD dwReserved), (hwnd, lpszSourceDir, lpszSourceFile, lpszDestDir, lpszDestFile, dwFlags, dwReserved)); }; inline CRunSetupHook::CRunSetupHook() { m_fInited = FALSE; m_hMod = NULL; #ifdef WX86 m_hModX86 = m_hModWx86 = NULL; #endif } inline CRunSetupHook::~CRunSetupHook() { if (m_fInited) { if (m_hMod) { FreeLibrary(m_hMod); } #ifdef WX86 if (m_hModX86) { if (pfnUnload) { (*pfnUnload)(m_hModX86); // free x86 advpack.dll } } if (m_hModWx86) { FreeLibrary(m_hModWx86); // free wx86.dll } #endif } } inline HRESULT CRunSetupHook::Init(void) { if (m_fInited) { return S_OK; } m_hMod = LoadLibrary( "ADVPACK.DLL" ); if (!m_hMod) { return HRESULT_FROM_WIN32(GetLastError()); } #define CHECKAPI(_fn) \ *(FARPROC*)&(_pfn##_fn) = GetProcAddress(m_hMod, #_fn); \ if (!(_pfn##_fn)) return E_UNEXPECTED; CHECKAPI(RunSetupCommand); CHECKAPI(NeedReboot); CHECKAPI(NeedRebootInit); CHECKAPI(TranslateInfString); CHECKAPI(AdvInstallFile); m_fInited = TRUE; return S_OK; } #ifdef WX86 inline HRESULT CRunSetupHook::InitX86(void) { typedef HMODULE (*pfnLoadFn)(LPCWSTR name, DWORD dwFlags); typedef PVOID (*pfnThunkFn)(PVOID pvAddress, PVOID pvCbDispatch, BOOLEAN fNativeToX86); pfnLoadFn pfnLoad; pfnThunkFn pfnThunk; if (m_fInitedX86) { return S_OK; } // No need to check the reg key to see if Wx86 is installed and enabled. // By the time this routine runs, that has already been done. m_hModWx86 = LoadLibrary("wx86.dll"); if (!m_hModWx86) { return HRESULT_FROM_WIN32(GetLastError()); } pfnLoad = (pfnLoadFn)GetProcAddress(m_hModWx86, "Wx86LoadX86Dll"); pfnUnload = (pfnUnloadFn)GetProcAddress(m_hModWx86, "Wx86FreeX86Dll"); pfnThunk = (pfnThunkFn)GetProcAddress(m_hModWx86, "Wx86ThunkProc"); if (!pfnLoad || !pfnThunk || !pfnUnload) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); FreeLibrary(m_hModWx86); return hr; } // Load x86 advpack.dll m_hModX86 = (*pfnLoad)( L"ADVPACK.DLL", 0 ); if (!m_hModX86) { return HRESULT_FROM_WIN32(GetLastError()); } #undef CHECKAPI #define CHECKAPI(_fn, n) \ *(FARPROC*)&(_pfn##_fn##X86) = GetProcAddress(m_hModX86, #_fn); \ if (!(_pfn##_fn##X86)) return E_UNEXPECTED; \ *(FARPROC*)&(_pfn##_fn##X86) = (FARPROC)(*pfnThunk)(_pfn##_fn##X86, (PVOID)n, TRUE); CHECKAPI(RunSetupCommand, 8); CHECKAPI(NeedReboot, 1); CHECKAPI(NeedRebootInit, 0); CHECKAPI(TranslateInfString, 8); CHECKAPI(AdvInstallFile, 7); m_fInitedX86 = TRUE; return S_OK; } #endif #endif