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.

379 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: catcache.cpp
  7. //
  8. // Contents: Implementation of Catalog Cache (see catcache.h for details)
  9. //
  10. // History: 26-May-98 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Member: CCatalogCache::Initialize, public
  17. //
  18. // Synopsis: initialize the cache
  19. //
  20. //----------------------------------------------------------------------------
  21. BOOL
  22. CCatalogCache::Initialize ()
  23. {
  24. LRU_CACHE_CONFIG Config;
  25. __try
  26. {
  27. InitializeCriticalSection( &m_Lock );
  28. }
  29. __except(EXCEPTION_EXECUTE_HANDLER)
  30. {
  31. return ( FALSE );
  32. }
  33. memset( &Config, 0, sizeof( Config ) );
  34. m_hCache = NULL;
  35. Config.dwFlags = LRU_CACHE_NO_SERIALIZE;
  36. Config.pfnFree = CatalogCacheFreeEntryData;
  37. Config.pfnHash = CatalogCacheHashIdentifier;
  38. Config.cBuckets = DEFAULT_CATALOG_CACHE_BUCKETS;
  39. Config.MaxEntries = DEFAULT_CATALOG_CACHE_MAX_ENTRIES;
  40. return( I_CryptCreateLruCache( &Config, &m_hCache ) );
  41. }
  42. //+---------------------------------------------------------------------------
  43. //
  44. // Member: CCatalogCache::Uninitialize, public
  45. //
  46. // Synopsis: uninitialize the cache
  47. //
  48. //----------------------------------------------------------------------------
  49. VOID
  50. CCatalogCache::Uninitialize ()
  51. {
  52. if ( m_hCache != NULL )
  53. {
  54. I_CryptFreeLruCache( m_hCache, 0, NULL );
  55. }
  56. DeleteCriticalSection( &m_Lock );
  57. }
  58. //+---------------------------------------------------------------------------
  59. //
  60. // Member: CCatalogCache::IsCacheableWintrustCall, public
  61. //
  62. // Synopsis: is this a cacheable call
  63. //
  64. //----------------------------------------------------------------------------
  65. BOOL
  66. CCatalogCache::IsCacheableWintrustCall (WINTRUST_DATA* pWintrustData)
  67. {
  68. if ( pWintrustData->dwUnionChoice != WTD_CHOICE_CATALOG )
  69. {
  70. return( FALSE );
  71. }
  72. if ( _ISINSTRUCT( WINTRUST_DATA, pWintrustData->cbStruct, hWVTStateData ) )
  73. {
  74. if ( ( pWintrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE ) ||
  75. ( pWintrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE_FLUSH ) )
  76. {
  77. return( TRUE );
  78. }
  79. }
  80. return( FALSE );
  81. }
  82. //+---------------------------------------------------------------------------
  83. //
  84. // Member: CCatalogCache::AdjustWintrustDataToCachedState, public
  85. //
  86. // Synopsis: adjust the wintrust data structure
  87. //
  88. //----------------------------------------------------------------------------
  89. VOID
  90. CCatalogCache::AdjustWintrustDataToCachedState (
  91. WINTRUST_DATA* pWintrustData,
  92. PCATALOG_CACHED_STATE pCachedState,
  93. BOOL fUndoAdjustment
  94. )
  95. {
  96. PCRYPT_PROVIDER_DATA pProvData;
  97. if ( fUndoAdjustment == FALSE )
  98. {
  99. pWintrustData->dwStateAction = WTD_STATEACTION_VERIFY;
  100. if ( pCachedState != NULL )
  101. {
  102. pWintrustData->hWVTStateData = pCachedState->hStateData;
  103. pProvData = WTHelperProvDataFromStateData( pCachedState->hStateData );
  104. pProvData->pWintrustData = pWintrustData;
  105. }
  106. else
  107. {
  108. pWintrustData->hWVTStateData = NULL;
  109. }
  110. }
  111. else
  112. {
  113. if ( pCachedState != NULL )
  114. {
  115. pProvData = WTHelperProvDataFromStateData( pCachedState->hStateData );
  116. pProvData->pWintrustData = NULL;
  117. }
  118. pWintrustData->dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  119. pWintrustData->hWVTStateData = NULL;
  120. }
  121. }
  122. //+---------------------------------------------------------------------------
  123. //
  124. // Member: CCatalogCache::CreateCachedStateFromWintrustData, public
  125. //
  126. // Synopsis: create cached state
  127. //
  128. //----------------------------------------------------------------------------
  129. BOOL
  130. CCatalogCache::CreateCachedStateFromWintrustData (
  131. WINTRUST_DATA* pWintrustData,
  132. PCATALOG_CACHED_STATE* ppCachedState
  133. )
  134. {
  135. BOOL fResult;
  136. PCATALOG_CACHED_STATE pCachedState;
  137. CRYPT_DATA_BLOB Identifier;
  138. PCRYPT_PROVIDER_DATA pProvData;
  139. if ( pWintrustData->hWVTStateData == NULL )
  140. {
  141. return( FALSE );
  142. }
  143. pProvData = WTHelperProvDataFromStateData( pWintrustData->hWVTStateData );
  144. if ( ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_INITPROV ] != ERROR_SUCCESS ) ||
  145. ( ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_OBJPROV ] != ERROR_SUCCESS ) &&
  146. ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_OBJPROV ] != TRUST_E_BAD_DIGEST ) ) ||
  147. ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_SIGPROV ] != ERROR_SUCCESS ) ||
  148. ( pProvData->hMsg == NULL ) )
  149. {
  150. return( FALSE );
  151. }
  152. assert( pProvData->hMsg != NULL );
  153. pCachedState = new CATALOG_CACHED_STATE;
  154. if ( pCachedState != NULL )
  155. {
  156. pCachedState->hStateData = pWintrustData->hWVTStateData;
  157. pCachedState->hEntry = NULL;
  158. Identifier.cbData = wcslen(
  159. pWintrustData->pCatalog->pcwszCatalogFilePath
  160. );
  161. Identifier.cbData *= sizeof( WCHAR );
  162. Identifier.pbData = (LPBYTE)pWintrustData->pCatalog->pcwszCatalogFilePath;
  163. fResult = I_CryptCreateLruEntry(
  164. m_hCache,
  165. &Identifier,
  166. pCachedState,
  167. &pCachedState->hEntry
  168. );
  169. }
  170. else
  171. {
  172. SetLastError( E_OUTOFMEMORY );
  173. fResult = FALSE;
  174. }
  175. if ( fResult == TRUE )
  176. {
  177. *ppCachedState = pCachedState;
  178. }
  179. else
  180. {
  181. delete pCachedState;
  182. }
  183. return( fResult );
  184. }
  185. //+---------------------------------------------------------------------------
  186. //
  187. // Member: CCatalogCache::ReleaseCachedState, public
  188. //
  189. // Synopsis: release the cached state
  190. //
  191. //----------------------------------------------------------------------------
  192. VOID
  193. CCatalogCache::ReleaseCachedState (PCATALOG_CACHED_STATE pCachedState)
  194. {
  195. if ( pCachedState == NULL )
  196. {
  197. return;
  198. }
  199. I_CryptReleaseLruEntry( pCachedState->hEntry );
  200. }
  201. //+---------------------------------------------------------------------------
  202. //
  203. // Member: CCatalogCache::AddCachedState, public
  204. //
  205. // Synopsis: add cached state
  206. //
  207. //----------------------------------------------------------------------------
  208. VOID
  209. CCatalogCache::AddCachedState (PCATALOG_CACHED_STATE pCachedState)
  210. {
  211. I_CryptInsertLruEntry( pCachedState->hEntry, NULL );
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Member: CCatalogCache::RemoveCachedState, public
  216. //
  217. // Synopsis: remove cached state
  218. //
  219. //----------------------------------------------------------------------------
  220. VOID
  221. CCatalogCache::RemoveCachedState (PCATALOG_CACHED_STATE pCachedState)
  222. {
  223. I_CryptRemoveLruEntry( pCachedState->hEntry, 0, NULL );
  224. }
  225. //+---------------------------------------------------------------------------
  226. //
  227. // Member: CCatalogCache::RemoveCachedState, public
  228. //
  229. // Synopsis: remove cached state
  230. //
  231. //----------------------------------------------------------------------------
  232. VOID
  233. CCatalogCache::RemoveCachedState (WINTRUST_DATA* pWintrustData)
  234. {
  235. PCATALOG_CACHED_STATE pCachedState;
  236. pCachedState = FindCachedState( pWintrustData );
  237. if ( pCachedState != NULL )
  238. {
  239. RemoveCachedState( pCachedState );
  240. ReleaseCachedState( pCachedState );
  241. }
  242. }
  243. //+---------------------------------------------------------------------------
  244. //
  245. // Member: CCatalogCache::FindCachedState, public
  246. //
  247. // Synopsis: find cached state, the state is addref'd via the entry
  248. //
  249. //----------------------------------------------------------------------------
  250. PCATALOG_CACHED_STATE
  251. CCatalogCache::FindCachedState (WINTRUST_DATA* pWintrustData)
  252. {
  253. PCATALOG_CACHED_STATE pCachedState;
  254. CRYPT_DATA_BLOB Identifier;
  255. HLRUENTRY hEntry;
  256. Identifier.cbData = wcslen(
  257. pWintrustData->pCatalog->pcwszCatalogFilePath
  258. );
  259. Identifier.cbData *= sizeof( WCHAR );
  260. Identifier.pbData = (LPBYTE)pWintrustData->pCatalog->pcwszCatalogFilePath;
  261. pCachedState = (PCATALOG_CACHED_STATE)I_CryptFindLruEntryData(
  262. m_hCache,
  263. &Identifier,
  264. &hEntry
  265. );
  266. return( pCachedState );
  267. }
  268. //+---------------------------------------------------------------------------
  269. //
  270. // Member: CCatalogCache::FlushCache, public
  271. //
  272. // Synopsis: flush the cache
  273. //
  274. //----------------------------------------------------------------------------
  275. VOID
  276. CCatalogCache::FlushCache ()
  277. {
  278. I_CryptFlushLruCache( m_hCache, 0, NULL );
  279. }
  280. //+---------------------------------------------------------------------------
  281. //
  282. // Function: CatalogCacheFreeEntryData
  283. //
  284. // Synopsis: free entry data
  285. //
  286. //----------------------------------------------------------------------------
  287. VOID WINAPI
  288. CatalogCacheFreeEntryData (LPVOID pvData)
  289. {
  290. PCATALOG_CACHED_STATE pCachedState = (PCATALOG_CACHED_STATE)pvData;
  291. WINTRUST_DATA WintrustData;
  292. GUID ActionGuid;
  293. memset( &ActionGuid, 0, sizeof( ActionGuid ) );
  294. memset( &WintrustData, 0, sizeof( WintrustData ) );
  295. WintrustData.cbStruct = sizeof( WintrustData );
  296. WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
  297. WintrustData.hWVTStateData = pCachedState->hStateData;
  298. WinVerifyTrust( NULL, &ActionGuid, &WintrustData );
  299. delete pCachedState;
  300. }
  301. //+---------------------------------------------------------------------------
  302. //
  303. // Function: CatalogCacheHashIdentifier
  304. //
  305. // Synopsis: hash the name
  306. //
  307. //----------------------------------------------------------------------------
  308. DWORD WINAPI
  309. CatalogCacheHashIdentifier (PCRYPT_DATA_BLOB pIdentifier)
  310. {
  311. DWORD dwHash = 0;
  312. DWORD cb = pIdentifier->cbData;
  313. LPBYTE pb = pIdentifier->pbData;
  314. while ( cb-- )
  315. {
  316. if ( dwHash & 0x80000000 )
  317. {
  318. dwHash = ( dwHash << 1 ) | 1;
  319. }
  320. else
  321. {
  322. dwHash = dwHash << 1;
  323. }
  324. dwHash += *pb++;
  325. }
  326. return( dwHash );
  327. }