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.

357 lines
7.0 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2001
  5. //
  6. // File: cache.cxx
  7. //
  8. // Contents: Class Store Binding cache
  9. //
  10. // Author: AdamEd
  11. //
  12. //-------------------------------------------------------------------------
  13. #include "cstore.hxx"
  14. CBinding::CBinding(
  15. CServerContext* pServerContext,
  16. WCHAR* wszClassStorePath,
  17. PSID pSid,
  18. IClassAccess* pClassAccess,
  19. HRESULT hrBind,
  20. HRESULT* phr)
  21. {
  22. ULONG ulSize;
  23. *phr = E_OUTOFMEMORY;
  24. Hr = hrBind;
  25. ulSize = lstrlen( wszClassStorePath ) + 1;
  26. szStorePath = (WCHAR*) CsMemAlloc(
  27. ulSize * sizeof( *wszClassStorePath ) );
  28. if ( szStorePath )
  29. {
  30. UINT dwBytesRequired;
  31. *phr = StringCchCopy( szStorePath, ulSize, wszClassStorePath );
  32. if ( SUCCEEDED( *phr ) && pServerContext )
  33. {
  34. *phr =ServerContext.Initialize( pServerContext );
  35. }
  36. if (SUCCEEDED(*phr))
  37. {
  38. dwBytesRequired = GetLengthSid(pSid);
  39. Sid = (PSID) CsMemAlloc( dwBytesRequired );
  40. if ( Sid )
  41. {
  42. BOOL bStatus;
  43. bStatus = CopySid(
  44. dwBytesRequired,
  45. Sid,
  46. pSid);
  47. if ( ! bStatus )
  48. {
  49. LONG Status;
  50. Status = GetLastError();
  51. *phr = HRESULT_FROM_WIN32( Status );
  52. }
  53. else
  54. {
  55. *phr = S_OK;
  56. }
  57. }
  58. }
  59. }
  60. if ( SUCCEEDED( *phr ) && pClassAccess )
  61. {
  62. pIClassAccess = pClassAccess;
  63. pIClassAccess->AddRef();
  64. }
  65. }
  66. CBinding::~CBinding()
  67. {
  68. if ( pIClassAccess )
  69. {
  70. pIClassAccess->Release();
  71. }
  72. CsMemFree( Sid );
  73. CsMemFree( szStorePath );
  74. }
  75. BOOL
  76. CBinding::Compare(
  77. CServerContext* pServerContext,
  78. WCHAR* wszClassStorePath,
  79. PSID pSid)
  80. {
  81. LONG lCompare;
  82. BOOL bStatus;
  83. bStatus = FALSE;
  84. lCompare = lstrcmp(
  85. szStorePath,
  86. wszClassStorePath);
  87. if ( 0 == lCompare )
  88. {
  89. if ( ServerContext.Compare( pServerContext ) )
  90. {
  91. lCompare = 0;
  92. }
  93. else
  94. {
  95. lCompare = -1;
  96. }
  97. }
  98. if ( 0 == lCompare )
  99. {
  100. bStatus = EqualSid(
  101. Sid,
  102. pSid);
  103. }
  104. return bStatus;
  105. }
  106. BOOL CBinding::IsExpired( FILETIME* pftCurrentTime )
  107. {
  108. SYSTEMTIME SystemTimeCurrent;
  109. SYSTEMTIME SystemTimeExpiration;
  110. BOOL bRetrievedTime;
  111. bRetrievedTime = FileTimeToSystemTime(
  112. pftCurrentTime,
  113. &SystemTimeCurrent);
  114. bRetrievedTime &= FileTimeToSystemTime(
  115. &Time,
  116. &SystemTimeExpiration);
  117. if ( bRetrievedTime )
  118. {
  119. CSDBGPrint((
  120. DM_VERBOSE,
  121. IDS_CSTORE_CACHE_EXPIRE,
  122. L"Current Time",
  123. SystemTimeCurrent.wMonth,
  124. SystemTimeCurrent.wDay,
  125. SystemTimeCurrent.wYear,
  126. SystemTimeCurrent.wHour,
  127. SystemTimeCurrent.wMinute,
  128. SystemTimeCurrent.wSecond));
  129. CSDBGPrint((
  130. DM_VERBOSE,
  131. IDS_CSTORE_CACHE_EXPIRE,
  132. L"Expire Time",
  133. SystemTimeExpiration.wMonth,
  134. SystemTimeExpiration.wDay,
  135. SystemTimeExpiration.wYear,
  136. SystemTimeExpiration.wHour,
  137. SystemTimeExpiration.wMinute,
  138. SystemTimeExpiration.wSecond));
  139. }
  140. //
  141. // Compare the current time to the expiration time
  142. //
  143. LONG CompareResult;
  144. CompareResult = CompareFileTime(
  145. pftCurrentTime,
  146. &Time);
  147. //
  148. // If the current time is later than the expired time,
  149. // then we have expired
  150. //
  151. if ( CompareResult > 0 )
  152. {
  153. return TRUE;
  154. }
  155. return FALSE;
  156. }
  157. CBindingList::CBindingList() :
  158. _cBindings( 0 )
  159. {
  160. memset( &_ListLock, 0, sizeof( _ListLock ) );
  161. //
  162. // InitializeCriticalSection has no return value --
  163. // in extremely low memory situations, it may
  164. // throw an exception
  165. //
  166. (void) InitializeCriticalSection( &_ListLock );
  167. }
  168. CBindingList::~CBindingList()
  169. {
  170. CBinding* pBinding;
  171. for (
  172. Reset();
  173. pBinding = (CBinding*) GetCurrentItem();
  174. )
  175. {
  176. //
  177. // We must perform the MoveNext before the Delete
  178. // since it alters the list and will render its
  179. // current pointer invalid
  180. //
  181. MoveNext();
  182. Delete( pBinding );
  183. }
  184. //
  185. // Clean up the critical section allocated in the constructor
  186. //
  187. DeleteCriticalSection( &_ListLock );
  188. }
  189. void
  190. CBindingList::Lock()
  191. {
  192. EnterCriticalSection( &_ListLock );
  193. }
  194. void
  195. CBindingList::Unlock()
  196. {
  197. LeaveCriticalSection( &_ListLock );
  198. }
  199. CBinding*
  200. CBindingList::Find(
  201. CServerContext* pServerContext,
  202. FILETIME* pCurrentTime,
  203. WCHAR* wszClassStorePath,
  204. PSID pSid)
  205. {
  206. CBinding* pCurrent;
  207. CBinding* pExpired;
  208. pCurrent = NULL;
  209. for ( Reset();
  210. pCurrent = (CBinding*) GetCurrentItem();
  211. MoveNext(), Delete( pExpired ) )
  212. {
  213. BOOL bFound;
  214. if ( pCurrent->IsExpired( pCurrentTime ) )
  215. {
  216. pExpired = pCurrent;
  217. continue;
  218. }
  219. pExpired = NULL;
  220. bFound = pCurrent->Compare(
  221. pServerContext,
  222. wszClassStorePath,
  223. pSid);
  224. if ( bFound )
  225. {
  226. CSDBGPrint((DM_WARNING,
  227. IDS_CSTORE_CSCACHE_HIT,
  228. wszClassStorePath));
  229. return pCurrent;
  230. }
  231. }
  232. return NULL;
  233. }
  234. CBinding*
  235. CBindingList::AddBinding(
  236. FILETIME* pCurrentTime,
  237. CBinding* pBinding)
  238. {
  239. CBinding* pExisting;
  240. pExisting = Find(
  241. &(pBinding->ServerContext),
  242. pCurrentTime,
  243. pBinding->szStorePath,
  244. pBinding->Sid);
  245. if ( pExisting )
  246. {
  247. delete pBinding;
  248. return pExisting;
  249. }
  250. if ( _cBindings >= MAXCLASSSTORES )
  251. {
  252. Reset();
  253. Delete( (CBinding*) GetCurrentItem() );
  254. }
  255. GetExpiredTime(
  256. pCurrentTime,
  257. &(pBinding->Time));
  258. InsertFIFO( pBinding );
  259. _cBindings++;
  260. return pBinding;
  261. }
  262. void
  263. CBindingList::Delete( CBinding* pBinding )
  264. {
  265. if ( pBinding )
  266. {
  267. CSDBGPrint((DM_WARNING,
  268. IDS_CSTORE_CSCACHEPURGE,
  269. pBinding->szStorePath));
  270. pBinding->Remove();
  271. delete pBinding;
  272. _cBindings--;
  273. }
  274. }