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.

320 lines
9.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: cryp32.cpp
  8. //
  9. // Contents: Crypto API, version 2.
  10. //
  11. // Functions: DllMain
  12. //
  13. // History: 13-Aug-96 kevinr created
  14. //
  15. //--------------------------------------------------------------------------
  16. #include "windows.h"
  17. #include "unicode.h"
  18. // assignment within conditional expression
  19. #pragma warning (disable: 4706)
  20. #if DBG
  21. extern BOOL WINAPI DebugDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  22. #endif
  23. extern BOOL WINAPI I_CryptTlsDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  24. extern BOOL WINAPI I_CryptOIDFuncDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  25. extern BOOL WINAPI I_CryptOIDInfoDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  26. extern BOOL WINAPI I_CertRevFuncDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  27. extern BOOL WINAPI I_CertCTLUsageFuncDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  28. extern BOOL WINAPI CertStoreDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  29. extern BOOL WINAPI CertASNDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  30. extern BOOL WINAPI CertHelperDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  31. extern BOOL WINAPI CryptMsgDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  32. extern BOOL WINAPI UnicodeDllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  33. extern BOOL WINAPI CryptFrmtFuncDllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved);
  34. extern BOOL WINAPI CryptSIPDllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved);
  35. extern BOOL WINAPI CryptPFXDllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved);
  36. extern BOOL WINAPI CertChainPolicyDllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved);
  37. extern BOOL WINAPI ChainDllMain (HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  38. extern BOOL WINAPI CertPerfDllMain (HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved);
  39. typedef BOOL (WINAPI *PFN_DLL_MAIN_FUNC) (
  40. HMODULE hInstDLL,
  41. DWORD fdwReason,
  42. LPVOID lpvReserved
  43. );
  44. // For process/thread attach, called in the following order. For process/thread
  45. // detach, called in reverse order.
  46. static const PFN_DLL_MAIN_FUNC rgpfnDllMain[] = {
  47. #if DBG
  48. DebugDllMain,
  49. #endif
  50. // For process/thread attach the following two functions must be called
  51. // first. For process/thread detach the following two functions must
  52. // be called last.
  53. I_CryptTlsDllMain,
  54. I_CryptOIDFuncDllMain,
  55. CertPerfDllMain,
  56. CryptSIPDllMain,
  57. I_CryptOIDInfoDllMain,
  58. CertHelperDllMain,
  59. UnicodeDllMain,
  60. I_CertRevFuncDllMain,
  61. I_CertCTLUsageFuncDllMain,
  62. CryptFrmtFuncDllMain,
  63. CertStoreDllMain,
  64. CryptPFXDllMain,
  65. CertASNDllMain,
  66. ChainDllMain,
  67. CertChainPolicyDllMain,
  68. CryptMsgDllMain
  69. };
  70. #define DLL_MAIN_FUNC_COUNT (sizeof(rgpfnDllMain) / sizeof(rgpfnDllMain[0]))
  71. #if DBG
  72. #include <crtdbg.h>
  73. #ifndef _CRTDBG_LEAK_CHECK_DF
  74. #define _CRTDBG_LEAK_CHECK_DF 0x20
  75. #endif
  76. #define DEBUG_MASK_LEAK_CHECK _CRTDBG_LEAK_CHECK_DF /* 0x20 */
  77. static int WINAPI DbgGetDebugFlags()
  78. {
  79. char *pszEnvVar;
  80. char *p;
  81. int iDebugFlags = 0;
  82. if (pszEnvVar = getenv("DEBUG_MASK"))
  83. iDebugFlags = strtol(pszEnvVar, &p, 16);
  84. return iDebugFlags;
  85. }
  86. #endif
  87. //
  88. // I_CryptUIProtect loads cryptui.dll. we need to free it on DLL_PROCESS_DETACH
  89. // if it was loaded.
  90. //
  91. static HINSTANCE g_hCryptUI;
  92. //+-------------------------------------------------------------------------
  93. // Return TRUE if DLL_PROCESS_DETACH is called for FreeLibrary instead
  94. // of ProcessExit. The third parameter, lpvReserved, passed to DllMain
  95. // is NULL for FreeLibrary and non-NULL for ProcessExit.
  96. //
  97. // Also for debugging purposes, check the following environment variables:
  98. // CRYPT_DEBUG_FORCE_FREE_LIBRARY != 0 (retail and checked)
  99. // DEBUG_MASK & 0x20 (only checked)
  100. //
  101. // If either of the above environment variables is present and satisfies
  102. // the expression, TRUE is returned.
  103. //--------------------------------------------------------------------------
  104. BOOL
  105. WINAPI
  106. I_CryptIsProcessDetachFreeLibrary(
  107. LPVOID lpvReserved // Third parameter passed to DllMain
  108. )
  109. {
  110. #define ENV_LEN 32
  111. char rgch[ENV_LEN + 1];
  112. DWORD cch;
  113. if (NULL == lpvReserved)
  114. return TRUE;
  115. cch = GetEnvironmentVariableA(
  116. "CRYPT_DEBUG_FORCE_FREE_LIBRARY",
  117. rgch,
  118. ENV_LEN
  119. );
  120. if (cch && cch <= ENV_LEN) {
  121. long lValue;
  122. rgch[cch] = '\0';
  123. lValue = atol(rgch);
  124. if (lValue)
  125. return TRUE;
  126. }
  127. #if DBG
  128. if (DbgGetDebugFlags() & DEBUG_MASK_LEAK_CHECK)
  129. return TRUE;
  130. #endif
  131. return FALSE;
  132. }
  133. //+-------------------------------------------------------------------------
  134. // Dll initialization
  135. //--------------------------------------------------------------------------
  136. BOOL WINAPI DllMain(
  137. HMODULE hInstDLL,
  138. DWORD fdwReason,
  139. LPVOID lpvReserved
  140. )
  141. {
  142. BOOL fReturn = TRUE;
  143. int i;
  144. #if DBG
  145. // NB- Due to an apparent bug in the Win95 loader, the CRT gets unloaded
  146. // too early in some circumstances. In particular, it can get unloaded
  147. // before this routine executes at process detach time. This can cause
  148. // faults when executing this routine, and also when executing the rest
  149. // of CRYPT32:CRT_INIT, after this initroutine returns. Ergo, we do an
  150. // extra load of the CRT, to be sure it stays around long enough.
  151. if ((fdwReason == DLL_PROCESS_ATTACH) && (!FIsWinNT()))
  152. LoadLibrary( "MSVCRTD.DLL");
  153. #endif
  154. switch (fdwReason) {
  155. case DLL_PROCESS_DETACH:
  156. if( g_hCryptUI ) {
  157. FreeLibrary( g_hCryptUI );
  158. g_hCryptUI = NULL;
  159. }
  160. if (!I_CryptIsProcessDetachFreeLibrary(lpvReserved)) {
  161. // Process Exit. I have seen cases where other Dlls, like
  162. // wininet.dll, depend on crypt32.dll. However, crypt32.dll
  163. // gets called first at ProcessDetach. Since all the memory
  164. // and kernel handles will get freed anyway by the kernel,
  165. // we can skip the following detach freeing.
  166. // Always need to free shared memory used for certificate
  167. // performance counters
  168. CertPerfDllMain(hInstDLL, fdwReason, lpvReserved);
  169. return TRUE;
  170. }
  171. // Fall through for FreeLibrary
  172. case DLL_THREAD_DETACH:
  173. for (i = DLL_MAIN_FUNC_COUNT - 1; i >= 0; i--)
  174. fReturn &= rgpfnDllMain[i](hInstDLL, fdwReason, lpvReserved);
  175. break;
  176. case DLL_PROCESS_ATTACH:
  177. for (i = 0; i < DLL_MAIN_FUNC_COUNT; i++) {
  178. fReturn = rgpfnDllMain[i](hInstDLL, fdwReason, lpvReserved);
  179. if (!fReturn)
  180. break;
  181. }
  182. if (!fReturn) {
  183. for (i--; i >= 0; i--)
  184. rgpfnDllMain[i](hInstDLL, DLL_PROCESS_DETACH, NULL);
  185. }
  186. break;
  187. case DLL_THREAD_ATTACH:
  188. default:
  189. for (i = 0; i < DLL_MAIN_FUNC_COUNT; i++)
  190. fReturn &= rgpfnDllMain[i](hInstDLL, fdwReason, lpvReserved);
  191. break;
  192. }
  193. return(fReturn);
  194. }
  195. #if 1
  196. typedef
  197. DWORD
  198. (WINAPI *PFN_I_CryptUIProtect)(
  199. IN PVOID pvReserved1,
  200. IN PVOID pvReserved2,
  201. IN DWORD dwReserved3,
  202. IN PVOID *pvReserved4,
  203. IN BOOL fReserved5,
  204. IN PVOID pvReserved6
  205. );
  206. extern "C"
  207. DWORD
  208. WINAPI
  209. I_CryptUIProtect(
  210. IN PVOID pvReserved1,
  211. IN PVOID pvReserved2,
  212. IN DWORD dwReserved3,
  213. IN PVOID *pvReserved4,
  214. IN BOOL fReserved5,
  215. IN PVOID pvReserved6
  216. )
  217. {
  218. static PFN_I_CryptUIProtect pfn;
  219. DWORD rc;
  220. if ( g_hCryptUI == NULL ) {
  221. g_hCryptUI = LoadLibrary(TEXT("cryptui.dll"));
  222. if( g_hCryptUI == NULL )
  223. return GetLastError();
  224. }
  225. if ( pfn == NULL ) {
  226. pfn = (PFN_I_CryptUIProtect)GetProcAddress(g_hCryptUI, "I_CryptUIProtect");
  227. }
  228. if ( pfn != NULL ) {
  229. rc = (*pfn)(pvReserved1, pvReserved2, dwReserved3, pvReserved4, fReserved5, pvReserved6);
  230. } else {
  231. rc = GetLastError();
  232. if( rc == ERROR_SUCCESS )
  233. rc = ERROR_INVALID_PARAMETER;
  234. }
  235. return rc;
  236. }
  237. typedef
  238. DWORD
  239. (WINAPI *PFN_I_CryptUIProtectFailure)(
  240. IN PVOID pvReserved1,
  241. IN DWORD dwReserved2,
  242. IN PVOID *pvReserved3
  243. );
  244. extern "C"
  245. DWORD
  246. WINAPI
  247. I_CryptUIProtectFailure(
  248. IN PVOID pvReserved1,
  249. IN DWORD dwReserved2,
  250. IN PVOID *pvReserved3
  251. )
  252. {
  253. static PFN_I_CryptUIProtectFailure pfn;
  254. DWORD rc;
  255. if ( g_hCryptUI == NULL ) {
  256. g_hCryptUI = LoadLibrary(TEXT("cryptui.dll"));
  257. if( g_hCryptUI == NULL )
  258. return GetLastError();
  259. }
  260. if ( pfn == NULL ) {
  261. pfn = (PFN_I_CryptUIProtectFailure)GetProcAddress(g_hCryptUI, "I_CryptUIProtectFailure");
  262. }
  263. if ( pfn != NULL ) {
  264. rc = (*pfn)(pvReserved1, dwReserved2, pvReserved3);
  265. } else {
  266. rc = GetLastError();
  267. if( rc == ERROR_SUCCESS )
  268. rc = ERROR_INVALID_PARAMETER;
  269. }
  270. return rc;
  271. }
  272. #endif