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.

769 lines
25 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. //
  4. // File: DomCfg.cpp
  5. //
  6. // Description: Implementation of CDomainConfigTable and CInternalDomainInfo
  7. //
  8. // Author: mikeswa
  9. //
  10. // Copyright (C) 1998 Microsoft Corporation
  11. //
  12. //-----------------------------------------------------------------------------
  13. #include "aqprecmp.h"
  14. #include <domhash.h>
  15. #include "domcfg.h"
  16. #include "aqutil.h"
  17. //Encourage compiler to include symbols for enums
  18. eDomainInfoFlags g_eDomainInfo = DOMAIN_INFO_USE_SSL;
  19. eIntDomainInfoFlags g_eIntDomainInfo = INT_DOMAIN_INFO_INVALID;
  20. //---[ RemoveConfigEntryIteratorFn ]--------------------------------------------
  21. //
  22. //
  23. // Description:
  24. // Deletes and releases all internal domain info objects in table
  25. // Parameters:
  26. // IN pvContext - pointer to context (ignored)
  27. // IN pvData - data entry to look at
  28. // IN fWildcardData - TRUE if data is a wildcard entry (ignored)
  29. // OUT pfContinue - TRUE if iterator should continue to the next entry
  30. // OUT pfRemoveEntry - TRUE if entry should be deleted
  31. // Returns:
  32. // -
  33. // History:
  34. // 6/17/98 - MikeSwa Created
  35. //
  36. //-----------------------------------------------------------------------------
  37. VOID RemoveConfigEntryIteratorFn(PVOID pvContext, PVOID pvData, BOOL fWildcard,
  38. BOOL *pfContinue, BOOL *pfDelete)
  39. {
  40. CInternalDomainInfo *pIntDomainInfo = (CInternalDomainInfo *) pvData;
  41. *pfDelete = TRUE;
  42. *pfContinue = TRUE;
  43. _ASSERT(INT_DOMAIN_INFO_SIG == pIntDomainInfo->m_dwSignature);
  44. pIntDomainInfo->m_dwIntDomainInfoFlags |= INT_DOMAIN_INFO_INVALID;
  45. pIntDomainInfo->Release();
  46. }
  47. //---[ RemoveOutdatedConfigEntryIteratorFn ]------------------------------------
  48. //
  49. //
  50. // Description:
  51. // Deletes and releases all outdated internal domain info objects in table.
  52. // An internal domain entry is considered outdated if its version number
  53. // does not match the global version number.
  54. // Parameters:
  55. // IN pvContext - pointer to context (current version number)
  56. // IN pvData - data entry to look at
  57. // IN fWildcardData - TRUE if data is a wildcard entry (ignored)
  58. // OUT pfContinue - TRUE if iterator should continue to the next entry
  59. // OUT pfRemoveEntry - TRUE if entry should be deleted
  60. // Returns:
  61. // -
  62. // History:
  63. // 9/29/98 - MikeSwa Created
  64. //
  65. //-----------------------------------------------------------------------------
  66. VOID RemoveOutdatedConfigEntryIteratorFn(PVOID pvContext, PVOID pvData,
  67. BOOL fWildcard, BOOL *pfContinue, BOOL *pfDelete)
  68. {
  69. CInternalDomainInfo *pIntDomainInfo = (CInternalDomainInfo *) pvData;
  70. _ASSERT(INT_DOMAIN_INFO_SIG == pIntDomainInfo->m_dwSignature);
  71. _ASSERT(pvContext);
  72. *pfContinue = TRUE;
  73. if (pIntDomainInfo->m_dwVersion != *((DWORD *)pvContext))
  74. {
  75. //make sure it is not the root entry
  76. if ((1*sizeof(CHAR) == pIntDomainInfo->m_DomainInfo.cbDomainNameLength) &&
  77. ('*' == pIntDomainInfo->m_DomainInfo.szDomainName[0]) &&
  78. ('\0' == pIntDomainInfo->m_DomainInfo.szDomainName[1]))
  79. {
  80. //
  81. //NOTE - It is not expected for this to happen. We expect
  82. //SMTP to always provide a default entry. If SMTP changes such
  83. //that does not, then dynamic updates would fail, because we never
  84. //mark the default entry that we create as invalid. Once a link
  85. //picks up this entry, it will never let it go.
  86. //
  87. _ASSERT(0 && "SMTP did not supply a * entry");
  88. //It is the root entry... update verision number
  89. //NOTE: The Root entry is a special case... it is required to be
  90. //present at all times, and is not always inserted into the
  91. //metabase. Because of this, it's version number may be incorrect,
  92. //so we need to make sure that we don't remove it.
  93. *pfDelete = FALSE;
  94. pIntDomainInfo->m_dwVersion = *((DWORD *)pvContext);
  95. }
  96. else
  97. {
  98. //The entry is old
  99. *pfDelete = TRUE;
  100. pIntDomainInfo->m_dwIntDomainInfoFlags |= INT_DOMAIN_INFO_INVALID;
  101. pIntDomainInfo->Release();
  102. }
  103. }
  104. else
  105. {
  106. *pfDelete = FALSE;
  107. }
  108. }
  109. //---[ HrCopyStringProperty ]--------------------------------------------------
  110. //
  111. //
  112. // Description:
  113. // Private helper function that is used to allocate and copy string
  114. // properties in the DomainInfo struct
  115. // Parameters:
  116. // OUT (ref) szDest Dest string to allocate and copy to
  117. // IN szSource Source string to copy
  118. // IN cbLength Length of string (without ending '\0'
  119. // Returns:
  120. // S_OK on success
  121. //
  122. //-----------------------------------------------------------------------------
  123. HRESULT inline HrCopyStringProperty(LPSTR &szDest, const LPSTR szSource,
  124. DWORD cbLength)
  125. {
  126. HRESULT hr = S_OK;
  127. _ASSERT(szSource); //must have a buffer to copy
  128. _ASSERT(!szDest);
  129. szDest = (LPSTR) pvMalloc(cbLength + sizeof(CHAR));
  130. if (!szDest)
  131. {
  132. hr = E_OUTOFMEMORY;
  133. goto Exit;
  134. }
  135. //copy data
  136. memcpy(szDest, szSource, cbLength); //copy string
  137. szDest[cbLength] = '\0';
  138. Exit:
  139. return hr;
  140. }
  141. //---[ COPY_DOMAIN_INFO_STRING_PROP ]------------------------------------------
  142. //
  143. //
  144. // Description:
  145. // Macro used to call private helper function HrCopyStringProperty
  146. // Parameters:
  147. // pOldDomainInfo DomainInfo Struct to copy
  148. // pNewDomainInfo New DomainInfo stuct to copy to
  149. // cbProp Name of size property
  150. // szProp Name of string proptery
  151. // Returns:
  152. //
  153. //
  154. //-----------------------------------------------------------------------------
  155. #define COPY_DOMAIN_INFO_STRING_PROP(pOldDomainInfo, pNewDomainInfo, cbProp, szProp) \
  156. { \
  157. _ASSERT(!(pNewDomainInfo)->cbProp); \
  158. _ASSERT(!(pNewDomainInfo)->szProp); \
  159. (pNewDomainInfo)->cbProp = (pOldDomainInfo)->cbProp; \
  160. if ((pOldDomainInfo)->cbProp) \
  161. hr = HrCopyStringProperty((pNewDomainInfo)->szProp, \
  162. (pOldDomainInfo)->szProp, (pOldDomainInfo)->cbProp); \
  163. }
  164. //---[ CInternalDomainInfo::CInternalDomainInfo ]------------------------------
  165. //
  166. //
  167. // Description:
  168. // Object constructor. Initializes DomainInfo struct
  169. // Parameters:
  170. // DWORD dwVersion Current DomainConfigTable version
  171. // Returns:
  172. // -
  173. // History:
  174. // 9/29/98 - MikeSwa - added version
  175. //
  176. //-----------------------------------------------------------------------------
  177. CInternalDomainInfo::CInternalDomainInfo(DWORD dwVersion)
  178. {
  179. ZeroMemory(&m_DomainInfo.dwDomainInfoFlags, sizeof(DomainInfo) - sizeof(DWORD));
  180. m_dwIntDomainInfoFlags = INT_DOMAIN_INFO_OK;
  181. m_dwSignature = INT_DOMAIN_INFO_SIG;
  182. m_dwVersion = dwVersion;
  183. //make sure our assumptions about the struct of DomainInfo are valid
  184. _ASSERT(1 == ((DWORD *) &m_DomainInfo.dwDomainInfoFlags) - ((DWORD *) &m_DomainInfo));
  185. m_DomainInfo.cbVersion = sizeof(DomainInfo);
  186. }
  187. //---[ CInternalDomainInfo::~CInternalDomainInfo ]-----------------------------
  188. //
  189. //
  190. // Description:
  191. // Class destructor... deallocates any memory associated with the
  192. // DomainInfo struct
  193. // Parameters:
  194. // -
  195. // Returns:
  196. // -
  197. //
  198. //-----------------------------------------------------------------------------
  199. CInternalDomainInfo::~CInternalDomainInfo()
  200. {
  201. _ASSERT(m_DomainInfo.cbVersion == sizeof(DomainInfo));
  202. if (m_DomainInfo.szDomainName)
  203. FreePv(m_DomainInfo.szDomainName);
  204. if (m_DomainInfo.szETRNDomainName)
  205. FreePv(m_DomainInfo.szETRNDomainName);
  206. if (m_DomainInfo.szSmartHostDomainName)
  207. FreePv(m_DomainInfo.szSmartHostDomainName);
  208. if (m_DomainInfo.szDropDirectory)
  209. FreePv(m_DomainInfo.szDropDirectory);
  210. if (m_DomainInfo.szAuthType)
  211. FreePv(m_DomainInfo.szAuthType);
  212. if (m_DomainInfo.szUserName)
  213. FreePv(m_DomainInfo.szUserName);
  214. if (m_DomainInfo.szPassword)
  215. FreePv(m_DomainInfo.szPassword);
  216. if (m_DomainInfo.pvBlob)
  217. FreePv(m_DomainInfo.pvBlob);
  218. }
  219. //---[ CInternalDomainInfo::HrInit ]-------------------------------------------
  220. //
  221. //
  222. // Description:
  223. // Clones a DomainInfo struct and allocates needed memory
  224. // Parameters:
  225. // IN pDomainInfo DomainInfo struct to copy
  226. // Returns:
  227. // S_OK on success
  228. // E_OUTOFMEMORY if allocations fail
  229. //-----------------------------------------------------------------------------
  230. HRESULT CInternalDomainInfo::HrInit(DomainInfo *pDomainInfo)
  231. {
  232. HRESULT hr = S_OK;
  233. m_DomainInfo.dwDomainInfoFlags = pDomainInfo->dwDomainInfoFlags;
  234. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  235. cbDomainNameLength, szDomainName);
  236. if (FAILED(hr))
  237. goto Exit;
  238. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  239. cbETRNDomainNameLength, szETRNDomainName);
  240. if (FAILED(hr))
  241. goto Exit;
  242. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  243. cbSmartHostDomainNameLength, szSmartHostDomainName);
  244. if (FAILED(hr))
  245. goto Exit;
  246. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  247. cbDropDirectoryLength, szDropDirectory);
  248. if (FAILED(hr))
  249. goto Exit;
  250. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  251. cbAuthTypeLength, szAuthType);
  252. if (FAILED(hr))
  253. goto Exit;
  254. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  255. cbUserNameLength, szUserName);
  256. if (FAILED(hr))
  257. goto Exit;
  258. COPY_DOMAIN_INFO_STRING_PROP(pDomainInfo, &m_DomainInfo,
  259. cbPasswordLength, szPassword);
  260. if (FAILED(hr))
  261. goto Exit;
  262. m_DomainInfo.cEtrnDelayTime = pDomainInfo->cEtrnDelayTime;
  263. //Copy the blob
  264. if (pDomainInfo->cbBlob)
  265. {
  266. _ASSERT(pDomainInfo->pvBlob);
  267. m_DomainInfo.pvBlob = (DWORD *) pvMalloc(pDomainInfo->cbBlob);
  268. if (!m_DomainInfo.pvBlob)
  269. {
  270. hr = E_OUTOFMEMORY;
  271. goto Exit;
  272. }
  273. //copy data
  274. memcpy(m_DomainInfo.pvBlob, pDomainInfo->pvBlob, pDomainInfo->cbBlob);
  275. m_DomainInfo.cbBlob = pDomainInfo->cbBlob;
  276. }
  277. Exit:
  278. return hr;
  279. }
  280. //---[ CDomainConfigTable::CDomainConfigTable ]--------------------------------
  281. //
  282. //
  283. // Description:
  284. // Constuctor for CDomainConfig Table
  285. // Parameters:
  286. // -
  287. // Returns:
  288. // -
  289. //
  290. //-----------------------------------------------------------------------------
  291. CDomainConfigTable::CDomainConfigTable() :
  292. m_slPrivateData("CDomainConfigTable")
  293. {
  294. m_dwFlags = 0;
  295. m_dwSignature = DOMAIN_CONFIG_SIG;
  296. m_dwCurrentConfigVersion = 0;
  297. m_pLastStarDomainInfo = NULL;
  298. m_pDefaultDomainConfig = NULL;
  299. }
  300. //---[ CDomainConfigTable::~CDomainConfigTable ]-------------------------------
  301. //
  302. //
  303. // Description:
  304. // Destructor for CDomainConfig Table
  305. // Parameters:
  306. // -
  307. // Returns:
  308. // -
  309. //
  310. //-----------------------------------------------------------------------------
  311. CDomainConfigTable::~CDomainConfigTable()
  312. {
  313. TraceFunctEnterEx((LPARAM) this, "CDomainConfigTable::~CDomainConfigTable");
  314. HRESULT hr = S_OK;
  315. //Delete all entries from the table
  316. if (DOMCFG_DOMAIN_NAME_TABLE_INIT & m_dwFlags)
  317. {
  318. //iterate over all domains and delete entries in hash table
  319. m_dnt.HrIterateOverSubDomains(NULL, RemoveConfigEntryIteratorFn, NULL);
  320. if (m_pDefaultDomainConfig != NULL) {
  321. m_pDefaultDomainConfig->Release();
  322. m_pDefaultDomainConfig = NULL;
  323. }
  324. m_dwFlags ^= DOMCFG_DOMAIN_NAME_TABLE_INIT;
  325. }
  326. TraceFunctLeave();
  327. }
  328. //---[ CDomainConfigTable::HrInit ]--------------------------------------------
  329. //
  330. //
  331. // Description:
  332. // Initializes DOMAIN_NAME_TABLE hash table
  333. // Parameters:
  334. // -
  335. // Returns:
  336. // S_OK on success
  337. //
  338. //-----------------------------------------------------------------------------
  339. HRESULT CDomainConfigTable::HrInit()
  340. {
  341. TraceFunctEnterEx((LPARAM) this, "CDomainConfigTable::HrInit");
  342. HRESULT hr = S_OK;
  343. CInternalDomainInfo *pIntDomainInfoDefault = NULL;
  344. DOMAIN_STRING strDomain;
  345. hr = m_dnt.HrInit();
  346. if (FAILED(hr))
  347. goto Exit;
  348. m_dwFlags |= DOMCFG_DOMAIN_NAME_TABLE_INIT;
  349. //Part 1
  350. //
  351. //Allocate an InternalDomainInfo for m_pDefaultDomainConfig. This
  352. //will be used for links/connections for which a routing sink has returned
  353. //no connector
  354. m_pDefaultDomainConfig = new CInternalDomainInfo(m_dwCurrentConfigVersion);
  355. if (!m_pDefaultDomainConfig)
  356. {
  357. hr = E_OUTOFMEMORY;
  358. goto Exit;
  359. }
  360. m_pDefaultDomainConfig->m_DomainInfo.cbDomainNameLength = 1;
  361. m_pDefaultDomainConfig->m_DomainInfo.szDomainName =
  362. (LPSTR) pvMalloc(2*sizeof(CHAR));
  363. if (!m_pDefaultDomainConfig->m_DomainInfo.szDomainName)
  364. {
  365. hr = E_OUTOFMEMORY;
  366. goto Exit;
  367. }
  368. memcpy(m_pDefaultDomainConfig->m_DomainInfo.szDomainName, "*", 2);
  369. //Part 2
  370. //
  371. //Create default "*" entry in the DCT so that arbitrary domains will have
  372. //something to match against. Note that this entry is separate from the
  373. //m_pDefaultDomainConfig entry that is *not* part of the DCT, and is used
  374. //for links/connections that are *not* supposed to match anything in the DCT
  375. pIntDomainInfoDefault = new CInternalDomainInfo(m_dwCurrentConfigVersion);
  376. if (!pIntDomainInfoDefault)
  377. {
  378. hr = E_OUTOFMEMORY;
  379. goto Exit;
  380. }
  381. pIntDomainInfoDefault->m_DomainInfo.cbDomainNameLength = 1;
  382. pIntDomainInfoDefault->m_DomainInfo.szDomainName = (LPSTR) pvMalloc(2*sizeof(CHAR));
  383. if (!pIntDomainInfoDefault->m_DomainInfo.szDomainName)
  384. {
  385. hr = E_OUTOFMEMORY;
  386. goto Exit;
  387. }
  388. memcpy(pIntDomainInfoDefault->m_DomainInfo.szDomainName, "*", 2);
  389. strDomain.Length = (USHORT) pIntDomainInfoDefault->m_DomainInfo.cbDomainNameLength;
  390. strDomain.MaximumLength = strDomain.Length;
  391. strDomain.Buffer = pIntDomainInfoDefault->m_DomainInfo.szDomainName;
  392. hr = m_dnt.HrInsertDomainName(&strDomain, (PVOID) pIntDomainInfoDefault);
  393. if (FAILED(hr))
  394. goto Exit;
  395. Exit:
  396. TraceFunctLeave();
  397. return hr;
  398. }
  399. //---[ CDomainConfigTable::HrSetInternalDomainInfo ]---------------------------
  400. //
  401. //
  402. // Description:
  403. // Inserts InternalDomainInfo into hash table based on szDomain
  404. // Parameters:
  405. // IN pIntDomainInfo Internal DomainInfo to insert
  406. // Returns:
  407. // S_OK on success
  408. //
  409. //-----------------------------------------------------------------------------
  410. HRESULT CDomainConfigTable::HrSetInternalDomainInfo(
  411. IN CInternalDomainInfo *pIntDomainInfo)
  412. {
  413. TraceFunctEnterEx((LPARAM) this, "CDomainConfigTable::SetInternalDomainInfo");
  414. HRESULT hr = S_OK;
  415. DOMAIN_STRING strDomain;
  416. CInternalDomainInfo *pIntDomainInfoCurrent = NULL;
  417. _ASSERT(pIntDomainInfo);
  418. _ASSERT(pIntDomainInfo->m_DomainInfo.szDomainName);
  419. _ASSERT(pIntDomainInfo->m_DomainInfo.cbDomainNameLength);
  420. _ASSERT(pIntDomainInfo->m_dwVersion == m_dwCurrentConfigVersion);
  421. strDomain.Length = (USHORT) pIntDomainInfo->m_DomainInfo.cbDomainNameLength;
  422. strDomain.MaximumLength = (USHORT) pIntDomainInfo->m_DomainInfo.cbDomainNameLength;
  423. strDomain.Buffer = pIntDomainInfo->m_DomainInfo.szDomainName;
  424. pIntDomainInfo->AddRef();
  425. //Get Lock on table
  426. m_slPrivateData.ExclusiveLock();
  427. //HACK ALERT
  428. //
  429. //SMTP calls this routine with info from one of two places:
  430. //1. For each domain configured in the /smtpsvc/1/domains container in the
  431. // metabase. In PT, these entries are populated from address spaces on
  432. // connectors.
  433. //2. For outbound-security configured at the /smtpsvc/1 (ie, at the VS)
  434. // level, it creates a "dummy" entry for the "*" domain.
  435. //
  436. //Unfortunately, this creates a problem if you have a connector with the
  437. // * address space, because the insertion in item 2 will overwrite the
  438. // insertion for * in item 1.
  439. //To handle this case, we keep the "last" * entry received in the
  440. // m_pLastStarDomainInfo. If we receive a second entry, then we know the
  441. // m_pLastStarDomainInfo is a domain entry from item 1. Otherwise, it
  442. // is the default config info.
  443. //
  444. //
  445. //If this is the "*" domain, then store it in m_pLastStarDomainInfo, until
  446. //we decide whether this is really the star domain info from item 1 or
  447. //the info from item 2
  448. //
  449. if (pIntDomainInfo->m_DomainInfo.cbDomainNameLength == 1 &&
  450. pIntDomainInfo->m_DomainInfo.szDomainName[0] == '*') {
  451. if (m_pLastStarDomainInfo == NULL) {
  452. m_pLastStarDomainInfo = pIntDomainInfo;
  453. hr = S_OK;
  454. goto Exit;
  455. } else {
  456. // This is the second * domain entry we have seen. Insert the
  457. // previous entry into the DMT, and keep this one as the last star
  458. // entry seen.
  459. pIntDomainInfoCurrent = pIntDomainInfo;
  460. pIntDomainInfo = m_pLastStarDomainInfo;
  461. m_pLastStarDomainInfo = pIntDomainInfoCurrent;
  462. pIntDomainInfoCurrent = NULL;
  463. dwInterlockedSetBits(&m_dwFlags, DOMCFG_MULTIPLE_STAR_DOMAINS);
  464. }
  465. }
  466. hr = m_dnt.HrInsertDomainName(&strDomain, (PVOID) pIntDomainInfo);
  467. if (FAILED(hr))
  468. {
  469. if (DOMHASH_E_DOMAIN_EXISTS == hr)
  470. {
  471. //someone already inserted for this domain
  472. hr = m_dnt.HrRemoveDomainName(&strDomain,
  473. (PVOID *) &pIntDomainInfoCurrent);
  474. _ASSERT(DOMHASH_E_NO_SUCH_DOMAIN != hr); //someone violated write-lock
  475. if (FAILED(hr))
  476. goto Exit;
  477. _ASSERT(pIntDomainInfoCurrent);
  478. //Mark old info as invalid & release
  479. pIntDomainInfoCurrent->m_dwIntDomainInfoFlags |= INT_DOMAIN_INFO_INVALID;
  480. _ASSERT(pIntDomainInfoCurrent->m_dwVersion <= pIntDomainInfo->m_dwVersion);
  481. pIntDomainInfoCurrent->Release();
  482. pIntDomainInfoCurrent = NULL;
  483. hr = m_dnt.HrInsertDomainName(&strDomain, (PVOID) pIntDomainInfo);
  484. _ASSERT(DOMHASH_E_DOMAIN_EXISTS != hr); //someone violated write-lock
  485. if (FAILED(hr))
  486. goto Exit;
  487. }
  488. else
  489. {
  490. goto Exit;
  491. }
  492. }
  493. Exit:
  494. m_slPrivateData.ExclusiveUnlock();
  495. TraceFunctLeave();
  496. return hr;
  497. }
  498. //---[ CDomainConfigTable::HrGetInternalDomainInfo ]---------------------------
  499. //
  500. //
  501. // Description:
  502. // Gets internal Domaininfo stuct from hash table. Will use wildcard
  503. // matching
  504. // Parameters:
  505. // IN cbDomainnameLength Length of string to search for
  506. // IN szDomainName Domain Name to search for
  507. // OUT ppIntDomainInfo Domain info returned (must be released)
  508. // Returns:
  509. // S_OK if match is found
  510. // AQUEUE_E_INVALID_DOMAIN if no match is found
  511. //
  512. //-----------------------------------------------------------------------------
  513. HRESULT CDomainConfigTable::HrGetInternalDomainInfo(
  514. IN DWORD cbDomainNameLength,
  515. IN LPSTR szDomainName,
  516. OUT CInternalDomainInfo **ppIntDomainInfo)
  517. {
  518. TraceFunctEnterEx((LPARAM) this, "CDomainConfigTable::GetInternalDomainInfo");
  519. HRESULT hr = S_OK;
  520. DOMAIN_STRING strDomain;
  521. _ASSERT(cbDomainNameLength);
  522. _ASSERT(szDomainName);
  523. _ASSERT(ppIntDomainInfo);
  524. strDomain.Length = (USHORT) cbDomainNameLength;
  525. strDomain.MaximumLength = (USHORT) cbDomainNameLength;
  526. strDomain.Buffer = szDomainName;
  527. m_slPrivateData.ShareLock();
  528. //Use wildcard lookup
  529. hr = m_dnt.HrFindDomainName(&strDomain, (PVOID *) ppIntDomainInfo, FALSE);
  530. if (FAILED(hr))
  531. {
  532. //It should at least match the default domain
  533. _ASSERT(DOMHASH_E_NO_SUCH_DOMAIN != hr);
  534. goto Exit;
  535. }
  536. _ASSERT(*ppIntDomainInfo);
  537. (*ppIntDomainInfo)->AddRef();
  538. Exit:
  539. m_slPrivateData.ShareUnlock();
  540. TraceFunctLeave();
  541. return hr;
  542. }
  543. //---[ CDomainConfigTable::HrGetDefaultDomainInfo ]---------------------------
  544. //
  545. //
  546. // Description:
  547. // Gets internal Default Domaininfo stuct.
  548. // Parameters:
  549. // OUT ppIntDomainInfo Domain info returned (must be released)
  550. // Returns:
  551. // S_OK if successful
  552. // AQUEUE_E_INVALID_DOMAIN if error
  553. //
  554. //-----------------------------------------------------------------------------
  555. HRESULT CDomainConfigTable::HrGetDefaultDomainInfo(
  556. OUT CInternalDomainInfo **ppIntDomainInfo)
  557. {
  558. TraceFunctEnterEx((LPARAM) this, "CDomainConfigTable::GetDefaultDomainInfo");
  559. HRESULT hr = S_OK;
  560. *ppIntDomainInfo = NULL;
  561. m_slPrivateData.ShareLock();
  562. if (m_pDefaultDomainConfig != NULL) {
  563. *ppIntDomainInfo = m_pDefaultDomainConfig;
  564. } else {
  565. hr = AQUEUE_E_INVALID_DOMAIN;
  566. goto Exit;
  567. }
  568. _ASSERT(*ppIntDomainInfo);
  569. (*ppIntDomainInfo)->AddRef();
  570. Exit:
  571. m_slPrivateData.ShareUnlock();
  572. TraceFunctLeave();
  573. return hr;
  574. }
  575. //---[ CDomainConfigTable::StartConfigUpdate ]---------------------------------
  576. //
  577. //
  578. // Description:
  579. // Signals that the metabase has been updated, and we will now begin to
  580. // get updated information. Increments an internal version number that
  581. // will be used to removed old, outdated entries once all of the config
  582. // info has been updated.
  583. // Parameters:
  584. // -
  585. // Returns:
  586. // -
  587. // History:
  588. // 9/29/98 - MikeSwa Created
  589. //
  590. //-----------------------------------------------------------------------------
  591. void CDomainConfigTable::StartConfigUpdate()
  592. {
  593. InterlockedIncrement((PLONG) &m_dwCurrentConfigVersion);
  594. _ASSERT(!(m_dwFlags & DOMCFG_FINISH_UPDATE_PENDING));
  595. _ASSERT(m_pLastStarDomainInfo == NULL);
  596. dwInterlockedSetBits(&m_dwFlags, DOMCFG_FINISH_UPDATE_PENDING);
  597. dwInterlockedUnsetBits(&m_dwFlags, DOMCFG_MULTIPLE_STAR_DOMAINS);
  598. }
  599. //---[ CDomainConfigTable::FinishConfigUpdate ]--------------------------------
  600. //
  601. //
  602. // Description:
  603. // Used to signal when all updated configuration information has been
  604. // passed in. Will then walk all of our cached configuration information
  605. // and remove outdated entries
  606. // Parameters:
  607. // -
  608. // Returns:
  609. // -
  610. // History:
  611. // 9/29/98 - MikeSwa Created
  612. //
  613. //-----------------------------------------------------------------------------
  614. void CDomainConfigTable::FinishConfigUpdate()
  615. {
  616. HRESULT hr = S_OK;
  617. DWORD dwCurrentVersion = m_dwCurrentConfigVersion;
  618. CInternalDomainInfo *pIntDomainInfo = NULL;
  619. //There should be a matching start
  620. _ASSERT(m_dwFlags & DOMCFG_FINISH_UPDATE_PENDING);
  621. //
  622. // Get the last "*" domain in case we need to explicitly update the table
  623. // with it.
  624. //
  625. m_slPrivateData.ShareLock();
  626. pIntDomainInfo = m_pLastStarDomainInfo;
  627. if (pIntDomainInfo)
  628. pIntDomainInfo->AddRef();
  629. m_slPrivateData.ShareUnlock();
  630. //
  631. // If only 1 "*" domain has been configured, then we have not inserted
  632. // it in the DNT, and the actual data there is out of date. We
  633. // need to insert it into the table.
  634. //
  635. if (pIntDomainInfo && !(DOMCFG_MULTIPLE_STAR_DOMAINS & m_dwFlags))
  636. {
  637. HrSetInternalDomainInfo(pIntDomainInfo);
  638. }
  639. //
  640. // Release the internal domain info if we got it.
  641. //
  642. if (pIntDomainInfo)
  643. pIntDomainInfo->Release();
  644. dwInterlockedUnsetBits(&m_dwFlags, DOMCFG_FINISH_UPDATE_PENDING);
  645. //Lock table, remove outdated entries, and update the default domain config
  646. m_slPrivateData.ExclusiveLock();
  647. if (m_pLastStarDomainInfo) {
  648. m_pDefaultDomainConfig->m_dwIntDomainInfoFlags |=
  649. INT_DOMAIN_INFO_INVALID;
  650. m_pDefaultDomainConfig->Release();
  651. m_pDefaultDomainConfig = m_pLastStarDomainInfo;
  652. m_pLastStarDomainInfo = NULL;
  653. }
  654. hr = m_dnt.HrIterateOverSubDomains(NULL,
  655. RemoveOutdatedConfigEntryIteratorFn, &dwCurrentVersion);
  656. m_slPrivateData.ExclusiveUnlock();
  657. if (FAILED(hr))
  658. _ASSERT(DOMHASH_E_NO_SUCH_DOMAIN == hr);
  659. }