windows-nt/Source/XPSP1/NT/shell/shdocvw/shell32.cpp
2020-09-26 16:20:57 +08:00

202 lines
6.2 KiB
C++

// 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));