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.

331 lines
10 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. // The following is set for a successful DLL_PROCESS_DETACH.
  93. static BOOL g_fEnableProcessDetach = FALSE;
  94. //+-------------------------------------------------------------------------
  95. // Return TRUE if DLL_PROCESS_DETACH is called for FreeLibrary instead
  96. // of ProcessExit. The third parameter, lpvReserved, passed to DllMain
  97. // is NULL for FreeLibrary and non-NULL for ProcessExit.
  98. //
  99. // Also for debugging purposes, check the following environment variables:
  100. // CRYPT_DEBUG_FORCE_FREE_LIBRARY != 0 (retail and checked)
  101. // DEBUG_MASK & 0x20 (only checked)
  102. //
  103. // If either of the above environment variables is present and satisfies
  104. // the expression, TRUE is returned.
  105. //--------------------------------------------------------------------------
  106. BOOL
  107. WINAPI
  108. I_CryptIsProcessDetachFreeLibrary(
  109. LPVOID lpvReserved // Third parameter passed to DllMain
  110. )
  111. {
  112. #define ENV_LEN 32
  113. char rgch[ENV_LEN + 1];
  114. DWORD cch;
  115. if (NULL == lpvReserved)
  116. return TRUE;
  117. cch = GetEnvironmentVariableA(
  118. "CRYPT_DEBUG_FORCE_FREE_LIBRARY",
  119. rgch,
  120. ENV_LEN
  121. );
  122. if (cch && cch <= ENV_LEN) {
  123. long lValue;
  124. rgch[cch] = '\0';
  125. lValue = atol(rgch);
  126. if (lValue)
  127. return TRUE;
  128. }
  129. #if DBG
  130. if (DbgGetDebugFlags() & DEBUG_MASK_LEAK_CHECK)
  131. return TRUE;
  132. #endif
  133. return FALSE;
  134. }
  135. //+-------------------------------------------------------------------------
  136. // Dll initialization
  137. //--------------------------------------------------------------------------
  138. BOOL WINAPI DllMain(
  139. HMODULE hInstDLL,
  140. DWORD fdwReason,
  141. LPVOID lpvReserved
  142. )
  143. {
  144. BOOL fReturn = TRUE;
  145. int i;
  146. #if DBG
  147. // NB- Due to an apparent bug in the Win95 loader, the CRT gets unloaded
  148. // too early in some circumstances. In particular, it can get unloaded
  149. // before this routine executes at process detach time. This can cause
  150. // faults when executing this routine, and also when executing the rest
  151. // of CRYPT32:CRT_INIT, after this initroutine returns. Ergo, we do an
  152. // extra load of the CRT, to be sure it stays around long enough.
  153. if ((fdwReason == DLL_PROCESS_ATTACH) && (!FIsWinNT()))
  154. LoadLibrary( "MSVCRTD.DLL");
  155. #endif
  156. switch (fdwReason) {
  157. case DLL_PROCESS_DETACH:
  158. if( g_hCryptUI ) {
  159. FreeLibrary( g_hCryptUI );
  160. g_hCryptUI = NULL;
  161. }
  162. if (!g_fEnableProcessDetach)
  163. return TRUE;
  164. else
  165. g_fEnableProcessDetach = FALSE;
  166. if (!I_CryptIsProcessDetachFreeLibrary(lpvReserved)) {
  167. // Process Exit. I have seen cases where other Dlls, like
  168. // wininet.dll, depend on crypt32.dll. However, crypt32.dll
  169. // gets called first at ProcessDetach. Since all the memory
  170. // and kernel handles will get freed anyway by the kernel,
  171. // we can skip the following detach freeing.
  172. // Always need to free shared memory used for certificate
  173. // performance counters
  174. CertPerfDllMain(hInstDLL, fdwReason, lpvReserved);
  175. return TRUE;
  176. }
  177. // Fall through for FreeLibrary
  178. case DLL_THREAD_DETACH:
  179. for (i = DLL_MAIN_FUNC_COUNT - 1; i >= 0; i--)
  180. fReturn &= rgpfnDllMain[i](hInstDLL, fdwReason, lpvReserved);
  181. break;
  182. case DLL_PROCESS_ATTACH:
  183. for (i = 0; i < DLL_MAIN_FUNC_COUNT; i++) {
  184. fReturn = rgpfnDllMain[i](hInstDLL, fdwReason, lpvReserved);
  185. if (!fReturn)
  186. break;
  187. }
  188. if (!fReturn) {
  189. for (i--; i >= 0; i--)
  190. rgpfnDllMain[i](hInstDLL, DLL_PROCESS_DETACH, NULL);
  191. } else
  192. g_fEnableProcessDetach = TRUE;
  193. break;
  194. case DLL_THREAD_ATTACH:
  195. default:
  196. for (i = 0; i < DLL_MAIN_FUNC_COUNT; i++)
  197. fReturn &= rgpfnDllMain[i](hInstDLL, fdwReason, lpvReserved);
  198. break;
  199. }
  200. return(fReturn);
  201. }
  202. #if 1
  203. typedef
  204. DWORD
  205. (WINAPI *PFN_I_CryptUIProtect)(
  206. IN PVOID pvReserved1,
  207. IN PVOID pvReserved2,
  208. IN DWORD dwReserved3,
  209. IN PVOID *pvReserved4,
  210. IN BOOL fReserved5,
  211. IN PVOID pvReserved6
  212. );
  213. extern "C"
  214. DWORD
  215. WINAPI
  216. I_CryptUIProtect(
  217. IN PVOID pvReserved1,
  218. IN PVOID pvReserved2,
  219. IN DWORD dwReserved3,
  220. IN PVOID *pvReserved4,
  221. IN BOOL fReserved5,
  222. IN PVOID pvReserved6
  223. )
  224. {
  225. static PFN_I_CryptUIProtect pfn;
  226. DWORD rc;
  227. if ( g_hCryptUI == NULL ) {
  228. g_hCryptUI = LoadLibrary(TEXT("cryptui.dll"));
  229. if( g_hCryptUI == NULL )
  230. return GetLastError();
  231. }
  232. if ( pfn == NULL ) {
  233. pfn = (PFN_I_CryptUIProtect)GetProcAddress(g_hCryptUI, "I_CryptUIProtect");
  234. }
  235. if ( pfn != NULL ) {
  236. rc = (*pfn)(pvReserved1, pvReserved2, dwReserved3, pvReserved4, fReserved5, pvReserved6);
  237. } else {
  238. rc = GetLastError();
  239. if( rc == ERROR_SUCCESS )
  240. rc = ERROR_INVALID_PARAMETER;
  241. }
  242. return rc;
  243. }
  244. typedef
  245. DWORD
  246. (WINAPI *PFN_I_CryptUIProtectFailure)(
  247. IN PVOID pvReserved1,
  248. IN DWORD dwReserved2,
  249. IN PVOID *pvReserved3
  250. );
  251. extern "C"
  252. DWORD
  253. WINAPI
  254. I_CryptUIProtectFailure(
  255. IN PVOID pvReserved1,
  256. IN DWORD dwReserved2,
  257. IN PVOID *pvReserved3
  258. )
  259. {
  260. static PFN_I_CryptUIProtectFailure pfn;
  261. DWORD rc;
  262. if ( g_hCryptUI == NULL ) {
  263. g_hCryptUI = LoadLibrary(TEXT("cryptui.dll"));
  264. if( g_hCryptUI == NULL )
  265. return GetLastError();
  266. }
  267. if ( pfn == NULL ) {
  268. pfn = (PFN_I_CryptUIProtectFailure)GetProcAddress(g_hCryptUI, "I_CryptUIProtectFailure");
  269. }
  270. if ( pfn != NULL ) {
  271. rc = (*pfn)(pvReserved1, dwReserved2, pvReserved3);
  272. } else {
  273. rc = GetLastError();
  274. if( rc == ERROR_SUCCESS )
  275. rc = ERROR_INVALID_PARAMETER;
  276. }
  277. return rc;
  278. }
  279. #endif