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.

208 lines
7.8 KiB

  1. #include <windows.h>
  2. #include "netmpr.h"
  3. #include "pwlapi.h"
  4. #include <pcerr.h>
  5. /* Avoid inconsistent-DLL-linkage warnings on shell32 and comctl32 APIs. */
  6. #undef DECLSPEC_IMPORT
  7. #define DECLSPEC_IMPORT
  8. #include <prsht.h>
  9. #include <shellapi.h>
  10. #pragma warning(disable:4229) // No warnings when modifiers used on data
  11. // Delay loading mechanism. This allows you to write code as if you are
  12. // calling implicitly linked APIs, and yet have these APIs really be
  13. // explicitly linked. You can reduce the initial number of DLLs that
  14. // are loaded (load on demand) using this technique.
  15. //
  16. // Use the following macros to indicate which APIs/DLLs are delay-linked
  17. // and -loaded.
  18. //
  19. // DELAY_LOAD
  20. // DELAY_LOAD_HRESULT
  21. // DELAY_LOAD_SAFEARRAY
  22. // DELAY_LOAD_UINT
  23. // DELAY_LOAD_INT
  24. // DELAY_LOAD_VOID
  25. //
  26. // Use these macros for APIs that are exported by ordinal only.
  27. //
  28. // DELAY_LOAD_ORD
  29. // DELAY_LOAD_ORD_VOID
  30. //
  31. // Use these macros for APIs that only exist on the integrated-shell
  32. // installations (i.e., a new shell32 is on the system).
  33. //
  34. // DELAY_LOAD_SHELL
  35. // DELAY_LOAD_SHELL_HRESULT
  36. // DELAY_LOAD_SHELL_VOID
  37. //
  38. //
  39. // These macros produce code that looks like
  40. #if 0
  41. BOOL GetOpenFileNameA(LPOPENFILENAME pof)
  42. {
  43. static BOOL (*pfnGetOpenFileNameA)(LPOPENFILENAME pof);
  44. _GetProcFromDLL(&g_hinstCOMDLG32, "COMDLG32.DLL", "GetOpenFileNameA", &pfnGetoptnFileNameA);
  45. if (pfnGetOpenFileNameA)
  46. return pfnGetOpenFileNameA(pof);
  47. return -1;
  48. }
  49. #endif
  50. /**********************************************************************/
  51. void _GetProcFromDLL(HINSTANCE* phinst, LPCSTR pszDLL, FARPROC* ppfn, LPCSTR pszProc)
  52. {
  53. // If it's already loaded, return.
  54. if (*ppfn) {
  55. return;
  56. }
  57. if (*phinst == NULL) {
  58. *phinst = LoadLibrary(pszDLL);
  59. if (*phinst == NULL) {
  60. return;
  61. }
  62. }
  63. *ppfn = GetProcAddress(*phinst, pszProc);
  64. }
  65. #define DELAY_LOAD_MAP(_hinst, _dll, _ret, _fnpriv, _fn, _args, _nargs, _err) \
  66. _ret __stdcall _fnpriv _args \
  67. { \
  68. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  69. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, #_fn); \
  70. if (_pfn##_fn) \
  71. return _pfn##_fn _nargs; \
  72. return (_ret)_err; \
  73. }
  74. #define DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, _err) DELAY_LOAD_MAP(_hinst, _dll, _ret, _fn, _fn, _args, _nargs, _err)
  75. #define DELAY_LOAD(_hinst, _dll, _ret, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, 0)
  76. #define DELAY_LOAD_HRESULT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, HRESULT, _fn, _args, _nargs, E_FAIL)
  77. #define DELAY_LOAD_SAFEARRAY(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, SAFEARRAY *, _fn, _args, _nargs, NULL)
  78. #define DELAY_LOAD_DWORD(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, DWORD, _fn, _args, _nargs, 0)
  79. #define DELAY_LOAD_UINT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, UINT, _fn, _args, _nargs, 0)
  80. #define DELAY_LOAD_INT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, INT, _fn, _args, _nargs, 0)
  81. #define DELAY_MAP_DWORD(_hinst, _dll, _fnpriv, _fn, _args, _nargs) DELAY_LOAD_MAP(_hinst, _dll, DWORD, _fnpriv, _fn, _args, _nargs, 0)
  82. #define DELAY_LOAD_VOID(_hinst, _dll, _fn, _args, _nargs) \
  83. void __stdcall _fn _args \
  84. { \
  85. static void (* __stdcall _pfn##_fn) _args = NULL; \
  86. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, #_fn); \
  87. if (_pfn##_fn) \
  88. _pfn##_fn _nargs; \
  89. return; \
  90. }
  91. //
  92. // For private entrypoints exported by ordinal.
  93. //
  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. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
  99. if (_pfn##_fn) \
  100. return _pfn##_fn _nargs; \
  101. return (_ret)_err; \
  102. }
  103. #define DELAY_LOAD_ORD(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  104. #define DELAY_LOAD_ORD_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) \
  105. void __stdcall _fn _args \
  106. { \
  107. static void (* __stdcall _pfn##_fn) _args = NULL; \
  108. _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
  109. if (_pfn##_fn) \
  110. _pfn##_fn _nargs; \
  111. return; \
  112. }
  113. /**********************************************************************/
  114. /**********************************************************************/
  115. // --------- MSPWL32.DLL ---------------
  116. HINSTANCE g_hinstMSPWL32 = NULL;
  117. #define DELAY_LOAD_PWL(_fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(g_hinstMSPWL32, mspwl32.dll, APIERR, _fn, _ord, _args, _nargs, IERR_CachingDisabled)
  118. DELAY_LOAD_PWL(OpenPasswordCache, 10,
  119. (LPHPWL lphCache,const CHAR *pszUsername,const CHAR *pszPassword,BOOL fWritable),
  120. (lphCache, pszUsername, pszPassword, fWritable));
  121. DELAY_LOAD_PWL(ClosePasswordCache, 11,
  122. (HPWL hCache, BOOL fDiscardMemory), (hCache, fDiscardMemory));
  123. DELAY_LOAD_PWL(CreatePasswordCache, 12,
  124. (LPHPWL lphCache,const CHAR *pszUsername,const CHAR *pszPassword),
  125. (lphCache, pszUsername, pszPassword));
  126. DELAY_LOAD_PWL(DeletePasswordCache, 22,
  127. (const CHAR *pszUsername), (pszUsername));
  128. DELAY_LOAD_PWL(FindCacheResource, 16,
  129. (HPWL hCache,const CHAR *pbResource,WORD cbResource,CHAR *pbBuffer,WORD cbBuffer,UCHAR nType),
  130. (hCache, pbResource, cbResource, pbBuffer, cbBuffer, nType));
  131. DELAY_LOAD_PWL(DeleteCacheResource, 17,
  132. (HPWL hCache,const CHAR *pbResource,WORD cbResource,UCHAR nType),
  133. (hCache, pbResource, cbResource, nType));
  134. DELAY_LOAD_PWL(AddCacheResource, 18,
  135. (HPWL hCache,const CHAR *pbResource,WORD cbResource,const CHAR *pbPassword,WORD cbPassword,UCHAR nType,UINT fnFlags),
  136. (hCache, pbResource, cbResource, pbPassword, cbPassword, nType, fnFlags));
  137. DELAY_LOAD_PWL(SetCachePassword, 21,
  138. (HPWL hCache, const CHAR *pszNewPassword),
  139. (hCache, pszNewPassword));
  140. // --------- MPR.DLL ---------------
  141. HINSTANCE g_hinstMPR = NULL;
  142. DELAY_LOAD_ERR(g_hinstMPR, mpr.dll, DWORD, WNetCachePassword,
  143. (LPSTR pbResource, WORD cbResource, LPSTR pbPassword, WORD cbPassword, BYTE nType, UINT fnFlags),
  144. (pbResource, cbResource, pbPassword, cbPassword, nType, fnFlags),
  145. WN_CANCEL);
  146. DELAY_LOAD_ERR(g_hinstMPR, mpr.dll, DWORD, WNetGetCachedPassword,
  147. (LPSTR pbResource, WORD cbResource, LPSTR pbPassword, LPWORD pcbPassword, BYTE nType),
  148. (pbResource, cbResource, pbPassword, pcbPassword, nType),
  149. WN_CANCEL);
  150. DELAY_LOAD_ERR(g_hinstMPR, mpr.dll, DWORD, WNetRemoveCachedPassword,
  151. (LPSTR pbResource, WORD cbResource, BYTE nType),
  152. (pbResource, cbResource, nType),
  153. WN_CANCEL);
  154. // --------- COMCTL32.DLL ---------------
  155. HINSTANCE g_hinstCOMCTL32 = NULL;
  156. DELAY_LOAD(g_hinstCOMCTL32, comctl32.dll, HPROPSHEETPAGE, CreatePropertySheetPageA,
  157. (LPCPROPSHEETPAGEA lpPage), (lpPage));
  158. DELAY_LOAD(g_hinstCOMCTL32, comctl32.dll, INT_PTR, PropertySheetA,
  159. (LPCPROPSHEETHEADERA lpHdr), (lpHdr));
  160. // --------- SHELL32.DLL ----------------
  161. HINSTANCE g_hinstSHELL32 = NULL;
  162. #ifdef UNICODE
  163. DELAY_LOAD(g_hinstSHELL32, SHELL32.DLL, BOOL, ShellExecuteExW,
  164. (LPSHELLEXECUTEINFOW lpExecInfo), (lpExecInfo));
  165. #else
  166. DELAY_LOAD(g_hinstSHELL32, SHELL32.DLL, BOOL, ShellExecuteExA,
  167. (LPSHELLEXECUTEINFOA lpExecInfo), (lpExecInfo));
  168. #endif
  169. DELAY_LOAD_ORD_VOID(g_hinstSHELL32, SHELL32.DLL, SHFlushSFCache, 526, (), ());
  170. #pragma warning(default:4229)