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.

224 lines
4.7 KiB

  1. #include "nds.hxx"
  2. #pragma hdrstop
  3. NDS_CONTEXT BindCache ;
  4. DWORD BindCacheCount = 0 ;
  5. //
  6. // Initializes a cache entry
  7. //
  8. HRESULT BindCacheAllocEntry(NDS_CONTEXT **ppCacheEntry)
  9. {
  10. NDS_CONTEXT *pCacheEntry ;
  11. *ppCacheEntry = NULL ;
  12. if (!(pCacheEntry = (PNDS_CONTEXT)AllocADsMem(sizeof(NDS_CONTEXT)))) {
  13. RRETURN(E_OUTOFMEMORY);
  14. }
  15. pCacheEntry->RefCount = 0;
  16. pCacheEntry->Flags = 0;
  17. pCacheEntry->List.Flink = NULL ;
  18. pCacheEntry->List.Blink = NULL ;
  19. *ppCacheEntry = pCacheEntry ;
  20. RRETURN(S_OK);
  21. }
  22. //
  23. // Invalidates a cache entry so it will not be used.
  24. //
  25. VOID BindCacheInvalidateEntry(NDS_CONTEXT *pCacheEntry)
  26. {
  27. pCacheEntry->Flags |= NDS_CACHE_INVALID ;
  28. }
  29. //
  30. // Lookup an entry in the cache. Does not take into account timeouts.
  31. // Increments ref count if found.
  32. //
  33. PNDS_CONTEXT
  34. BindCacheLookup(
  35. LPWSTR pszNDSTreeName,
  36. CCredentials& Credentials
  37. )
  38. {
  39. DWORD i ;
  40. PNDS_CONTEXT pEntry = (PNDS_CONTEXT) BindCache.List.Flink ;
  41. //
  42. // Loop thru looking for match. A match is defined as:
  43. // tree name and credentials, and it is NOT invalid.
  44. //
  45. while (pEntry != &BindCache) {
  46. if (!(pEntry->Flags & NDS_CACHE_INVALID) &&
  47. (((pszNDSTreeName != NULL) && (pEntry->pszNDSTreeName != NULL) &&
  48. (wcscmp(pEntry->pszNDSTreeName, pszNDSTreeName) == 0)) ||
  49. (pEntry->pszNDSTreeName == NULL && pszNDSTreeName == NULL)) &&
  50. (*(pEntry->pCredentials) == Credentials)) {
  51. ++pEntry->RefCount ;
  52. return(pEntry) ;
  53. }
  54. pEntry = (PNDS_CONTEXT)pEntry->List.Flink ;
  55. }
  56. return NULL ;
  57. }
  58. //
  59. // Add entry to cache
  60. //
  61. HRESULT
  62. BindCacheAdd(
  63. LPWSTR pszNDSTreeName,
  64. CCredentials& Credentials,
  65. BOOL fLoggedIn,
  66. PNDS_CONTEXT pCacheEntry)
  67. {
  68. if (BindCacheCount > MAX_BIND_CACHE_SIZE) {
  69. //
  70. // If exceed limit, just dont put in cache. Since we leave the
  71. // RefCount & the Links unset, the deref will simply note that
  72. // this entry is not in cache and allow it to be freed.
  73. //
  74. // We limit cache so that if someone leaks handles we dont over
  75. // time end up traversing this huge linked list.
  76. //
  77. RRETURN(S_OK) ;
  78. }
  79. LPWSTR pszTreeName = (LPWSTR) AllocADsMem(
  80. (wcslen(pszNDSTreeName)+1)*sizeof(WCHAR)) ;
  81. if (!pszTreeName) {
  82. RRETURN(E_OUTOFMEMORY);
  83. }
  84. CCredentials * pCredentials = new CCredentials(Credentials);
  85. if (!pCredentials) {
  86. FreeADsMem(pszTreeName);
  87. RRETURN(E_OUTOFMEMORY);
  88. }
  89. //
  90. // setup the data
  91. //
  92. wcscpy(pszTreeName,pszNDSTreeName) ;
  93. pCacheEntry->pszNDSTreeName = pszTreeName;
  94. pCacheEntry->pCredentials = pCredentials;
  95. pCacheEntry->RefCount = 1 ;
  96. pCacheEntry->fLoggedIn = fLoggedIn;
  97. //
  98. // insert into list
  99. //
  100. InsertHeadList(&BindCache.List, &pCacheEntry->List) ;
  101. ++BindCacheCount ;
  102. RRETURN(S_OK);
  103. }
  104. //
  105. // Dereference an entry in the cache. Removes if ref count is zero.
  106. // Returns the final ref count or zero if not there. If zero, caller
  107. // should close the handle.
  108. //
  109. DWORD BindCacheDeref(NDS_CONTEXT *pCacheEntry)
  110. {
  111. DWORD i=0;
  112. ENTER_BIND_CRITSECT() ;
  113. if ((pCacheEntry->List.Flink == NULL) &&
  114. (pCacheEntry->List.Blink == NULL) &&
  115. (pCacheEntry->RefCount == NULL)) {
  116. //
  117. // this is one of the entries that never got into the cache.
  118. //
  119. LEAVE_BIND_CRITSECT() ;
  120. return(0) ;
  121. }
  122. ADsAssert(pCacheEntry->List.Flink) ;
  123. ADsAssert(pCacheEntry->RefCount > 0) ;
  124. //
  125. // Dereference by one. If result is non zero, just return.
  126. //
  127. --pCacheEntry->RefCount ;
  128. if (pCacheEntry->RefCount) {
  129. LEAVE_BIND_CRITSECT() ;
  130. return(pCacheEntry->RefCount) ;
  131. }
  132. //
  133. // This entry can be cleaned up.
  134. //
  135. --BindCacheCount ;
  136. (void) FreeADsMem(pCacheEntry->pszNDSTreeName) ;
  137. pCacheEntry->pszNDSTreeName = NULL ;
  138. delete pCacheEntry->pCredentials;
  139. pCacheEntry->pCredentials = NULL;
  140. RemoveEntryList(&pCacheEntry->List) ;
  141. LEAVE_BIND_CRITSECT() ;
  142. return 0 ;
  143. }
  144. VOID
  145. BindCacheInit(
  146. VOID
  147. )
  148. {
  149. InitializeCriticalSection(&BindCacheCritSect) ;
  150. InitializeListHead(&BindCache.List) ;
  151. }
  152. VOID
  153. BindCacheCleanup(
  154. VOID
  155. )
  156. {
  157. PNDS_CONTEXT pEntry = (PNDS_CONTEXT) BindCache.List.Flink ;
  158. while (pEntry != &BindCache) {
  159. PNDS_CONTEXT pNext = (PNDS_CONTEXT) pEntry->List.Flink;
  160. (void) FreeADsMem(pEntry->pszNDSTreeName) ;
  161. pEntry->pszNDSTreeName = NULL ;
  162. RemoveEntryList(&pEntry->List) ;
  163. pEntry = pNext;
  164. }
  165. DeleteCriticalSection(&BindCacheCritSect);
  166. }