// Wrappers for APIs that have moved elsewhere #include "priv.h" #include "shlwapip.h" //------------------------------------------------------------------------ // // APIs from SHDOCVW that are now forwarded to SHLWAPI // // // Note that we cannot use DLL forwarders because there is a bug // in Win95 where the loader screws up forwarders for bound DLLs. STDAPI_(DWORD) StopWatchModeFORWARD(VOID) { return StopWatchMode(); } STDAPI_(DWORD) StopWatchFlushFORWARD(VOID) { return StopWatchFlush(); } STDAPI SHRunIndirectRegClientCommandForward(HWND hwnd, LPCWSTR pszClient) { return SHRunIndirectRegClientCommand(hwnd, pszClient); } #ifdef ux10 /*IEUNIX : In the hp-ux linker, there is no option of specifying an internal name and an external name. */ #define StopWatch StopWatch #define StopWatchFORWARD StopWatch #endif STDAPI_(DWORD) StopWatchFORWARD(DWORD dwId, LPCSTR pszDesc, DWORD dwType, DWORD dwFlags, DWORD dwCount) { return StopWatchA(dwId, (LPCSTR)pszDesc, dwType, dwFlags, dwCount); } //------------------------------------------------------------------------ // // APIs from SHDOCVW that are now forwarded to SHELL32/SHDOC41 // // This variable name is a misnomer. It's really // // g_hinstShell32OrShdoc401DependingOnWhatWeDetected; // // I can live with the misnomer; saves typing. Think of it as // "the INSTANCE of SHDOC401 or whatever DLL is masquerading as // SHDOC401". // // extern "C" { HINSTANCE g_hinstSHDOC401 = NULL; } // // GetShdoc401 // // Detect whether we should be using Shell32 or Shdoc401 to handle // active desktop stuff. The rule is // // If PF_FORCESHDOC401 is set, then use shdoc401. (DEBUG only) // If shell32 version >= 5, then use shell32. // Else use shdoc401. // // Warning: THIS FUNCTION CANNOT BE CALLED DURING PROCESS_ATTACH // because it calls LoadLibrary. HINSTANCE GetShdoc401() { DWORD dwMajorVersion; HINSTANCE hinst; HINSTANCE hinstSh32 = GetModuleHandle(TEXT("SHELL32.DLL")); ASSERT(hinstSh32); #ifdef DEBUG if (g_dwPrototype & PF_FORCESHDOC401) { hinstSh32 = NULL; // force SHDOC401 to be loaded } #endif if (hinstSh32) { DLLVERSIONINFO dllinfo; DLLGETVERSIONPROC pfnGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstSh32, "DllGetVersion"); dllinfo.cbSize = sizeof(DLLVERSIONINFO); if (pfnGetVersion && SUCCEEDED(pfnGetVersion(&dllinfo))) { dwMajorVersion = dllinfo.dwMajorVersion; } else { dwMajorVersion = 0; } } else { dwMajorVersion = 0; } if (dwMajorVersion >= 5) { hinst = hinstSh32; } else { hinst = LoadLibrary(TEXT("SHDOC401.DLL")); if (NULL == hinst) { // If this fails we're screwed TraceMsg(TF_ERROR, "Failed to load SHDOC401.DLL."); } } g_hinstSHDOC401 = hinst; return hinst; } // // GetShdoc401ProcAddress // // Get a procedure from SHDOC401 or whoever is masquerading as same. // // Warning: THIS FUNCTION CANNOT BE CALLED DURING PROCESS_ATTACH // because it calls LoadLibrary. FARPROC GetShdoc401ProcAddress(FARPROC *ppfn, UINT ord) { if (*ppfn) { return *ppfn; } else { HINSTANCE hinst = g_hinstSHDOC401; // // No race condition here. If two threads both call GetShdoc401, // all that happens is that we load SHDOC401 into memory and then // bump his refcount up to 2 instead of leaving it at 1. Big deal. // if (hinst == NULL) { hinst = GetShdoc401(); } if (hinst) { return *ppfn = GetProcAddress(hinst, (LPCSTR)LongToHandle(ord)); } else { return NULL; } } } // // Delay-load-like macros. // #define DELAY_LOAD_SHDOC401(_type, _err, _fn, _ord, _arg, _nargs) \ STDAPI_(_type) _fn _arg \ { \ static FARPROC s_pfn##_fn = NULL; \ FARPROC pfn = GetShdoc401ProcAddress(&s_pfn##_fn, _ord); \ if (pfn) { \ typedef _type (__stdcall *PFN##_fn) _arg; \ return ((PFN##_fn)pfn) _nargs; \ } else { \ return _err; \ } \ } \ #define DELAY_LOAD_SHDOC401_VOID(_fn, _ord, _arg, _nargs) \ STDAPI_(void) _fn _arg \ { \ static FARPROC s_pfn##_fn = NULL; \ FARPROC pfn = GetShdoc401ProcAddress(&s_pfn##_fn, _ord); \ if (pfn) { \ typedef void (__stdcall *PFN##_fn) _arg; \ ((PFN##_fn)pfn) _nargs; \ } \ } \ // IE4 Shell Integrated Explorer called ShellDDEInit in shdocvw to // set up DDE. Forward this call to SHELL32/SHDOC401 appropriately. DELAY_LOAD_SHDOC401_VOID(ShellDDEInit, 188, (BOOL fInit), (fInit)); DELAY_LOAD_SHDOC401(HANDLE, NULL, SHCreateDesktop, 200, (IDeskTray* pdtray), (pdtray)); DELAY_LOAD_SHDOC401(BOOL, FALSE, SHDesktopMessageLoop, 201, (HANDLE hDesktop), (hDesktop)); // This may not have been used in IE4 DELAY_LOAD_SHDOC401(BOOL, FALSE, DDEHandleViewFolderNotify, 202, (IShellBrowser* psb, HWND hwnd, LPNMVIEWFOLDER lpnm), (psb, hwnd, lpnm)); DELAY_LOAD_SHDOC401(LPNMVIEWFOLDER, NULL, DDECreatePostNotify, 82, (LPNMVIEWFOLDER pnm), (pnm));