Leaked source code of windows server 2003
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.

487 lines
12 KiB

  1. /*
  2. ** d e m a n d . c p p
  3. **
  4. ** Purpose: implement the loader functions for defer/demand -loaded libraries
  5. **
  6. ** Creators: jimsch, brimo, t-erikne
  7. ** Created: 5/15/97
  8. **
  9. ** Copyright (C) Microsoft Corp. 1997
  10. */
  11. #include "_apipch.h"
  12. // W4 stuff
  13. #pragma warning(disable: 4201) // nameless struct/union
  14. #pragma warning(disable: 4514) // unreferenced inline function removed
  15. #include <wincrypt.h>
  16. #define IMPLEMENT_LOADER_FUNCTIONS
  17. #include "demand.h"
  18. ////////////////////////////////////////////////////////////////////////////
  19. //
  20. // Macros
  21. #define CRIT_GET_PROC_ADDR(h, fn, temp) \
  22. temp = (TYP_##fn) GetProcAddress(h, #fn); \
  23. if (temp) \
  24. VAR_##fn = temp; \
  25. else \
  26. { \
  27. AssertSz(VAR_##fn TEXT(" failed to load")); \
  28. goto error; \
  29. }
  30. #define RESET(fn) \
  31. VAR_##fn = LOADER_##fn;
  32. #define GET_PROC_ADDR(h, fn) \
  33. VAR_##fn = (TYP_##fn) GetProcAddress(h, #fn); \
  34. Assert(VAR_##fn != NULL); \
  35. if(NULL == VAR_##fn ) { \
  36. VAR_##fn = LOADER_##fn; \
  37. }
  38. #define GET_PROC_ADDR3(h, fn, varname) \
  39. VAR_##varname = (TYP_##varname) GetProcAddress(h, #fn); \
  40. Assert(VAR_##varname != NULL);
  41. #define GET_PROC_ADDR_FLAG(h, fn, pflag) \
  42. VAR_##fn = (TYP_##fn) GetProcAddress(h, #fn); \
  43. *pflag = (VAR_##fn != NULL);
  44. ////////////////////////////////////////////////////////////////////////////
  45. //
  46. // Variables
  47. static HMODULE s_hCrypt = 0;
  48. static HMODULE s_hAdvApi = 0;
  49. static HMODULE s_hPstoreC = 0;
  50. static HMODULE s_hCryptDlg = 0;
  51. static HMODULE s_hWinTrust = 0;
  52. static HMODULE s_hVersion = 0;
  53. static HMODULE s_hImm32 = 0;
  54. static HMODULE s_hWininet = 0;
  55. static HMODULE s_hUrlmon = 0;
  56. static HMODULE s_hShlwapi = NULL;
  57. #ifdef USE_CRITSEC
  58. static CRITICAL_SECTION cs = {0};
  59. #endif
  60. #ifdef DEBUG
  61. static BOOL s_fInit = FALSE;
  62. #endif
  63. ////////////////////////////////////////////////////////////////////////////
  64. //
  65. // Management functions
  66. void InitDemandLoadedLibs()
  67. {
  68. #ifdef USE_CRITSEC
  69. InitializeCriticalSection(&cs);
  70. #endif
  71. #ifdef DEBUG
  72. s_fInit = TRUE;
  73. #endif
  74. }
  75. void FreeDemandLoadedLibs()
  76. {
  77. #ifdef USE_CRITSEC
  78. EnterCriticalSection(&cs);
  79. #endif
  80. if (s_hCrypt)
  81. FreeLibrary(s_hCrypt);
  82. if (s_hAdvApi)
  83. FreeLibrary(s_hAdvApi);
  84. if (s_hPstoreC)
  85. FreeLibrary(s_hPstoreC);
  86. if (s_hCryptDlg)
  87. FreeLibrary(s_hCryptDlg);
  88. if (s_hWinTrust)
  89. FreeLibrary(s_hWinTrust);
  90. if (s_hVersion)
  91. FreeLibrary(s_hVersion);
  92. if (s_hImm32)
  93. FreeLibrary(s_hImm32);
  94. if (s_hWininet)
  95. FreeLibrary(s_hWininet);
  96. if (s_hUrlmon)
  97. FreeLibrary(s_hUrlmon);
  98. if (s_hShlwapi)
  99. FreeLibrary(s_hShlwapi);
  100. #ifdef DEBUG
  101. s_fInit = FALSE;
  102. #endif
  103. #ifdef USE_CRITSEC
  104. LeaveCriticalSection(&cs);
  105. DeleteCriticalSection(&cs);
  106. #endif
  107. }
  108. ////////////////////////////////////////////////////////////////////////////
  109. //
  110. // Loader functions
  111. /* sample loader with critical proc addrs
  112. ** but not thread-safe
  113. BOOL DemandLoadFoo()
  114. {
  115. FARPROC fp;
  116. if (0 == g_hFoo)
  117. {
  118. g_hFoo = LoadLibrary("FOO.DLL");
  119. if (0 == g_hFoo)
  120. return FALSE;
  121. CRIT_GET_PROC_ADDR(NeededFunction1, fp);
  122. CRIT_GET_PROC_ADDR(NeededFunction2, fp);
  123. GET_PROC_ADDR(OptionalFunction);
  124. }
  125. return TRUE;
  126. error:
  127. FreeLibrary(g_hFoo);
  128. g_hFoo = NULL;
  129. RESET(NeededFunction1)
  130. RESET(NeededFunction2)
  131. RESET(OptionalFunction)
  132. return FALSE;
  133. }
  134. */
  135. ///////////////////////////////////////////////////////////////////////////
  136. ///////////////////////////////////////////////////////////////////////////
  137. BOOL DemandLoadCrypt32()
  138. {
  139. BOOL fRet = TRUE;
  140. Assert(s_fInit);
  141. #ifdef USE_CRITSEC
  142. EnterCriticalSection(&cs);
  143. #endif
  144. if (0 == s_hCrypt)
  145. {
  146. s_hCrypt = LoadLibrary(TEXT("CRYPT32.DLL"));
  147. AssertSz((NULL != s_hCrypt), TEXT("LoadLibrary failed on CRYPT32.DLL"));
  148. if (0 == s_hCrypt)
  149. fRet = FALSE;
  150. else
  151. {
  152. GET_PROC_ADDR(s_hCrypt, CertFreeCertificateContext)
  153. GET_PROC_ADDR(s_hCrypt, CertDuplicateCertificateContext)
  154. GET_PROC_ADDR(s_hCrypt, CertFindCertificateInStore)
  155. GET_PROC_ADDR(s_hCrypt, CertVerifyTimeValidity)
  156. GET_PROC_ADDR(s_hCrypt, CertOpenSystemStoreA)
  157. GET_PROC_ADDR(s_hCrypt, CertCloseStore)
  158. GET_PROC_ADDR(s_hCrypt, CertGetCertificateContextProperty)
  159. GET_PROC_ADDR(s_hCrypt, CertOpenStore)
  160. GET_PROC_ADDR(s_hCrypt, CertCompareCertificate)
  161. GET_PROC_ADDR(s_hCrypt, CryptMsgClose)
  162. GET_PROC_ADDR(s_hCrypt, CryptDecodeObjectEx)
  163. GET_PROC_ADDR(s_hCrypt, CryptMsgGetParam)
  164. GET_PROC_ADDR(s_hCrypt, CryptMsgUpdate)
  165. GET_PROC_ADDR(s_hCrypt, CryptMsgOpenToDecode)
  166. GET_PROC_ADDR(s_hCrypt, CertAddCertificateContextToStore)
  167. }
  168. }
  169. #ifdef USE_CRITSEC
  170. LeaveCriticalSection(&cs);
  171. #endif
  172. return fRet;
  173. }
  174. ///////////////////////////////////////////////////////////////////////////
  175. ///////////////////////////////////////////////////////////////////////////
  176. BOOL DemandLoadAdvApi32()
  177. {
  178. BOOL fRet = TRUE;
  179. Assert(s_fInit);
  180. #ifdef USE_CRITSEC
  181. EnterCriticalSection(&cs);
  182. #endif
  183. if (0 == s_hAdvApi)
  184. {
  185. s_hAdvApi = LoadLibrary(TEXT("ADVAPI32.DLL"));
  186. AssertSz((NULL != s_hAdvApi), TEXT("LoadLibrary failed on ADVAPI32.DLL"));
  187. if (0 == s_hAdvApi)
  188. fRet = FALSE;
  189. else
  190. {
  191. GET_PROC_ADDR(s_hAdvApi, CryptAcquireContextA)
  192. GET_PROC_ADDR(s_hAdvApi, CryptAcquireContextW)
  193. GET_PROC_ADDR(s_hAdvApi, CryptReleaseContext)
  194. }
  195. }
  196. #ifdef USE_CRITSEC
  197. LeaveCriticalSection(&cs);
  198. #endif
  199. return fRet;
  200. }
  201. ///////////////////////////////////////////////////////////////////////////
  202. ///////////////////////////////////////////////////////////////////////////
  203. BOOL DemandLoadPStoreC()
  204. {
  205. BOOL fRet = TRUE;
  206. Assert(s_fInit);
  207. #ifdef USE_CRITSEC
  208. EnterCriticalSection(&cs);
  209. #endif
  210. if (0 == s_hPstoreC)
  211. {
  212. s_hPstoreC = LoadLibrary(TEXT("PSTOREC.DLL"));
  213. AssertSz((NULL != s_hPstoreC), TEXT("LoadLibrary failed on PSTOREC.DLL"));
  214. if (0 == s_hPstoreC)
  215. fRet = FALSE;
  216. else
  217. {
  218. GET_PROC_ADDR(s_hPstoreC, PStoreCreateInstance)
  219. GET_PROC_ADDR(s_hPstoreC, PStoreEnumProviders)
  220. }
  221. }
  222. #ifdef USE_CRITSEC
  223. LeaveCriticalSection(&cs);
  224. #endif
  225. return fRet;
  226. }
  227. ///////////////////////////////////////////////////////////////////////////
  228. ///////////////////////////////////////////////////////////////////////////
  229. static BOOL s_fCertViewPropertiesCryptUIA = FALSE;
  230. BOOL DemandLoadCryptDlg()
  231. {
  232. BOOL fRet = TRUE;
  233. Assert(s_fInit);
  234. #ifdef USE_CRITSEC
  235. EnterCriticalSection(&cs);
  236. #endif
  237. if (0 == s_hCryptDlg)
  238. {
  239. s_hCryptDlg = LoadLibrary(TEXT("CRYPTDLG.DLL"));
  240. AssertSz((NULL != s_hCryptDlg), TEXT("LoadLibrary failed on CRYPTDLG.DLL"));
  241. if (0 == s_hCryptDlg)
  242. fRet = FALSE;
  243. else
  244. {
  245. GET_PROC_ADDR(s_hCryptDlg, GetFriendlyNameOfCertA)
  246. GET_PROC_ADDR(s_hCryptDlg, CertViewPropertiesA)
  247. }
  248. }
  249. #ifdef USE_CRITSEC
  250. LeaveCriticalSection(&cs);
  251. #endif
  252. return fRet;
  253. }
  254. BOOL CryptUIAvailable(void) {
  255. DemandLoadCryptDlg();
  256. return(s_fCertViewPropertiesCryptUIA);
  257. }
  258. ///////////////////////////////////////////////////////////////////////////
  259. ///////////////////////////////////////////////////////////////////////////
  260. BOOL DemandLoadWinTrust()
  261. {
  262. BOOL fRet = TRUE;
  263. Assert(s_fInit);
  264. #ifdef USE_CRITSEC
  265. EnterCriticalSection(&cs);
  266. #endif
  267. if (0 == s_hWinTrust)
  268. {
  269. s_hWinTrust = LoadLibrary(TEXT("WINTRUST.DLL"));
  270. AssertSz((NULL != s_hWinTrust), TEXT("LoadLibrary failed on WINTRUST.DLL"));
  271. if (0 == s_hWinTrust)
  272. fRet = FALSE;
  273. else
  274. {
  275. GET_PROC_ADDR(s_hWinTrust, WinVerifyTrust)
  276. }
  277. }
  278. #ifdef USE_CRITSEC
  279. LeaveCriticalSection(&cs);
  280. #endif
  281. return fRet;
  282. }
  283. ///////////////////////////////////////////////////////////////////////////
  284. ///////////////////////////////////////////////////////////////////////////
  285. BOOL DemandLoadVersion()
  286. {
  287. BOOL fRet = TRUE;
  288. Assert(s_fInit);
  289. #ifdef USE_CRITSEC
  290. EnterCriticalSection(&cs);
  291. #endif
  292. if (0 == s_hVersion)
  293. {
  294. s_hVersion = LoadLibrary(TEXT("VERSION.DLL"));
  295. AssertSz((NULL != s_hVersion), TEXT("LoadLibrary failed on VERSION.DLL"));
  296. if (0 == s_hVersion)
  297. fRet = FALSE;
  298. else
  299. {
  300. GET_PROC_ADDR(s_hVersion, GetFileVersionInfoSizeW)
  301. GET_PROC_ADDR(s_hVersion, GetFileVersionInfoW)
  302. GET_PROC_ADDR(s_hVersion, VerQueryValueW)
  303. GET_PROC_ADDR(s_hVersion, GetFileVersionInfoSizeA)
  304. GET_PROC_ADDR(s_hVersion, GetFileVersionInfoA)
  305. GET_PROC_ADDR(s_hVersion, VerQueryValueA)
  306. }
  307. }
  308. #ifdef USE_CRITSEC
  309. LeaveCriticalSection(&cs);
  310. #endif
  311. return fRet;
  312. }
  313. BOOL DemandLoadImm32()
  314. {
  315. BOOL fRet = TRUE;
  316. Assert(s_fInit);
  317. #ifdef USE_CRITSEC
  318. EnterCriticalSection(&cs);
  319. #endif
  320. if (0 == s_hImm32)
  321. {
  322. s_hImm32 = LoadLibrary(TEXT("IMM32.DLL"));
  323. AssertSz((NULL != s_hImm32), TEXT("LoadLibrary failed on IMM32.DLL"));
  324. if (0 == s_hImm32)
  325. fRet = FALSE;
  326. else
  327. {
  328. GET_PROC_ADDR(s_hImm32, ImmAssociateContext)
  329. GET_PROC_ADDR(s_hImm32, ImmGetContext)
  330. GET_PROC_ADDR(s_hImm32, ImmGetCompositionStringW)
  331. GET_PROC_ADDR(s_hImm32, ImmReleaseContext)
  332. }
  333. }
  334. #ifdef USE_CRITSEC
  335. LeaveCriticalSection(&cs);
  336. #endif
  337. return fRet;
  338. }
  339. BOOL DemandLoadWininet()
  340. {
  341. BOOL fRet = TRUE;
  342. Assert(s_fInit);
  343. #ifdef USE_CRITSEC
  344. EnterCriticalSection(&cs);
  345. #endif
  346. if (0 == s_hWininet)
  347. {
  348. s_hWininet = LoadLibrary(TEXT("wininet.dll"));
  349. AssertSz((NULL != s_hWininet), TEXT("LoadLibrary failed on Wininet.DLL"));
  350. if (0 == s_hWininet)
  351. fRet = FALSE;
  352. else
  353. {
  354. GET_PROC_ADDR(s_hWininet, InternetCanonicalizeUrlW)
  355. GET_PROC_ADDR(s_hWininet, InternetGetConnectedState)
  356. }
  357. }
  358. #ifdef USE_CRITSEC
  359. LeaveCriticalSection(&cs);
  360. #endif
  361. return fRet;
  362. }
  363. BOOL DemandLoadURLMON(void)
  364. {
  365. BOOL fRet = TRUE;
  366. Assert(s_fInit);
  367. #ifdef USE_CRITSEC
  368. EnterCriticalSection(&cs);
  369. #endif
  370. if (0 == s_hUrlmon)
  371. {
  372. s_hUrlmon = LoadLibrary(TEXT("URLMON.DLL"));
  373. AssertSz((NULL != s_hUrlmon), TEXT("LoadLibrary failed on Urlmon.DLL"));
  374. if (0 == s_hUrlmon)
  375. fRet = FALSE;
  376. else
  377. {
  378. GET_PROC_ADDR(s_hUrlmon, ObtainUserAgentString);
  379. }
  380. }
  381. #ifdef USE_CRITSEC
  382. LeaveCriticalSection(&cs);
  383. #endif
  384. return fRet;
  385. }
  386. ///////////////////////////////////////////////////////////////////////////////
  387. // DemandLoadShlwapi()
  388. //
  389. // Only load version 5.0 or greater
  390. ///////////////////////////////////////////////////////////////////////////////
  391. static const TCHAR c_szShlwapiDll[] = TEXT("shlwapi.dll");
  392. HINSTANCE DemandLoadShlwapi()
  393. {
  394. Assert(s_fInit);
  395. #ifdef USE_CRITSEC
  396. EnterCriticalSection(&cs);
  397. #endif
  398. if (!s_hShlwapi)
  399. s_hShlwapi = LoadLibrary(c_szShlwapiDll);
  400. #ifdef USE_CRITSEC
  401. LeaveCriticalSection(&cs);
  402. #endif
  403. return s_hShlwapi;
  404. }