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.

169 lines
7.1 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997
  5. //
  6. // File:
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History:
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "stdinc.h"
  18. #pragma warning(disable:4229) // No warnings when modifiers used on data
  19. //----------------------------------------------------------------------------
  20. // Delay loading mechanism. [Stolen from shdocvw.]
  21. //
  22. // This allows you to write code as if you are
  23. // calling implicitly linked APIs, and yet have these APIs really be
  24. // explicitly linked. You can reduce the initial number of DLLs that
  25. // are loaded (load on demand) using this technique.
  26. //
  27. // Use the following macros to indicate which APIs/DLLs are delay-linked
  28. // and -loaded.
  29. //
  30. // DELAY_LOAD
  31. // DELAY_LOAD_HRESULT
  32. // DELAY_LOAD_SAFEARRAY
  33. // DELAY_LOAD_UINT
  34. // DELAY_LOAD_INT
  35. // DELAY_LOAD_VOID
  36. //
  37. // Use these macros for APIs that are exported by ordinal only.
  38. //
  39. // DELAY_LOAD_ORD
  40. // DELAY_LOAD_ORD_VOID
  41. //
  42. // Use these macros for APIs that only exist on the integrated-shell
  43. // installations (i.e., a new shell32 is on the system).
  44. //
  45. // DELAY_LOAD_SHELL
  46. // DELAY_LOAD_SHELL_HRESULT
  47. // DELAY_LOAD_SHELL_VOID
  48. //
  49. //----------------------------------------------------------------------------
  50. #define ENSURE_LOADED(_hinst, _dll, pszfn) (_hinst ? TRUE : NULL!=(_hinst = LoadLibraryA(#_dll)))
  51. #define DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, _err) \
  52. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  53. _ret __stdcall _fn _args \
  54. { \
  55. if (!ENSURE_LOADED(_hinst, _dll, #_fn)) \
  56. { \
  57. AssertMsg((BOOL)_hinst, "LoadLibrary failed on " ## #_dll); \
  58. return (_ret)_err; \
  59. } \
  60. if (_pfn##_fn == NULL) \
  61. { \
  62. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, #_fn); \
  63. AssertMsg((BOOL)_pfn##_fn, "GetProcAddress failed on " ## #_fn); \
  64. if (_pfn##_fn == NULL) \
  65. return (_ret)_err; \
  66. } \
  67. return _pfn##_fn _nargs; \
  68. }
  69. #define DELAY_LOAD_VOID(_hinst, _dll, _fn, _args, _nargs) \
  70. void __stdcall _fn _args \
  71. { \
  72. static void (* __stdcall _pfn##_fn) _args = NULL; \
  73. if (!ENSURE_LOADED(_hinst, _dll, #_fn)) \
  74. { \
  75. AssertMsg((BOOL)_hinst, "LoadLibrary failed on " ## #_dll); \
  76. return; \
  77. } \
  78. if (_pfn##_fn == NULL) \
  79. { \
  80. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, #_fn); \
  81. AssertMsg((BOOL)_pfn##_fn, "GetProcAddress failed on " ## #_fn); \
  82. if (_pfn##_fn == NULL) \
  83. return; \
  84. } \
  85. _pfn##_fn _nargs; \
  86. }
  87. #define DELAY_LOAD(_hinst, _dll, _ret, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, 0)
  88. #define DELAY_LOAD_HRESULT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, HRESULT, _fn, _args, _nargs, E_FAIL)
  89. #define DELAY_LOAD_SAFEARRAY(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, SAFEARRAY *, _fn, _args, _nargs, NULL)
  90. #define DELAY_LOAD_DWORD(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, DWORD, _fn, _args, _nargs, 0)
  91. #define DELAY_LOAD_UINT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, UINT, _fn, _args, _nargs, 0)
  92. #define DELAY_LOAD_INT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, INT, _fn, _args, _nargs, 0)
  93. #define DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) \
  94. _ret __stdcall _fn _args \
  95. { \
  96. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  97. if (!ENSURE_LOADED(_hinst, _dll, "(ordinal " ## #_ord ## ")")) \
  98. { \
  99. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  100. return (_ret)_err; \
  101. } \
  102. if (_pfn##_fn == NULL) \
  103. { \
  104. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, (LPSTR) _ord); \
  105. \
  106. /* GetProcAddress always returns non-NULL, even for bad ordinals. \
  107. But do the check anyways... */ \
  108. \
  109. if (_pfn##_fn == NULL) \
  110. return (_ret)_err; \
  111. } \
  112. return _pfn##_fn _nargs; \
  113. }
  114. #define DELAY_LOAD_ORD_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) \
  115. void __stdcall _fn _args \
  116. { \
  117. static void (* __stdcall _pfn##_fn) _args = NULL; \
  118. if (!ENSURE_LOADED(_hinst, _dll, "(ordinal " ## #_ord ## ")")) \
  119. { \
  120. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  121. return; \
  122. } \
  123. if (_pfn##_fn == NULL) \
  124. { \
  125. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, (LPSTR) _ord); \
  126. \
  127. /* GetProcAddress always returns non-NULL, even for bad ordinals. \
  128. But do the check anyways... */ \
  129. \
  130. if (_pfn##_fn == NULL) \
  131. return; \
  132. } \
  133. _pfn##_fn _nargs; \
  134. }
  135. #define DELAY_LOAD_ORD(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  136. //
  137. // And now the DLLs which are delay loaded
  138. //
  139. // --------- SHDOCVW.DLL ---------------
  140. // NOTE: These may not remain private.
  141. HINSTANCE g_hinstSHDOCVW = NULL;
  142. DELAY_LOAD_ORD(g_hinstSHDOCVW, SHDOCVW.DLL, DWORD, SHRestricted2A, 158,
  143. (BROWSER_RESTRICTIONS rest, LPCSTR pszUrl, DWORD dwReserved), (rest, pszUrl, dwReserved));
  144. DELAY_LOAD_ORD(g_hinstSHDOCVW, SHDOCVW.DLL, DWORD, SHRestricted2W, 159,
  145. (BROWSER_RESTRICTIONS rest, LPCWSTR pwzUrl, DWORD dwReserved), (rest, pwzUrl, dwReserved));
  146. DELAY_LOAD_ORD_ERR(g_hinstSHDOCVW, SHDOCVW.DLL, HRESULT, CDDEAuto_Navigate, 162,
  147. (BSTR str, HWND* phwnd, long lTransID), (str, phwnd, lTransID), E_FAIL);
  148. #ifdef UNIX
  149. DELAY_LOAD_ORD(g_hinstSHDOCVW, SHDOCVW.DLL, HRESULT, SHAddSubscribeFavorite,163, (HWND hwnd, LPCWSTR pwszURL, LPCWSTR pwszName, DWORD dwFlags, SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO* pInfo), (hwnd, pwszURL, pwszName, dwFlags, subsType, pInfo));
  150. #endif /* UNIX */
  151. #pragma warning(default:4229)