shell32.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 6k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. // Wrappers for APIs that have moved elsewhere
  2. #include "priv.h"
  3. #include "shlwapip.h"
  4. //------------------------------------------------------------------------
  5. //
  6. // APIs from SHDOCVW that are now forwarded to SHLWAPI
  7. //
  8. //
  9. //  Note that we cannot use DLL forwarders because there is a bug
  10. //  in Win95 where the loader screws up forwarders for bound DLLs.
  11. STDAPI_(DWORD) StopWatchModeFORWARD(VOID)
  12. {
  13.     return StopWatchMode();
  14. }
  15. STDAPI_(DWORD) StopWatchFlushFORWARD(VOID)
  16. {
  17.     return StopWatchFlush();
  18. }
  19. #ifdef ux10
  20. /*IEUNIX : In the hp-ux linker, there is no option of specifying an internal name and an external name.  */
  21. #define StopWatch StopWatch
  22. #define StopWatchFORWARD StopWatch
  23. #endif 
  24. STDAPI_(DWORD) StopWatchFORWARD(DWORD dwId, LPCSTR pszDesc, DWORD dwType, DWORD dwFlags, DWORD dwCount)
  25. {
  26.     return StopWatchA(dwId, (LPCSTR)pszDesc, dwType, dwFlags, dwCount);
  27. }
  28. //------------------------------------------------------------------------
  29. //
  30. // APIs from SHDOCVW that are now forwarded to SHELL32/SHDOC41
  31. //
  32. //  This variable name is a misnomer.  It's really
  33. //
  34. //  g_hinstShell32OrShdoc401DependingOnWhatWeDetected;
  35. //
  36. //  I can live with the misnomer; saves typing.  Think of it as
  37. //  "the INSTANCE of SHDOC401 or whatever DLL is masquerading as
  38. //  SHDOC401".
  39. //
  40. //
  41. extern "C" { HINSTANCE g_hinstSHDOC401 = NULL; }
  42. //
  43. //  GetShdoc401
  44. //
  45. //  Detect whether we should be using Shell32 or Shdoc401 to handle
  46. //  active desktop stuff.  The rule is
  47. //
  48. //  If PF_FORCESHDOC401 is set, then use shdoc401. (DEBUG only)
  49. //  If shell32 version >= 5, then use shell32.
  50. //  Else use shdoc401.
  51. //
  52. //  Warning:  THIS FUNCTION CANNOT BE CALLED DURING PROCESS_ATTACH
  53. //  because it calls LoadLibrary.
  54. HINSTANCE GetShdoc401()
  55. {
  56.     DWORD dwMajorVersion;
  57.     HINSTANCE hinst;
  58.     HINSTANCE hinstSh32 = GetModuleHandle(TEXT("SHELL32.DLL"));
  59.     ASSERT(hinstSh32);
  60. #ifdef DEBUG
  61.     if (g_dwPrototype & PF_FORCESHDOC401) {
  62.         hinstSh32 = NULL; // force SHDOC401 to be loaded
  63.     }
  64. #endif
  65.     if (hinstSh32) {
  66.         DLLVERSIONINFO dllinfo;
  67.         DLLGETVERSIONPROC pfnGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstSh32, "DllGetVersion");
  68.         dllinfo.cbSize = sizeof(DLLVERSIONINFO);
  69.         if (pfnGetVersion && SUCCEEDED(pfnGetVersion(&dllinfo))) {
  70.             dwMajorVersion = dllinfo.dwMajorVersion;
  71.         } else {
  72.             dwMajorVersion = 0;
  73.         }
  74.     } else {
  75.         dwMajorVersion = 0;
  76.     }
  77.     if (dwMajorVersion >= 5) {
  78.         hinst = hinstSh32;
  79.     } else {
  80.         hinst = LoadLibrary(TEXT("SHDOC401.DLL"));
  81.         if (NULL == hinst)
  82.         {
  83.             // If this fails we're screwed
  84.             TraceMsg(TF_ERROR, "Failed to load SHDOC401.DLL.  We're screwed...");
  85.         }
  86.     }
  87.     g_hinstSHDOC401 = hinst;
  88.     return hinst;
  89. }
  90. //
  91. //  GetShdoc401ProcAddress
  92. //
  93. //  Get a procedure from SHDOC401 or whoever is masquerading as same.
  94. //
  95. //  Warning:  THIS FUNCTION CANNOT BE CALLED DURING PROCESS_ATTACH
  96. //  because it calls LoadLibrary.
  97. FARPROC GetShdoc401ProcAddress(FARPROC *ppfn, UINT ord)
  98. {
  99.     if (*ppfn) {
  100.         return *ppfn;
  101.     } else {
  102.         HINSTANCE hinst = g_hinstSHDOC401;
  103.         //
  104.         //  No race condition here.  If two threads both call GetShdoc401,
  105.         //  all that happens is that we load SHDOC401 into memory and then
  106.         //  bump his refcount up to 2 instead of leaving it at 1.  Big deal.
  107.         //
  108.         if (hinst == NULL) {
  109.             hinst = GetShdoc401();
  110.         }
  111.         if (hinst) {
  112.             return *ppfn = GetProcAddress(hinst, (LPCSTR)LongToHandle(ord));
  113.         } else {
  114.             return NULL;
  115.         }
  116.     }
  117. }
  118. //
  119. //  Delay-load-like macros.
  120. //
  121. #define DELAY_LOAD_SHDOC401(_type, _err, _fn, _ord, _arg, _nargs)   
  122.     STDAPI_(_type) _fn _arg                                         
  123.     {                                                               
  124.         static FARPROC s_pfn##_fn = NULL;                           
  125.         FARPROC pfn = GetShdoc401ProcAddress(&s_pfn##_fn, _ord);    
  126.         if (pfn) {                                                  
  127.             typedef _type (__stdcall *PFN##_fn) _arg;               
  128.             return ((PFN##_fn)pfn) _nargs;                          
  129.         } else {                                                    
  130.             return _err;                                            
  131.         }                                                           
  132.     }                                                               
  133. #define DELAY_LOAD_SHDOC401_VOID(_fn, _ord, _arg, _nargs)           
  134.     STDAPI_(void) _fn _arg                                          
  135.     {                                                               
  136.         static FARPROC s_pfn##_fn = NULL;                           
  137.         FARPROC pfn = GetShdoc401ProcAddress(&s_pfn##_fn, _ord);    
  138.         if (pfn) {                                                  
  139.             typedef void (__stdcall *PFN##_fn) _arg;                
  140.             ((PFN##_fn)pfn) _nargs;                                 
  141.         }                                                           
  142.     }                                                               
  143. // IE4 Shell Integrated Explorer called ShellDDEInit in shdocvw to
  144. // set up DDE. Forward this call to SHELL32/SHDOC401 appropriately.
  145. DELAY_LOAD_SHDOC401_VOID(ShellDDEInit, 188,
  146.                          (BOOL fInit),
  147.                          (fInit));
  148. DELAY_LOAD_SHDOC401(HANDLE, NULL,
  149.                     SHCreateDesktop, 200,
  150.                     (IDeskTray* pdtray),
  151.                     (pdtray));
  152. DELAY_LOAD_SHDOC401(BOOL, FALSE,
  153.                     SHDesktopMessageLoop, 201,
  154.                     (HANDLE hDesktop),
  155.                     (hDesktop));
  156. // This may not have been used in IE4
  157. DELAY_LOAD_SHDOC401(BOOL, FALSE,
  158.                     DDEHandleViewFolderNotify, 202,
  159.                     (IShellBrowser* psb, HWND hwnd, LPNMVIEWFOLDER lpnm),
  160.                     (psb, hwnd, lpnm));
  161. DELAY_LOAD_SHDOC401(LPNMVIEWFOLDER, NULL,
  162.                     DDECreatePostNotify, 82,
  163.                    (LPNMVIEWFOLDER pnm), 
  164.                    (pnm));
  165.                     
  166.