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.

151 lines
2.9 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FILE
  4. //
  5. // ntcache.cpp
  6. //
  7. // SYNOPSIS
  8. //
  9. // Defines the class NTCache.
  10. //
  11. // MODIFICATION HISTORY
  12. //
  13. // 05/11/1998 Original version.
  14. // 03/12/1999 Improve locking granularity.
  15. //
  16. ///////////////////////////////////////////////////////////////////////////////
  17. #include <ias.h>
  18. #include <ntcache.h>
  19. //////////
  20. // Utility function for getting the current system time as a 64-bit integer.
  21. //////////
  22. inline DWORDLONG GetSystemTimeAsDWORDLONG() throw ()
  23. {
  24. ULARGE_INTEGER ft;
  25. GetSystemTimeAsFileTime((LPFILETIME)&ft);
  26. return ft.QuadPart;
  27. }
  28. NTCache::~NTCache()
  29. {
  30. clear();
  31. }
  32. void NTCache::clear() throw ()
  33. {
  34. Lock();
  35. // Release all the domains.
  36. for (DomainTable::iterator i = cache.begin(); i.more(); ++i)
  37. {
  38. (*i)->Release();
  39. }
  40. // Clear the hash table.
  41. cache.clear();
  42. Unlock();
  43. }
  44. DWORD NTCache::getConnection(PCWSTR domainName, LDAPConnection** cxn) throw ()
  45. {
  46. _ASSERT(cxn != NULL);
  47. NTDomain* domain;
  48. DWORD status = getDomain(domainName, &domain);
  49. if (status == NO_ERROR)
  50. {
  51. status = domain->getConnection(cxn);
  52. domain->Release();
  53. }
  54. else
  55. {
  56. *cxn = NULL;
  57. }
  58. return status;
  59. }
  60. DWORD NTCache::getDomain(PCWSTR domainName, NTDomain** domain) throw ()
  61. {
  62. _ASSERT(domain != NULL);
  63. DWORD status = NO_ERROR;
  64. Lock();
  65. // Check if we already have an entry for this domainName.
  66. NTDomain* const* existing = cache.find(domainName);
  67. if (existing)
  68. {
  69. (*domain = *existing)->AddRef();
  70. }
  71. else
  72. {
  73. // We don't have this domain, so create a new one ...
  74. *domain = NTDomain::createInstance(domainName);
  75. // Evict expired entries.
  76. evict();
  77. try
  78. {
  79. // Try to insert the domain ...
  80. cache.multi_insert(*domain);
  81. // ... and AddRef if we succeeded.
  82. (*domain)->AddRef();
  83. }
  84. catch (...)
  85. {
  86. // We don't care if the insert failed.
  87. }
  88. }
  89. Unlock();
  90. return *domain ? NO_ERROR : ERROR_NOT_ENOUGH_MEMORY;
  91. }
  92. NTDomain::Mode NTCache::getMode(PCWSTR domainName) throw ()
  93. {
  94. NTDomain::Mode mode = NTDomain::MODE_UNKNOWN;
  95. NTDomain* domain;
  96. if (getDomain(domainName, &domain) == NO_ERROR)
  97. {
  98. mode = domain->getMode();
  99. domain->Release();
  100. }
  101. return mode;
  102. }
  103. void NTCache::evict() throw ()
  104. {
  105. //////////
  106. // Note: This method is not serialized.
  107. //////////
  108. DWORDLONG now = GetSystemTimeAsDWORDLONG();
  109. DomainTable::iterator i = cache.begin();
  110. while (i.more())
  111. {
  112. if ((*i)->isObsolete(now))
  113. {
  114. // The entry has expired, so release and erase.
  115. (*i)->Release();
  116. cache.erase(i);
  117. }
  118. else
  119. {
  120. ++i;
  121. }
  122. }
  123. }