Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
6.2 KiB

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