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.

1117 lines
35 KiB

  1. // --------------------------------------------------------------------------------
  2. // Demand.cpp
  3. // Written By: jimsch, brimo, t-erikne (bastardized by sbailey)
  4. // --------------------------------------------------------------------------------
  5. // W4 stuff
  6. #pragma warning(disable: 4201) // nameless struct/union
  7. #pragma warning(disable: 4514) // unreferenced inline function removed
  8. // --------------------------------------------------------------------------------
  9. // Includes
  10. // --------------------------------------------------------------------------------
  11. #include "pch.hxx"
  12. #include "shlwapi.h"
  13. #include "shared.h"
  14. #define IMPLEMENT_LOADER_FUNCTIONS
  15. #include "demand.h"
  16. // --------------------------------------------------------------------------------
  17. // CRIT_GET_PROC_ADDR
  18. // --------------------------------------------------------------------------------
  19. #define CRIT_GET_PROC_ADDR(h, fn, temp) \
  20. temp = (TYP_##fn) GetProcAddress(h, #fn); \
  21. if (temp) \
  22. VAR_##fn = temp; \
  23. else \
  24. { \
  25. AssertSz(0, VAR_##fn" failed to load"); \
  26. goto error; \
  27. }
  28. // --------------------------------------------------------------------------------
  29. // RESET
  30. // --------------------------------------------------------------------------------
  31. #define RESET(fn) VAR_##fn = LOADER_##fn;
  32. // --------------------------------------------------------------------------------
  33. // GET_PROC_ADDR
  34. // --------------------------------------------------------------------------------
  35. #define GET_PROC_ADDR(h, fn) \
  36. VAR_##fn = (TYP_##fn) GetProcAddress(h, #fn); \
  37. Assert(VAR_##fn != NULL); \
  38. if(NULL == VAR_##fn ) { \
  39. VAR_##fn = LOADER_##fn; \
  40. }
  41. // Use this for exports not available on all platforms
  42. #define GET_PROC_ADDR_NOASSERT(h, fn) \
  43. VAR_##fn = (TYP_##fn) GetProcAddress(h, #fn); \
  44. if(NULL == VAR_##fn ) { \
  45. VAR_##fn = LOADER_##fn; \
  46. }
  47. // --------------------------------------------------------------------------------
  48. // GET_PROC_ADDR_ORDINAL
  49. // --------------------------------------------------------------------------------
  50. #define GET_PROC_ADDR_ORDINAL(h, fn, ord) \
  51. VAR_##fn = (TYP_##fn) GetProcAddress(h, MAKEINTRESOURCE(ord)); \
  52. Assert(VAR_##fn != NULL); \
  53. if(NULL == VAR_##fn ) { \
  54. VAR_##fn = LOADER_##fn; \
  55. }
  56. // --------------------------------------------------------------------------------
  57. // GET_PROC_ADDR3
  58. // --------------------------------------------------------------------------------
  59. #define GET_PROC_ADDR3(h, fn, varname) \
  60. VAR_##varname = (TYP_##varname) GetProcAddress(h, #fn); \
  61. Assert(VAR_##varname != NULL);
  62. // --------------------------------------------------------------------------------
  63. // Static Globals
  64. // --------------------------------------------------------------------------------
  65. static HMODULE s_hCrypt = NULL;
  66. static HMODULE s_hCryptDlg = NULL;
  67. static HMODULE s_hWinTrust = NULL;
  68. static HMODULE s_hWinINET = NULL;
  69. static HMODULE s_hShell32 = NULL;
  70. static HMODULE s_hOleAut32 = NULL;
  71. static HMODULE s_hComDlg32 = NULL;
  72. static HMODULE s_hVersion = NULL;
  73. static HMODULE s_hUrlmon = NULL;
  74. static HMODULE s_hShDocVw = NULL;
  75. static HMODULE s_hInetCPL = NULL;
  76. static HMODULE s_hMSO9 = NULL;
  77. static HMODULE s_hWinMM = NULL;
  78. static HMODULE s_hRichEdit = NULL;
  79. static HMODULE s_hMLANG = NULL;
  80. static HMODULE s_hWSOCK = NULL;
  81. static HMODULE s_hPstoreC = NULL;
  82. static HMODULE s_hRAS = NULL;
  83. static HMODULE s_hAdvApi = NULL;
  84. static HMODULE s_hCryptUI = NULL;
  85. static HMODULE s_ShlWapi = NULL;
  86. static HMODULE s_hMSI = NULL;
  87. static CRITICAL_SECTION g_csDefLoad = {0};
  88. BOOL g_FSupportV3 = FALSE;
  89. IF_DEBUG(static BOOL s_fInit = FALSE;)
  90. // --------------------------------------------------------------------------------
  91. // InitDemandLoadedLibs
  92. // --------------------------------------------------------------------------------
  93. void InitDemandLoadedLibs(void)
  94. {
  95. InitializeCriticalSection(&g_csDefLoad);
  96. IF_DEBUG(s_fInit = TRUE;)
  97. }
  98. // --------------------------------------------------------------------------------
  99. // FreeDemandLoadedLibs
  100. // --------------------------------------------------------------------------------
  101. void FreeDemandLoadedLibs(void)
  102. {
  103. EnterCriticalSection(&g_csDefLoad);
  104. SafeFreeLibrary(s_hCrypt);
  105. SafeFreeLibrary(s_hCryptDlg);
  106. SafeFreeLibrary(s_hWinTrust);
  107. SafeFreeLibrary(s_hWinINET);
  108. SafeFreeLibrary(s_hWSOCK);
  109. SafeFreeLibrary(s_hShell32);
  110. SafeFreeLibrary(s_hOleAut32);
  111. SafeFreeLibrary(s_hComDlg32);
  112. SafeFreeLibrary(s_hVersion);
  113. SafeFreeLibrary(s_hUrlmon);
  114. SafeFreeLibrary(s_hMLANG);
  115. SafeFreeLibrary(s_hShDocVw);
  116. SafeFreeLibrary(s_hInetCPL);
  117. SafeFreeLibrary(s_hMSO9);
  118. SafeFreeLibrary(s_hWinMM);
  119. SafeFreeLibrary(s_hRichEdit);
  120. SafeFreeLibrary(s_hPstoreC);
  121. SafeFreeLibrary(s_hRAS);
  122. SafeFreeLibrary(s_hAdvApi);
  123. SafeFreeLibrary(s_ShlWapi);
  124. SafeFreeLibrary(s_hMSI);
  125. IF_DEBUG(s_fInit = FALSE;)
  126. LeaveCriticalSection(&g_csDefLoad);
  127. DeleteCriticalSection(&g_csDefLoad);
  128. }
  129. #ifdef DEAD
  130. // --------------------------------------------------------------------------------
  131. // CorrectAcctManPath
  132. // --------------------------------------------------------------------------------
  133. BOOL CorrectAcctManPath(LPTSTR pszPath, DWORD cb, DWORD *pdwT)
  134. {
  135. HKEY hKey = NULL;
  136. BOOL fRet = FALSE;
  137. // Tracing
  138. TraceCall("CorrectAcctManPath");
  139. // Tact 1: Look for msoeacct.dll in same dir as inetcomm.dll
  140. // Try to open the inetcomm regkey
  141. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegInetCommDll, 0, KEY_QUERY_VALUE, &hKey))
  142. {
  143. TraceResult(E_FAIL);
  144. goto exit;
  145. }
  146. // Query the Value
  147. if (ERROR_SUCCESS != RegQueryValueEx(hKey, c_szDllPath, 0, pdwT, (LPBYTE)pszPath, &cb))
  148. {
  149. TraceResult(E_FAIL);
  150. goto exit;
  151. }
  152. fRet = TRUE;
  153. exit:
  154. // Cleanup
  155. if (hKey)
  156. RegCloseKey(hKey);
  157. return fRet;
  158. }
  159. #endif // DEAD
  160. BOOL IsSMIME3Supported(void)
  161. {
  162. if (0 == s_hCrypt)
  163. DemandLoadCrypt32();
  164. return(g_FSupportV3);
  165. }
  166. // --------------------------------------------------------------------------------
  167. // DemandLoadCrypt32
  168. // --------------------------------------------------------------------------------
  169. BOOL DemandLoadCrypt32(void)
  170. {
  171. BOOL fRet = TRUE;
  172. Assert(s_fInit);
  173. EnterCriticalSection(&g_csDefLoad);
  174. if (0 == s_hCrypt)
  175. {
  176. s_hCrypt = LoadLibrary("CRYPT32.DLL");
  177. AssertSz((NULL != s_hCrypt), TEXT("LoadLibrary failed on CRYPT32.DLL"));
  178. if (0 == s_hCrypt)
  179. fRet = FALSE;
  180. else
  181. {
  182. GET_PROC_ADDR(s_hCrypt, CertRDNValueToStrA);
  183. GET_PROC_ADDR(s_hCrypt, CertAddCertificateContextToStore)
  184. GET_PROC_ADDR(s_hCrypt, CertAddEncodedCertificateToStore)
  185. GET_PROC_ADDR(s_hCrypt, CertGetIssuerCertificateFromStore)
  186. GET_PROC_ADDR(s_hCrypt, CertEnumCertificatesInStore)
  187. GET_PROC_ADDR(s_hCrypt, CertFreeCertificateContext)
  188. GET_PROC_ADDR(s_hCrypt, CertDuplicateCertificateContext)
  189. GET_PROC_ADDR(s_hCrypt, CertFindCertificateInStore)
  190. GET_PROC_ADDR(s_hCrypt, CertVerifyTimeValidity)
  191. GET_PROC_ADDR(s_hCrypt, CertCompareCertificate)
  192. GET_PROC_ADDR(s_hCrypt, CertCompareCertificateName)
  193. GET_PROC_ADDR(s_hCrypt, CertCompareIntegerBlob)
  194. GET_PROC_ADDR(s_hCrypt, CertOpenStore)
  195. GET_PROC_ADDR(s_hCrypt, CertDuplicateStore)
  196. GET_PROC_ADDR(s_hCrypt, CertCloseStore)
  197. GET_PROC_ADDR(s_hCrypt, CertControlStore)
  198. GET_PROC_ADDR(s_hCrypt, CertGetCertificateContextProperty)
  199. GET_PROC_ADDR(s_hCrypt, CertGetSubjectCertificateFromStore)
  200. GET_PROC_ADDR(s_hCrypt, CryptDecodeObject)
  201. GET_PROC_ADDR(s_hCrypt, CryptDecodeObjectEx)
  202. GET_PROC_ADDR(s_hCrypt, CertFindRDNAttr)
  203. GET_PROC_ADDR(s_hCrypt, CryptMsgOpenToEncode)
  204. GET_PROC_ADDR(s_hCrypt, CryptMsgOpenToDecode)
  205. GET_PROC_ADDR(s_hCrypt, CryptMsgControl)
  206. GET_PROC_ADDR(s_hCrypt, CryptMsgUpdate)
  207. GET_PROC_ADDR(s_hCrypt, CryptMsgGetParam)
  208. GET_PROC_ADDR(s_hCrypt, CryptMsgClose)
  209. GET_PROC_ADDR(s_hCrypt, CryptEncodeObject)
  210. GET_PROC_ADDR(s_hCrypt, CryptEncodeObjectEx)
  211. GET_PROC_ADDR(s_hCrypt, CertAddEncodedCRLToStore)
  212. GET_PROC_ADDR(s_hCrypt, CertEnumCRLsInStore)
  213. GET_PROC_ADDR(s_hCrypt, CertFindExtension)
  214. GET_PROC_ADDR(s_hCrypt, CertCreateCertificateContext)
  215. GET_PROC_ADDR(s_hCrypt, CertGetEnhancedKeyUsage);
  216. GET_PROC_ADDR(s_hCrypt, CertNameToStrA);
  217. GET_PROC_ADDR(s_hCrypt, CertAddStoreToCollection);
  218. GET_PROC_ADDR(s_hCrypt, CertVerifySubjectCertificateContext);
  219. GET_PROC_ADDR(s_hCrypt, CertSetCertificateContextProperty);
  220. GET_PROC_ADDR(s_hCrypt, CertFreeCertificateChain);
  221. GET_PROC_ADDR(s_hCrypt, CertGetCertificateChain);
  222. GET_PROC_ADDR(s_hCrypt, CertVerifyCertificateChainPolicy);
  223. //
  224. // We need to make a determination if the dll supports the
  225. // new APIs we need or not
  226. //
  227. if (GetProcAddress(s_hCrypt, "CryptMsgVerifyCountersignatureEncodedEx") != NULL) {
  228. g_FSupportV3 = TRUE;
  229. }
  230. }
  231. }
  232. LeaveCriticalSection(&g_csDefLoad);
  233. return fRet;
  234. }
  235. #ifdef DEAD
  236. // --------------------------------------------------------------------------------
  237. // SmartLoadLibrary
  238. // --------------------------------------------------------------------------------
  239. HINSTANCE SmartLoadLibrary(HKEY hKeyRoot, LPCSTR pszRegRoot, LPCSTR pszRegValue,
  240. LPCSTR pszDllName)
  241. {
  242. // Locals
  243. BOOL fProblem=FALSE;
  244. HINSTANCE hInst=NULL;
  245. HKEY hKey=NULL, hKey2 = NULL;
  246. CHAR szPath[MAX_PATH];
  247. DWORD cb=ARRAYSIZE(szPath);
  248. DWORD dwT;
  249. DWORD iEnd;
  250. LPSTR pszPath=szPath;
  251. CHAR szT[MAX_PATH];
  252. // Tracing
  253. TraceCall("SmartLoadLibrary");
  254. // Try to open the regkey
  255. if (ERROR_SUCCESS != RegOpenKeyEx(hKeyRoot, pszRegRoot, 0, KEY_QUERY_VALUE, &hKey))
  256. {
  257. TraceResult(E_FAIL);
  258. goto exit;
  259. }
  260. // Query the Value
  261. if (ERROR_SUCCESS != RegQueryValueEx(hKey, pszRegValue, 0, &dwT, (LPBYTE)szPath, &cb))
  262. {
  263. TraceResult(E_FAIL);
  264. goto exit;
  265. }
  266. // Special case: msoeacct reg entry may have been hosed by OL98
  267. // Looking for outlacct.dll\0 which has 13 characters
  268. if (!lstrcmpi(&szPath[cb-sizeof(TCHAR)*13], c_szOutlAcctManDll))
  269. {
  270. if (!CorrectAcctManPath(szPath, ARRAYSIZE(szPath), &dwT))
  271. // We're in trouble, couldn't find Inetcomm's path
  272. goto desperate;
  273. fProblem = TRUE;
  274. }
  275. // Remove the file name from the path
  276. PathRemoveFileSpec(szPath);
  277. // Get the End
  278. iEnd = lstrlen(szPath);
  279. // Append a backslash
  280. szPath[iEnd++] = '\\';
  281. // Append the Dll Name
  282. lstrcpyn(&szPath[iEnd], pszDllName, MAX_PATH - iEnd);
  283. if (fProblem)
  284. {
  285. // Try to open the regkey to save ourself in future - will fail if we are not admin!
  286. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegMsoeAcctDll, 0, KEY_SET_VALUE, &hKey2))
  287. {
  288. RegSetValueEx(hKey2, c_szDllPath, 0, dwT, (LPBYTE)szPath, (iEnd+lstrlen(pszDllName)+1)*sizeof(TCHAR));
  289. RegCloseKey(hKey2);
  290. }
  291. }
  292. // Expand Sz ?
  293. if (REG_EXPAND_SZ == dwT)
  294. {
  295. // Expand It
  296. cb = ExpandEnvironmentStrings(szPath, szT, ARRAYSIZE(szT));
  297. // Failure
  298. if (cb == 0 || cb > ARRAYSIZE(szT))
  299. {
  300. TraceResult(E_FAIL);
  301. goto exit;
  302. }
  303. // Change pszPath
  304. pszPath = szT;
  305. }
  306. // Try to Load Library the Dll
  307. hInst = LoadLibrary(pszPath);
  308. desperate:
  309. // Failure ?
  310. if (NULL == hInst)
  311. {
  312. // If we are not going to try the GetModuleFName, just try the dll name
  313. hInst = LoadLibrary(pszDllName);
  314. // We really failed
  315. if (NULL == hInst)
  316. {
  317. TraceResult(E_FAIL);
  318. goto exit;
  319. }
  320. }
  321. exit:
  322. // Cleanup
  323. if (hKey)
  324. RegCloseKey(hKey);
  325. // Done
  326. return hInst;
  327. }
  328. #endif // DEAD
  329. // --------------------------------------------------------------------------------
  330. // DemandLoadCryptDlg
  331. // --------------------------------------------------------------------------------
  332. BOOL DemandLoadCryptDlg(void)
  333. {
  334. BOOL fRet = TRUE;
  335. Assert(s_fInit);
  336. EnterCriticalSection(&g_csDefLoad);
  337. if (0 == s_hCryptDlg)
  338. {
  339. s_hCryptDlg = LoadLibrary("CRYPTDLG.DLL");
  340. AssertSz((NULL != s_hCryptDlg), TEXT("LoadLibrary failed on CRYPTDLG.DLL"));
  341. if (0 == s_hCryptDlg)
  342. fRet = FALSE;
  343. else
  344. {
  345. GET_PROC_ADDR(s_hCryptDlg, CertViewPropertiesA)
  346. GET_PROC_ADDR(s_hCryptDlg, GetFriendlyNameOfCertA)
  347. GET_PROC_ADDR(s_hCryptDlg, CertSelectCertificateA)
  348. }
  349. }
  350. LeaveCriticalSection(&g_csDefLoad);
  351. return fRet;
  352. }
  353. // --------------------------------------------------------------------------------
  354. // DemandLoadWinTrust
  355. // --------------------------------------------------------------------------------
  356. BOOL DemandLoadWinTrust(void)
  357. {
  358. BOOL fRet = TRUE;
  359. Assert(s_fInit);
  360. EnterCriticalSection(&g_csDefLoad);
  361. if (0 == s_hWinTrust)
  362. {
  363. s_hWinTrust = LoadLibrary("WINTRUST.DLL");
  364. AssertSz((NULL != s_hWinTrust), TEXT("LoadLibrary failed on WINTRUST.DLL"));
  365. if (0 == s_hWinTrust)
  366. fRet = FALSE;
  367. else
  368. {
  369. GET_PROC_ADDR(s_hWinTrust, WinVerifyTrust)
  370. }
  371. }
  372. LeaveCriticalSection(&g_csDefLoad);
  373. return fRet;
  374. }
  375. // --------------------------------------------------------------------------------
  376. // DemandLoadWinINET
  377. // --------------------------------------------------------------------------------
  378. BOOL DemandLoadWinINET(void)
  379. {
  380. BOOL fRet = TRUE;
  381. Assert(s_fInit);
  382. EnterCriticalSection(&g_csDefLoad);
  383. if (0 == s_hWinINET)
  384. {
  385. s_hWinINET = LoadLibrary("WININET.DLL");
  386. AssertSz((NULL != s_hWinINET), TEXT("LoadLibrary failed on WININET.DLL"));
  387. if (0 == s_hWinINET)
  388. fRet = FALSE;
  389. else
  390. {
  391. GET_PROC_ADDR(s_hWinINET, RetrieveUrlCacheEntryFileA)
  392. GET_PROC_ADDR(s_hWinINET, UnlockUrlCacheEntryFileA)
  393. GET_PROC_ADDR(s_hWinINET, InternetQueryOptionA)
  394. GET_PROC_ADDR(s_hWinINET, InternetSetOptionA)
  395. GET_PROC_ADDR(s_hWinINET, InternetDialA)
  396. GET_PROC_ADDR(s_hWinINET, InternetHangUp)
  397. GET_PROC_ADDR(s_hWinINET, InternetGetConnectedStateExA)
  398. GET_PROC_ADDR(s_hWinINET, InternetCombineUrlA)
  399. GET_PROC_ADDR(s_hWinINET, InternetCrackUrlA)
  400. GET_PROC_ADDR(s_hWinINET, InternetCloseHandle)
  401. GET_PROC_ADDR(s_hWinINET, InternetReadFile)
  402. GET_PROC_ADDR(s_hWinINET, InternetConnectA)
  403. GET_PROC_ADDR(s_hWinINET, InternetOpenA)
  404. GET_PROC_ADDR(s_hWinINET, InternetSetStatusCallbackA)
  405. GET_PROC_ADDR(s_hWinINET, HttpQueryInfoA)
  406. GET_PROC_ADDR(s_hWinINET, HttpOpenRequestA)
  407. GET_PROC_ADDR(s_hWinINET, HttpAddRequestHeadersA)
  408. GET_PROC_ADDR(s_hWinINET, HttpSendRequestA)
  409. GET_PROC_ADDR(s_hWinINET, InternetWriteFile)
  410. GET_PROC_ADDR(s_hWinINET, HttpEndRequestA)
  411. GET_PROC_ADDR(s_hWinINET, HttpSendRequestExA)
  412. GET_PROC_ADDR(s_hWinINET, CommitUrlCacheEntryA)
  413. GET_PROC_ADDR(s_hWinINET, CreateUrlCacheEntryA)
  414. GET_PROC_ADDR(s_hWinINET, DeleteUrlCacheEntryA)
  415. }
  416. }
  417. LeaveCriticalSection(&g_csDefLoad);
  418. return fRet;
  419. }
  420. // --------------------------------------------------------------------------------
  421. // DemandLoadWSOCK32
  422. // --------------------------------------------------------------------------------
  423. BOOL DemandLoadWSOCK32()
  424. {
  425. BOOL fRet = TRUE;
  426. Assert(s_fInit);
  427. EnterCriticalSection(&g_csDefLoad);
  428. if (0 == s_hWSOCK)
  429. {
  430. s_hWSOCK = LoadLibrary("WSOCK32.DLL");
  431. AssertSz((NULL != s_hWSOCK), TEXT("LoadLibrary failed on WSOCK32.DLL"));
  432. if (0 == s_hWSOCK)
  433. fRet = FALSE;
  434. else
  435. {
  436. GET_PROC_ADDR(s_hWSOCK, WSAStartup)
  437. GET_PROC_ADDR(s_hWSOCK, WSACleanup)
  438. GET_PROC_ADDR(s_hWSOCK, WSAGetLastError)
  439. GET_PROC_ADDR(s_hWSOCK, gethostname)
  440. GET_PROC_ADDR(s_hWSOCK, gethostbyname)
  441. GET_PROC_ADDR(s_hWSOCK, WSAAsyncGetHostByName)
  442. GET_PROC_ADDR(s_hWSOCK, inet_addr)
  443. GET_PROC_ADDR(s_hWSOCK, htons)
  444. GET_PROC_ADDR(s_hWSOCK, WSACancelAsyncRequest)
  445. GET_PROC_ADDR(s_hWSOCK, send)
  446. GET_PROC_ADDR(s_hWSOCK, connect)
  447. GET_PROC_ADDR(s_hWSOCK, WSAAsyncSelect)
  448. GET_PROC_ADDR(s_hWSOCK, socket)
  449. GET_PROC_ADDR(s_hWSOCK, inet_ntoa)
  450. GET_PROC_ADDR(s_hWSOCK, closesocket)
  451. GET_PROC_ADDR(s_hWSOCK, recv)
  452. }
  453. }
  454. LeaveCriticalSection(&g_csDefLoad);
  455. return fRet;
  456. }
  457. // --------------------------------------------------------------------------------
  458. // DemandLoadSHELL32
  459. // --------------------------------------------------------------------------------
  460. BOOL DemandLoadSHELL32(void)
  461. {
  462. BOOL fRet = TRUE;
  463. Assert(s_fInit);
  464. EnterCriticalSection(&g_csDefLoad);
  465. if (0 == s_hShell32)
  466. {
  467. s_hShell32 = LoadLibrary("SHELL32.DLL");
  468. AssertSz((NULL != s_hShell32), TEXT("LoadLibrary failed on SHELL32.DLL"));
  469. if (0 == s_hShell32)
  470. fRet = FALSE;
  471. else
  472. {
  473. GET_PROC_ADDR(s_hShell32, SHGetPathFromIDListA);
  474. GET_PROC_ADDR_NOASSERT(s_hShell32, SHGetPathFromIDListW);
  475. GET_PROC_ADDR(s_hShell32, SHGetSpecialFolderLocation);
  476. GET_PROC_ADDR_ORDINAL(s_hShell32, SHFree, 195);
  477. GET_PROC_ADDR(s_hShell32, SHBrowseForFolderA);
  478. GET_PROC_ADDR_NOASSERT(s_hShell32, SHBrowseForFolderW);
  479. GET_PROC_ADDR_NOASSERT(s_hShell32, SHSetUnreadMailCountW);
  480. GET_PROC_ADDR(s_hShell32, ShellExecuteA);
  481. GET_PROC_ADDR(s_hShell32, ShellExecuteExA);
  482. GET_PROC_ADDR(s_hShell32, DragQueryFileA);
  483. GET_PROC_ADDR(s_hShell32, SHGetFileInfoA);
  484. GET_PROC_ADDR(s_hShell32, Shell_NotifyIconA);
  485. GET_PROC_ADDR(s_hShell32, ExtractIconA);
  486. GET_PROC_ADDR(s_hShell32, SHFileOperationA);
  487. }
  488. }
  489. LeaveCriticalSection(&g_csDefLoad);
  490. return fRet;
  491. }
  492. #if 0
  493. // --------------------------------------------------------------------------------
  494. // DemandLoadOLEAUT32
  495. // --------------------------------------------------------------------------------
  496. BOOL DemandLoadOLEAUT32(void)
  497. {
  498. BOOL fRet = TRUE;
  499. Assert(s_fInit);
  500. EnterCriticalSection(&g_csDefLoad);
  501. if (0 == s_hOleAut32)
  502. {
  503. s_hOleAut32 = LoadLibrary("OLEAUT32.DLL");
  504. AssertSz((BOOL)s_hOleAut32, TEXT("LoadLibrary failed on OLEAUT32.DLL"));
  505. if (0 == s_hOleAut32)
  506. fRet = FALSE;
  507. else
  508. {
  509. GET_PROC_ADDR(s_hOleAut32, SafeArrayCreate);
  510. GET_PROC_ADDR(s_hOleAut32, SafeArrayPutElement);
  511. GET_PROC_ADDR(s_hOleAut32, DispInvoke);
  512. GET_PROC_ADDR(s_hOleAut32, DispGetIDsOfNames);
  513. GET_PROC_ADDR(s_hOleAut32, SafeArrayDestroy);
  514. GET_PROC_ADDR(s_hOleAut32, SafeArrayGetUBound);
  515. GET_PROC_ADDR(s_hOleAut32, SafeArrayGetLBound);
  516. GET_PROC_ADDR(s_hOleAut32, SafeArrayGetElement);
  517. GET_PROC_ADDR(s_hOleAut32, SysAllocStringByteLen);
  518. GET_PROC_ADDR(s_hOleAut32, SysReAllocString);
  519. GET_PROC_ADDR(s_hOleAut32, SysAllocStringLen);
  520. GET_PROC_ADDR(s_hOleAut32, SysAllocString);
  521. GET_PROC_ADDR(s_hOleAut32, SysFreeString);
  522. GET_PROC_ADDR(s_hOleAut32, SysStringLen);
  523. GET_PROC_ADDR(s_hOleAut32, VariantInit);
  524. GET_PROC_ADDR(s_hOleAut32, LoadTypeLib);
  525. GET_PROC_ADDR(s_hOleAut32, RegisterTypeLib);
  526. GET_PROC_ADDR(s_hOleAut32, SafeArrayAccessData);
  527. GET_PROC_ADDR(s_hOleAut32, SafeArrayUnaccessData);
  528. GET_PROC_ADDR(s_hOleAut32, SysStringByteLen);
  529. GET_PROC_ADDR(s_hOleAut32, VariantClear);
  530. GET_PROC_ADDR(s_hOleAut32, VariantCopy);
  531. GET_PROC_ADDR(s_hOleAut32, SetErrorInfo);
  532. GET_PROC_ADDR(s_hOleAut32, CreateErrorInfo);
  533. }
  534. }
  535. LeaveCriticalSection(&g_csDefLoad);
  536. return fRet;
  537. }
  538. #endif
  539. // --------------------------------------------------------------------------------
  540. // DemandLoadCOMDLG32
  541. // --------------------------------------------------------------------------------
  542. BOOL DemandLoadCOMDLG32(void)
  543. {
  544. BOOL fRet = TRUE;
  545. Assert(s_fInit);
  546. EnterCriticalSection(&g_csDefLoad);
  547. if (0 == s_hComDlg32)
  548. {
  549. s_hComDlg32 = LoadLibrary("COMDLG32.DLL");
  550. AssertSz((NULL != s_hComDlg32), TEXT("LoadLibrary failed on COMDLG32.DLL"));
  551. if (0 == s_hComDlg32)
  552. fRet = FALSE;
  553. else
  554. {
  555. GET_PROC_ADDR(s_hComDlg32, GetSaveFileNameA);
  556. GET_PROC_ADDR(s_hComDlg32, GetOpenFileNameA);
  557. GET_PROC_ADDR(s_hComDlg32, ChooseFontA);
  558. }
  559. }
  560. LeaveCriticalSection(&g_csDefLoad);
  561. return fRet;
  562. }
  563. // --------------------------------------------------------------------------------
  564. // DemandLoadVERSION
  565. // --------------------------------------------------------------------------------
  566. BOOL DemandLoadVERSION(void)
  567. {
  568. BOOL fRet = TRUE;
  569. Assert(s_fInit);
  570. EnterCriticalSection(&g_csDefLoad);
  571. if (0 == s_hVersion)
  572. {
  573. s_hVersion = LoadLibrary("VERSION.DLL");
  574. AssertSz((NULL != s_hVersion), TEXT("LoadLibrary failed on VERSION.DLL"));
  575. if (0 == s_hVersion)
  576. fRet = FALSE;
  577. else
  578. {
  579. GET_PROC_ADDR(s_hVersion, VerQueryValueA);
  580. GET_PROC_ADDR(s_hVersion, GetFileVersionInfoA);
  581. GET_PROC_ADDR(s_hVersion, GetFileVersionInfoSizeA);
  582. }
  583. }
  584. LeaveCriticalSection(&g_csDefLoad);
  585. return fRet;
  586. }
  587. // --------------------------------------------------------------------------------
  588. // DemandLoadURLMON
  589. // --------------------------------------------------------------------------------
  590. BOOL DemandLoadURLMON(void)
  591. {
  592. BOOL fRet = TRUE;
  593. Assert(s_fInit);
  594. EnterCriticalSection(&g_csDefLoad);
  595. if (0 == s_hUrlmon)
  596. {
  597. s_hUrlmon = LoadLibrary("URLMON.DLL");
  598. AssertSz((NULL != s_hUrlmon), TEXT("LoadLibrary failed on URLMON.DLL"));
  599. if (0 == s_hUrlmon)
  600. fRet = FALSE;
  601. else
  602. {
  603. GET_PROC_ADDR(s_hUrlmon, CreateURLMoniker);
  604. GET_PROC_ADDR(s_hUrlmon, URLOpenBlockingStreamA);
  605. GET_PROC_ADDR(s_hUrlmon, FindMimeFromData);
  606. GET_PROC_ADDR(s_hUrlmon, CoInternetCombineUrl);
  607. GET_PROC_ADDR(s_hUrlmon, RegisterBindStatusCallback);
  608. GET_PROC_ADDR(s_hUrlmon, RevokeBindStatusCallback);
  609. GET_PROC_ADDR(s_hUrlmon, FaultInIEFeature);
  610. GET_PROC_ADDR(s_hUrlmon, CoInternetGetSecurityUrl);
  611. GET_PROC_ADDR(s_hUrlmon, ObtainUserAgentString);
  612. GET_PROC_ADDR(s_hUrlmon, CoInternetCreateSecurityManager);
  613. }
  614. }
  615. LeaveCriticalSection(&g_csDefLoad);
  616. return fRet;
  617. }
  618. // --------------------------------------------------------------------------------
  619. // DemandLoadMLANG
  620. // --------------------------------------------------------------------------------
  621. BOOL DemandLoadMLANG(void)
  622. {
  623. BOOL fRet = TRUE;
  624. Assert(s_fInit);
  625. EnterCriticalSection(&g_csDefLoad);
  626. if (0 == s_hMLANG)
  627. {
  628. s_hMLANG = LoadLibrary("MLANG.DLL");
  629. AssertSz((NULL != s_hMLANG), TEXT("LoadLibrary failed on MLANG.DLL"));
  630. if (0 == s_hMLANG)
  631. fRet = FALSE;
  632. else
  633. {
  634. GET_PROC_ADDR(s_hMLANG, IsConvertINetStringAvailable)
  635. GET_PROC_ADDR(s_hMLANG, ConvertINetString)
  636. }
  637. }
  638. LeaveCriticalSection(&g_csDefLoad);
  639. return fRet;
  640. }
  641. // --------------------------------------------------------------------------------
  642. // DemandLoadSHDOCVW
  643. // --------------------------------------------------------------------------------
  644. BOOL DemandLoadSHDOCVW()
  645. {
  646. BOOL fRet = TRUE;
  647. Assert(s_fInit);
  648. EnterCriticalSection(&g_csDefLoad);
  649. if (0 == s_hShDocVw)
  650. {
  651. s_hShDocVw = LoadLibrary("SHDOCVW.DLL");
  652. AssertSz((NULL != s_hShDocVw), TEXT("LoadLibrary failed on SHDOCVW.DLL"));
  653. if (0 == s_hShDocVw)
  654. fRet = FALSE;
  655. else
  656. {
  657. GET_PROC_ADDR(s_hShDocVw, AddUrlToFavorites);
  658. GET_PROC_ADDR(s_hShDocVw, SetQueryNetSessionCount);
  659. GET_PROC_ADDR(s_hShDocVw, SetShellOfflineState);
  660. }
  661. }
  662. LeaveCriticalSection(&g_csDefLoad);
  663. return fRet;
  664. }
  665. // --------------------------------------------------------------------------------
  666. // DemandLoadINETCPL
  667. // --------------------------------------------------------------------------------
  668. BOOL DemandLoadINETCPL()
  669. {
  670. BOOL fRet = TRUE;
  671. Assert(s_fInit);
  672. EnterCriticalSection(&g_csDefLoad);
  673. if (0 == s_hInetCPL)
  674. {
  675. s_hInetCPL = LoadLibrary("INETCPL.CPL");
  676. AssertSz((NULL != s_hInetCPL), TEXT("LoadLibrary failed on INETCPL.CPL"));
  677. if (0 == s_hInetCPL)
  678. fRet = FALSE;
  679. else
  680. {
  681. GET_PROC_ADDR(s_hInetCPL, OpenFontsDialog);
  682. GET_PROC_ADDR(s_hInetCPL, LaunchConnectionDialog);
  683. }
  684. }
  685. LeaveCriticalSection(&g_csDefLoad);
  686. return fRet;
  687. }
  688. // --------------------------------------------------------------------------------
  689. // DemandLoadMSO9
  690. // --------------------------------------------------------------------------------
  691. BOOL DemandLoadMSO9(void)
  692. {
  693. BOOL fRet = TRUE;
  694. Assert(s_fInit);
  695. EnterCriticalSection(&g_csDefLoad);
  696. if (0 == s_hMSO9)
  697. {
  698. #ifdef DEBUG
  699. s_hMSO9 = LoadLibrary("mso9d.DLL");
  700. if (!s_hMSO9)
  701. s_hMSO9 = LoadLibrary("mso9.DLL");
  702. #else
  703. s_hMSO9 = LoadLibrary("mso9.DLL");
  704. #endif
  705. AssertSz((NULL != s_hMSO9), TEXT("LoadLibrary failed on MSO9.DLL"));
  706. if (0 == s_hMSO9)
  707. fRet = FALSE;
  708. else
  709. {
  710. GET_PROC_ADDR3(s_hMSO9, _MsoFGetComponentManager@4, MsoFGetComponentManager);
  711. }
  712. }
  713. LeaveCriticalSection(&g_csDefLoad);
  714. return fRet;
  715. }
  716. // --------------------------------------------------------------------------------
  717. // DemandLoadWinMM
  718. // --------------------------------------------------------------------------------
  719. BOOL DemandLoadWinMM(void)
  720. {
  721. BOOL fRet = TRUE;
  722. Assert(s_fInit);
  723. EnterCriticalSection(&g_csDefLoad);
  724. if (0 == s_hWinMM)
  725. {
  726. s_hWinMM = LoadLibrary("winmm.dll");
  727. AssertSz((NULL != s_hWinMM), TEXT("LoadLibrary failed on WINMM.DLL"));
  728. if (0 == s_hWinMM)
  729. fRet = FALSE;
  730. else
  731. {
  732. GET_PROC_ADDR(s_hWinMM, sndPlaySoundA);
  733. }
  734. }
  735. LeaveCriticalSection(&g_csDefLoad);
  736. return fRet;
  737. }
  738. // --------------------------------------------------------------------------------
  739. // DemandLoadRichEdit
  740. // --------------------------------------------------------------------------------
  741. BOOL DemandLoadRichEdit(void)
  742. {
  743. if (!s_hRichEdit)
  744. {
  745. s_hRichEdit = LoadLibrary("RICHED32.DLL");
  746. if (!s_hRichEdit)
  747. return FALSE;
  748. }
  749. return TRUE;
  750. }
  751. // --------------------------------------------------------------------------------
  752. // DemandLoadPStoreC
  753. // --------------------------------------------------------------------------------
  754. BOOL DemandLoadPStoreC()
  755. {
  756. BOOL fRet = TRUE;
  757. Assert(s_fInit);
  758. EnterCriticalSection(&g_csDefLoad);
  759. if (0 == s_hPstoreC)
  760. {
  761. s_hPstoreC = LoadLibrary("PSTOREC.DLL");
  762. AssertSz((NULL != s_hPstoreC), TEXT("LoadLibrary failed on PSTOREC.DLL"));
  763. if (0 == s_hPstoreC)
  764. fRet = FALSE;
  765. else
  766. {
  767. GET_PROC_ADDR(s_hPstoreC, PStoreCreateInstance);
  768. }
  769. }
  770. LeaveCriticalSection(&g_csDefLoad);
  771. return fRet;
  772. }
  773. // --------------------------------------------------------------------------------
  774. // DemandLoadRAS
  775. // --------------------------------------------------------------------------------
  776. BOOL DemandLoadRAS()
  777. {
  778. BOOL fRet = TRUE;
  779. Assert(s_fInit);
  780. EnterCriticalSection(&g_csDefLoad);
  781. if (0 == s_hRAS)
  782. {
  783. s_hRAS = LoadLibrary("RASAPI32.DLL");
  784. AssertSz((NULL != s_hRAS), TEXT("LoadLibrary failed on RASAPI32.DLL"));
  785. if (0 == s_hRAS)
  786. fRet = FALSE;
  787. else
  788. {
  789. GET_PROC_ADDR(s_hRAS, RasEnumEntriesA)
  790. GET_PROC_ADDR(s_hRAS, RasEditPhonebookEntryA)
  791. GET_PROC_ADDR(s_hRAS, RasCreatePhonebookEntryA)
  792. }
  793. }
  794. LeaveCriticalSection(&g_csDefLoad);
  795. return fRet;
  796. }
  797. BOOL IsWin95()
  798. {
  799. OSVERSIONINFOA ver;
  800. ver.dwOSVersionInfoSize = sizeof(ver);
  801. if (GetVersionExA(&ver))
  802. {
  803. return (VER_PLATFORM_WIN32_WINDOWS == ver.dwPlatformId);
  804. }
  805. return FALSE;
  806. }
  807. BOOL MyCryptAcquireContextW(HCRYPTPROV * phProv, LPCWSTR pszContainer,
  808. LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
  809. {
  810. char rgch1[256];
  811. char rgch2[256];
  812. if (pszContainer != NULL)
  813. {
  814. WideCharToMultiByte(CP_ACP, 0, pszContainer, -1, rgch1, sizeof(rgch1),
  815. NULL, NULL);
  816. pszContainer = (LPWSTR) rgch1;
  817. }
  818. if (pszProvider != NULL)
  819. {
  820. WideCharToMultiByte(CP_ACP, 0, pszProvider, -1, rgch2, sizeof(rgch2),
  821. NULL, NULL);
  822. pszProvider = (LPWSTR) rgch2;
  823. }
  824. return CryptAcquireContextA(phProv, (LPCSTR) pszContainer,
  825. (LPCSTR) pszProvider, dwProvType, dwFlags);
  826. }
  827. BOOL MY_CryptContextAddRef(HCRYPTPROV, DWORD * , DWORD )
  828. {
  829. #ifdef DEBUG
  830. return TRUE;
  831. #else // !DEBUG
  832. SetLastError(ERROR_NOT_SUPPORTED);
  833. return FALSE;
  834. #endif // DEBUG
  835. }
  836. BOOL MY_CryptDuplicateKey(HCRYPTKEY , DWORD * , DWORD , HCRYPTKEY * )
  837. {
  838. #ifdef DEBUG
  839. return TRUE;
  840. #else // !DEBUG
  841. SetLastError(ERROR_NOT_SUPPORTED);
  842. return FALSE;
  843. #endif // DEBUG
  844. }
  845. BOOL DemandLoadAdvApi32()
  846. {
  847. BOOL fRet = TRUE;
  848. OSVERSIONINFOA ver;
  849. ver.dwOSVersionInfoSize = sizeof(ver);
  850. Assert(s_fInit);
  851. EnterCriticalSection(&g_csDefLoad);
  852. if (0 == s_hAdvApi)
  853. {
  854. if(!GetVersionExA(&ver))
  855. {
  856. fRet = FALSE;
  857. goto exit;
  858. }
  859. s_hAdvApi = LoadLibrary("ADVAPI32.DLL");
  860. AssertSz((NULL != s_hAdvApi), TEXT("LoadLibrary failed on ADVAPI32.DLL"));
  861. if (0 == s_hAdvApi)
  862. fRet = FALSE;
  863. else
  864. {
  865. if (VER_PLATFORM_WIN32_WINDOWS == ver.dwPlatformId) // Win95
  866. CryptAcquireContextW = MyCryptAcquireContextW;
  867. else
  868. GET_PROC_ADDR(s_hAdvApi, CryptAcquireContextW)
  869. VAR_CryptContextAddRef = LOADER_CryptContextAddRef;
  870. if((ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ver.dwMajorVersion >= 5)) //NT5
  871. {
  872. GET_PROC_ADDR(s_hAdvApi, CryptContextAddRef);
  873. GET_PROC_ADDR(s_hAdvApi, CryptDuplicateKey);
  874. }
  875. if (VAR_CryptContextAddRef == LOADER_CryptContextAddRef)
  876. VAR_CryptContextAddRef = MY_CryptContextAddRef;
  877. if (VAR_CryptDuplicateKey == LOADER_CryptDuplicateKey)
  878. VAR_CryptDuplicateKey = MY_CryptDuplicateKey;
  879. }
  880. }
  881. exit:
  882. LeaveCriticalSection(&g_csDefLoad);
  883. return fRet;
  884. }
  885. HINSTANCE DemandLoadShlWapi()
  886. {
  887. Assert(s_fInit);
  888. EnterCriticalSection(&g_csDefLoad);
  889. if (!s_ShlWapi)
  890. {
  891. s_ShlWapi = LoadLibrary("shlwapi.dll");
  892. AssertSz((NULL != s_ShlWapi), TEXT("LoadLibrary failed on ShlWAPI.DLL"));
  893. }
  894. LeaveCriticalSection(&g_csDefLoad);
  895. return((HINSTANCE) s_ShlWapi);
  896. }
  897. BOOL DemandLoadCryptUI()
  898. {
  899. BOOL fRet = TRUE;
  900. Assert(s_fInit);
  901. EnterCriticalSection(&g_csDefLoad);
  902. if (0 == s_hCryptUI)
  903. {
  904. s_hCryptUI = LoadLibrary("CRYPTUI.DLL");
  905. AssertSz((NULL != s_hCryptUI), TEXT("LoadLibrary failed on CRYPTUI.DLL"));
  906. if (0 == s_hCryptUI)
  907. fRet = FALSE;
  908. else
  909. {
  910. GET_PROC_ADDR(s_hCryptUI, CryptUIDlgCertMgr)
  911. }
  912. }
  913. LeaveCriticalSection(&g_csDefLoad);
  914. return fRet;
  915. }
  916. // --------------------------------------------------------------------------------
  917. // DemandLoadMSI
  918. // --------------------------------------------------------------------------------
  919. BOOL DemandLoadMSI(void)
  920. {
  921. BOOL fRet = TRUE;
  922. static BOOL s_fMSIInited = FALSE;
  923. Assert(s_fInit);
  924. EnterCriticalSection(&g_csDefLoad);
  925. // Unlike other demand-loaded dlls, this dll may not exist and that's fine.
  926. // In these cases s_hMSI will always be NULL, so we need another flag to tell
  927. // us whether we are inited.
  928. if (FALSE == s_fMSIInited)
  929. {
  930. s_fMSIInited = TRUE;
  931. s_hMSI = LoadLibrary("MSI.DLL");
  932. if (NULL == s_hMSI)
  933. fRet = FALSE;
  934. else
  935. {
  936. // It's okay to use the asserting macro here because while MSI is
  937. // optional, if present it must have these entry points
  938. GET_PROC_ADDR(s_hMSI, MsiEnumComponentQualifiersA);
  939. GET_PROC_ADDR(s_hMSI, MsiProvideQualifiedComponentA);
  940. GET_PROC_ADDR(s_hMSI, MsiLocateComponentA);
  941. GET_PROC_ADDR(s_hMSI, MsiSetInternalUI);
  942. }
  943. }
  944. LeaveCriticalSection(&g_csDefLoad);
  945. return fRet;
  946. }