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.

247 lines
9.6 KiB

  1. /*****************************************************************************\
  2. FILE: dllload.cpp
  3. DESCRIPTION:
  4. Delay load functions that we want to use when they are available.
  5. BryanSt (Bryan Starbuck) - Created
  6. Copyright (c) 1998-2000 Microsoft Corporation
  7. \*****************************************************************************/
  8. #include "priv.h"
  9. #include <pstore.h>
  10. #include <wininet.h>
  11. #pragma warning(disable:4229) // No warnings when modifiers used on data
  12. // Delay loading mechanism. This allows you to write code as if you are
  13. // calling implicitly linked APIs, and yet have these APIs really be
  14. // explicitly linked. You can reduce the initial number of DLLs that
  15. // are loaded (load on demand) using this technique.
  16. //
  17. // Use the following macros to indicate which APIs/DLLs are delay-linked
  18. // and -loaded.
  19. //
  20. // DELAY_LOAD
  21. // DELAY_LOAD_HRESULT
  22. // DELAY_LOAD_SAFEARRAY
  23. // DELAY_LOAD_UINT
  24. // DELAY_LOAD_INT
  25. // DELAY_LOAD_VOID
  26. //
  27. // Use these macros for APIs that are exported by ordinal only.
  28. //
  29. // DELAY_LOAD_ORD
  30. // DELAY_LOAD_ORD_VOID
  31. //
  32. // Use these macros for APIs that only exist on the integrated-shell
  33. // installations (i.e., a new shell32 is on the system).
  34. //
  35. // DELAY_LOAD_SHELL
  36. // DELAY_LOAD_SHELL_HRESULT
  37. // DELAY_LOAD_SHELL_VOID
  38. //
  39. //
  40. /**********************************************************************/
  41. void _GetProcFromDLL(HINSTANCE* phinst, LPCSTR pszDLL, FARPROC* ppfn, LPCSTR pszProc)
  42. {
  43. #ifdef DEBUG
  44. CHAR szProcD[MAX_PATH];
  45. if (HIWORD(pszProc)) {
  46. lstrcpynA(szProcD, pszProc, ARRAYSIZE(szProcD));
  47. } else {
  48. wnsprintfA(szProcD, ARRAYSIZE(szProcD), "(ordinal %d)", LOWORD(pszProc));
  49. }
  50. #endif // DEBUG
  51. // If it's already loaded, return.
  52. if (*ppfn) {
  53. return;
  54. }
  55. if (*phinst == NULL) {
  56. #ifdef DEBUG
  57. TraceMsg(TF_FTP_DLLLOADING, "DLLLOAD: Loading %hs for the first time for %hs", pszDLL, szProcD);
  58. /*
  59. if (g_dwBreakFlags & TF_FTP_DLLLOAD_BREAK)
  60. {
  61. DebugBreak();
  62. }
  63. */
  64. #endif // DEBUG
  65. *phinst = LoadLibraryA(pszDLL);
  66. if (*phinst == NULL) {
  67. return;
  68. }
  69. }
  70. #ifdef DEBUG
  71. TraceMsg(TF_FTP_DLLLOADING, "DLLLOAD: GetProc'ing %hs from %hs for the first time", pszDLL, szProcD);
  72. #endif // DEBUG
  73. *ppfn = GetProcAddress(*phinst, pszProc);
  74. }
  75. /*----------------------------------------------------------
  76. Purpose: Performs a loadlibrary on the DLL only if the machine
  77. has the integrated shell installation.
  78. */
  79. void _SHGetProcFromDLL(HINSTANCE* phinst, LPCSTR pszDLL, FARPROC* ppfn, LPCSTR pszProc)
  80. {
  81. _GetProcFromDLL(phinst, pszDLL, ppfn, pszProc);
  82. }
  83. #define DELAY_LOAD_MAP(_hinst, _dll, _ret, _fnpriv, _fn, _args, _nargs, _err) \
  84. _ret __stdcall _fnpriv _args \
  85. { \
  86. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  87. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, #_fn); \
  88. if (_pfn##_fn) \
  89. return _pfn##_fn _nargs; \
  90. return (_ret)_err; \
  91. }
  92. #define DELAY_MAP_HRESULT(_hinst, _dll, _fnpriv, _fn, _args, _nargs) DELAY_LOAD_MAP(_hinst, _dll, HRESULT, _fnpriv, _fn, _args, _nargs, E_FAIL)
  93. #define DELAY_MAP_DWORD(_hinst, _dll, _fnpriv, _fn, _args, _nargs) DELAY_LOAD_MAP(_hinst, _dll, DWORD, _fnpriv, _fn, _args, _nargs, 0)
  94. #define DELAY_MAP_BOOL(_hinst, _dll, _fnpriv, _fn, _args, _nargs) DELAY_LOAD_MAP(_hinst, _dll, BOOL, _fnpriv, _fn, _args, _nargs, 0)
  95. #define DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, _err) DELAY_LOAD_MAP(_hinst, _dll, _ret, _fn, _fn, _args, _nargs, _err)
  96. #define DELAY_LOAD(_hinst, _dll, _ret, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, 0)
  97. #define DELAY_LOAD_HRESULT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, HRESULT, _fn, _args, _nargs, E_FAIL)
  98. #define DELAY_LOAD_SAFEARRAY(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, SAFEARRAY *, _fn, _args, _nargs, NULL)
  99. #define DELAY_LOAD_DWORD(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, DWORD, _fn, _args, _nargs, 0)
  100. #define DELAY_LOAD_BOOL(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, BOOL, _fn, _args, _nargs, 0)
  101. #define DELAY_LOAD_UINT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, UINT, _fn, _args, _nargs, 0)
  102. #define DELAY_LOAD_INT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, INT, _fn, _args, _nargs, 0)
  103. #define DELAY_LOAD_VOID(_hinst, _dll, _fn, _args, _nargs) \
  104. void __stdcall _fn _args \
  105. { \
  106. static void (* __stdcall _pfn##_fn) _args = NULL; \
  107. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, #_fn); \
  108. if (_pfn##_fn) \
  109. _pfn##_fn _nargs; \
  110. return; \
  111. }
  112. //
  113. // For private entrypoints exported by ordinal.
  114. //
  115. #define DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) \
  116. _ret __stdcall _fn _args \
  117. { \
  118. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  119. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
  120. if (_pfn##_fn) \
  121. return _pfn##_fn _nargs; \
  122. return (_ret)_err; \
  123. }
  124. #define DELAY_LOAD_ORD(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  125. #define DELAY_LOAD_ORD_HRESULT(_hinst, _dll, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD(_hinst, _dll, HRESULT, _fn, _ord, _args, _nargs)
  126. #define DELAY_LOAD_ORD_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) \
  127. void __stdcall _fn _args \
  128. { \
  129. static void (* __stdcall _pfn##_fn) _args = NULL; \
  130. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
  131. if (_pfn##_fn) \
  132. _pfn##_fn _nargs; \
  133. return; \
  134. }
  135. //
  136. // Private exports by ordinal for integrated-shell installs
  137. //
  138. #define DELAY_LOAD_SHELL_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) \
  139. _ret __stdcall _fn _args \
  140. { \
  141. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  142. _SHGetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
  143. if (_pfn##_fn) \
  144. return _pfn##_fn _nargs; \
  145. return (_ret)_err; \
  146. }
  147. #define DELAY_LOAD_SHELL(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_SHELL_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  148. #define DELAY_LOAD_SHELL_HRESULT(_hinst, _dll, _fn, _ord, _args, _nargs) DELAY_LOAD_SHELL_ERR(_hinst, _dll, HRESULT, _fn, _ord, _args, _nargs, E_FAIL)
  149. #define DELAY_LOAD_SHELL_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) \
  150. void __stdcall _fn _args \
  151. { \
  152. static void (* __stdcall _pfn##_fn) _args = NULL; \
  153. _SHGetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
  154. if (_pfn##_fn) \
  155. _pfn##_fn _nargs; \
  156. return; \
  157. }
  158. /**********************************************************************/
  159. /**********************************************************************/
  160. // --------- MLANG.DLL ---------------
  161. HINSTANCE g_hinstMLANG = NULL;
  162. DELAY_LOAD_HRESULT(g_hinstMLANG, MLANG.DLL, ConvertINetMultiByteToUnicode,
  163. (LPDWORD lpdwMode, DWORD dwEncoding, LPCSTR lpSrcStr, LPINT lpnMultiCharCount, LPWSTR lpDstStr, LPINT lpnWideCharCount),
  164. (lpdwMode, dwEncoding, lpSrcStr, lpnMultiCharCount, lpDstStr, lpnWideCharCount));
  165. DELAY_LOAD_HRESULT(g_hinstMLANG, MLANG.DLL, ConvertINetUnicodeToMultiByte,
  166. (LPDWORD lpdwMode, DWORD dwEncoding, LPCWSTR lpSrcStr, LPINT lpnWideCharCount, LPSTR lpDstStr, LPINT lpnMultiCharCount),
  167. (lpdwMode, dwEncoding, lpSrcStr, lpnWideCharCount, lpDstStr, lpnMultiCharCount));
  168. DELAY_LOAD_HRESULT(g_hinstMLANG, MLANG.DLL, LcidToRfc1766W,
  169. (LCID Locale, LPWSTR pszRfc1766, int nChar),
  170. (Locale, pszRfc1766, nChar));
  171. // --------- MSHTML.DLL ---------------
  172. HINSTANCE g_hinstMSHTML = NULL;
  173. DELAY_LOAD_HRESULT(g_hinstMSHTML, MSHTML.DLL, ShowHTMLDialog,
  174. (HWND hwnd, IMoniker * pmk, VARIANT * pvarArgIn, LPWSTR pchOptions, VARIANT * pvarArgOut),
  175. (hwnd, pmk, pvarArgIn, pchOptions, pvarArgOut));
  176. // --------- CRYPT32.DLL ---------------
  177. HINSTANCE g_hinstCRYPT32 = NULL;
  178. DELAY_MAP_BOOL(g_hinstCRYPT32, CRYPT32.DLL, _CryptProtectData, CryptProtectData,
  179. (DATA_BLOB *pDataIn, LPCWSTR pszDataDescr, DATA_BLOB * pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut),
  180. (pDataIn, pszDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut));
  181. DELAY_MAP_BOOL(g_hinstCRYPT32, CRYPT32.DLL, _CryptUnprotectData, CryptUnprotectData,
  182. (DATA_BLOB *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB * pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut),
  183. (pDataIn, ppszDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut));
  184. // --------- SHELL32.DLL ---------------
  185. HINSTANCE g_hinstSHELL32 = NULL;
  186. DELAY_LOAD_ORD_HRESULT(g_hinstSHELL32, SHELL32.DLL, _SHCreateShellFolderView, SHCreateShellFolderViewORD,
  187. (const SFV_CREATE* pcsfv, LPSHELLVIEW FAR* ppsv),
  188. (pcsfv, ppsv));
  189. DELAY_MAP_HRESULT(g_hinstSHELL32, SHELL32.DLL, _SHPathPrepareForWriteW, SHPathPrepareForWriteW,
  190. (HWND hwnd, IUnknown *punkEnableModless, LPCWSTR pwzPath, DWORD dwFlags),
  191. (hwnd, punkEnableModless, pwzPath, dwFlags));
  192. #pragma warning(default:4229)