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.

197 lines
8.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 "private.h"
  18. #include <winsock.h>
  19. #pragma warning(disable:4229) // No warnings when modifiers used on data
  20. //----------------------------------------------------------------------------
  21. // Delay loading mechanism. [Stolen from shdocvw.]
  22. //
  23. // This allows you to write code as if you are
  24. // calling implicitly linked APIs, and yet have these APIs really be
  25. // explicitly linked. You can reduce the initial number of DLLs that
  26. // are loaded (load on demand) using this technique.
  27. //
  28. // Use the following macros to indicate which APIs/DLLs are delay-linked
  29. // and -loaded.
  30. //
  31. // DELAY_LOAD
  32. // DELAY_LOAD_HRESULT
  33. // DELAY_LOAD_SAFEARRAY
  34. // DELAY_LOAD_UINT
  35. // DELAY_LOAD_INT
  36. // DELAY_LOAD_VOID
  37. //
  38. // Use these macros for APIs that are exported by ordinal only.
  39. //
  40. // DELAY_LOAD_ORD
  41. // DELAY_LOAD_ORD_VOID
  42. //
  43. // Use these macros for APIs that only exist on the integrated-shell
  44. // installations (i.e., a new shell32 is on the system).
  45. //
  46. // DELAY_LOAD_SHELL
  47. // DELAY_LOAD_SHELL_HRESULT
  48. // DELAY_LOAD_SHELL_VOID
  49. //
  50. //----------------------------------------------------------------------------
  51. #define ENSURE_LOADED(_hinst, _dll, pszfn) (_hinst ? _hinst : (_hinst = LoadLibrary(#_dll)))
  52. #define DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, _err) \
  53. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  54. _ret __stdcall _fn _args \
  55. { \
  56. if (!ENSURE_LOADED(_hinst, _dll, #_fn)) \
  57. { \
  58. AssertMsg(_hinst != NULL, "LoadLibrary failed on " ## #_dll); \
  59. return (_ret)_err; \
  60. } \
  61. if (_pfn##_fn == NULL) \
  62. { \
  63. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, #_fn); \
  64. AssertMsg(_pfn##_fn != NULL, "GetProcAddress failed on " ## #_fn); \
  65. if (_pfn##_fn == NULL) \
  66. return (_ret)_err; \
  67. } \
  68. return _pfn##_fn _nargs; \
  69. }
  70. #define DELAY_LOAD_VOID(_hinst, _dll, _fn, _args, _nargs) \
  71. void __stdcall _fn _args \
  72. { \
  73. static void (* __stdcall _pfn##_fn) _args = NULL; \
  74. if (!ENSURE_LOADED(_hinst, _dll, #_fn)) \
  75. { \
  76. AssertMsg(_hinst != NULL, "LoadLibrary failed on " ## #_dll); \
  77. return; \
  78. } \
  79. if (_pfn##_fn == NULL) \
  80. { \
  81. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, #_fn); \
  82. AssertMsg(_pfn##_fn != NULL, "GetProcAddress failed on " ## #_fn); \
  83. if (_pfn##_fn == NULL) \
  84. return; \
  85. } \
  86. _pfn##_fn _nargs; \
  87. }
  88. #define DELAY_LOAD(_hinst, _dll, _ret, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, 0)
  89. #define DELAY_LOAD_HRESULT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, HRESULT, _fn, _args, _nargs, E_FAIL)
  90. #define DELAY_LOAD_SAFEARRAY(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, SAFEARRAY *, _fn, _args, _nargs, NULL)
  91. #define DELAY_LOAD_DWORD(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, DWORD, _fn, _args, _nargs, 0)
  92. #define DELAY_LOAD_UINT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, UINT, _fn, _args, _nargs, 0)
  93. #define DELAY_LOAD_INT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, INT, _fn, _args, _nargs, 0)
  94. #define DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) \
  95. _ret __stdcall _fn _args \
  96. { \
  97. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  98. if (!ENSURE_LOADED(_hinst, _dll, "(ordinal " ## #_ord ## ")")) \
  99. { \
  100. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  101. return (_ret)_err; \
  102. } \
  103. if (_pfn##_fn == NULL) \
  104. { \
  105. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, (LPSTR) _ord); \
  106. \
  107. /* GetProcAddress always returns non-NULL, even for bad ordinals. \
  108. But do the check anyways... */ \
  109. \
  110. if (_pfn##_fn == NULL) \
  111. return (_ret)_err; \
  112. } \
  113. return _pfn##_fn _nargs; \
  114. }
  115. #define DELAY_LOAD_ORD_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) \
  116. void __stdcall _fn _args \
  117. { \
  118. static void (* __stdcall _pfn##_fn) _args = NULL; \
  119. if (!ENSURE_LOADED(_hinst, _dll, "(ordinal " ## #_ord ## ")")) \
  120. { \
  121. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  122. return; \
  123. } \
  124. if (_pfn##_fn == NULL) \
  125. { \
  126. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, (LPSTR) _ord); \
  127. \
  128. /* GetProcAddress always returns non-NULL, even for bad ordinals. \
  129. But do the check anyways... */ \
  130. \
  131. if (_pfn##_fn == NULL) \
  132. return; \
  133. } \
  134. _pfn##_fn _nargs; \
  135. }
  136. #define DELAY_LOAD_ORD(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  137. //
  138. // And now the DLLs which are delay loaded
  139. //
  140. // --------- OLEAUT32.DLL ---------------
  141. HINSTANCE g_hinstOLEAUT32 = NULL;
  142. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, RegisterTypeLib,
  143. (ITypeLib *ptlib, OLECHAR *szFullPath, OLECHAR *szHelpDir), (ptlib, szFullPath, szHelpDir));
  144. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, LoadTypeLib,
  145. (const OLECHAR *szFile, ITypeLib **pptlib), (szFile, pptlib));
  146. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, CreateErrorInfo,
  147. (ICreateErrorInfo **pperrinfo), (pperrinfo));
  148. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, SetErrorInfo,
  149. (unsigned long dwReserved, IErrorInfo*perrinfo), (dwReserved, perrinfo));
  150. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, LoadRegTypeLib,
  151. (REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **pptlib),
  152. (rguid, wVerMajor, wVerMinor, lcid, pptlib));
  153. DELAY_LOAD(g_hinstOLEAUT32, OLEAUT32.DLL, BSTR, SysAllocString, (const OLECHAR*pch), (pch));
  154. DELAY_LOAD(g_hinstOLEAUT32, OLEAUT32.DLL, BSTR, SysAllocStringLen,
  155. (const OLECHAR*pch, unsigned int i), (pch, i));
  156. DELAY_LOAD(g_hinstOLEAUT32, OLEAUT32.DLL, BSTR, SysAllocStringByteLen,
  157. (LPCSTR psz, UINT i), (psz, i));
  158. DELAY_LOAD_UINT(g_hinstOLEAUT32, OLEAUT32.DLL, SysStringLen, (BSTR bstr), (bstr));
  159. DELAY_LOAD_UINT(g_hinstOLEAUT32, OLEAUT32.DLL, SysStringByteLen, (BSTR bstr), (bstr));
  160. DELAY_LOAD_VOID(g_hinstOLEAUT32, OLEAUT32.DLL, SysFreeString, (BSTR bs), (bs));
  161. DELAY_LOAD_VOID(g_hinstOLEAUT32, OLEAUT32.DLL, VariantInit, (VARIANTARG *pvarg), (pvarg));
  162. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, VariantCopy,
  163. (VARIANTARG *pvargDest, VARIANTARG *pvargSrc), (pvargDest, pvargSrc));
  164. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, VariantChangeType,
  165. (VARIANTARG *pvargDest, VARIANTARG *pvargSrc, unsigned short wFlags, VARTYPE vt),
  166. (pvargDest, pvargSrc, wFlags, vt));
  167. DELAY_LOAD_HRESULT(g_hinstOLEAUT32, OLEAUT32.DLL, VariantClear, (VARIANTARG *pvarg), (pvarg));
  168. #pragma warning(default:4229)