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.

564 lines
22 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. //
  4. // File: domain.h
  5. //
  6. // Description:
  7. // Contains descriptions of the Domain table management structure
  8. //
  9. // Author: mikeswa
  10. //
  11. // Copyright (C) 1997 Microsoft Corporation
  12. //
  13. //-----------------------------------------------------------------------------
  14. #ifndef _DOMAIN_H_
  15. #define _DOMAIN_H_
  16. #include "cmt.h"
  17. #include <baseobj.h>
  18. #include <domhash.h>
  19. #include <rwnew.h>
  20. #include <smtpevent.h>
  21. class CInternalDomainInfo;
  22. class CDestMsgQueue;
  23. class CDomainEntry;
  24. class CDomainMappingTable;
  25. class CAQSvrInst;
  26. class CAQMessageType;
  27. class CLinkMsgQueue;
  28. class CLocalLinkMsgQueue;
  29. class CAQScheduleID;
  30. class CMsgRef;
  31. class CDeliveryContext;
  32. class CAsyncAdminMsgRefQueue;
  33. class CAsyncAdminMailMsgQueue;
  34. class CMailMsgAdminLink;
  35. class CDomainEntryLinkIterator;
  36. class CDomainEntryQueueIterator;
  37. class CDomainEntryIterator;
  38. #include "asyncq.h"
  39. #define DOMAIN_ENTRY_SIG 'tnED'
  40. #define DOMAIN_ENTRY_ITERATOR_SIG 'ItnD'
  41. #define DOMAIN_MAPPING_TABLE_SIG ' TMD'
  42. //Name used for global 'local' link
  43. #define LOCAL_LINK_NAME "LocalLink"
  44. #define UNREACHABLE_LINK_NAME "UnreachableLink"
  45. #define CURRENTLY_UNREACHABLE_LINK_NAME "CurrentlyUnreachableLink"
  46. #define PRECAT_QUEUE_NAME "PreCatQueue"
  47. #define PREROUTING_QUEUE_NAME "PreRoutingQueue"
  48. #define PRESUBMISSION_QUEUE_NAME "PreSubmissionQueue"
  49. #define POSTDSN_QUEUE_NAME "PostDSNGenerationQueue"
  50. // {34E2DCCA-C91A-11d2-A6B1-00C04FA3490A}
  51. static const GUID g_sGuidLocalLink =
  52. { 0x34e2dcca, 0xc91a, 0x11d2, { 0xa6, 0xb1, 0x0, 0xc0, 0x4f, 0xa3, 0x49, 0xa } };
  53. // {CD08CEE0-2A95-11d3-B38E-00C04F6B6167}
  54. static const GUID g_sGuidPrecatLink =
  55. { 0xcd08cee0, 0x2a95, 0x11d3, { 0xb3, 0x8e, 0x0, 0xc0, 0x4f, 0x6b, 0x61, 0x67 } };
  56. // {98C90E90-2BB5-11d3-B390-00C04F6B6167}
  57. static const GUID g_sGuidPreRoutingLink =
  58. { 0x98c90e90, 0x2bb5, 0x11d3, { 0xb3, 0x90, 0x0, 0xc0, 0x4f, 0x6b, 0x61, 0x67 } };
  59. // {0F5C33F2-B83A-41fa-9BE3-69C6D1314E13}
  60. static const GUID g_sGuidPreSubmissionLink =
  61. { 0xf5c33f2, 0xb83a, 0x41fa, { 0x9b, 0xe3, 0x69, 0xc6, 0xd1, 0x31, 0x4e, 0x13 } };
  62. #define DMT_FLAGS_SPECIAL_DELIVERY_SPINLOCK 0x80000000
  63. #define DMT_FLAGS_SPECIAL_DELIVERY_CALLBACK 0x40000000
  64. //Bits used to retry GetNextHop after it has failed. If
  65. //DMT_FLAGS_RESET_ROUTES_IN_PROGRESS is set, then a reset routes attempt is
  66. //in progress, and we should not have more than one attempt pending. If
  67. //DMT_FLAGS_GET_NEXT_HOP_FAILED is set, then a failure has been encountered
  68. //since the last reset routes.
  69. #define DMT_FLAGS_RESET_ROUTES_IN_PROGRESS 0x20000000
  70. #define DMT_FLAGS_GET_NEXT_HOP_FAILED 0x10000000
  71. //---[ DomainMapping ]---------------------------------------------------------
  72. //
  73. //
  74. // Hungarian: dmap, pdmap
  75. //
  76. // unquely identifies a queue / domain name pair.
  77. // Each Domain mapping that contains the same QueueID, belongs to
  78. // same queue.
  79. //
  80. // This entire ID should be treated as an opaque to the outside world.
  81. //
  82. // This class is essentially an abstraction that can allow us to add another
  83. // layer of indirection. Configuration based grouping of queues.... static
  84. // routing instead of dynamic.
  85. //-----------------------------------------------------------------------------
  86. class CDomainMapping
  87. {
  88. public:
  89. //removed constructor so we could have this in a union... works fine, but
  90. //you have to set mapping with manually or via clone
  91. void Clone(IN CDomainMapping *pdmap);
  92. //Returns a ptr to the DestMsgQueue associated with this object
  93. HRESULT HrGetDestMsgQueue(IN CAQMessageType *paqmt,
  94. OUT CDestMsgQueue **ppdmq);
  95. friend class CDomainEntry;
  96. //provide sorting operators
  97. friend bool operator <(CDomainMapping &pdmap1, CDomainMapping &pdmap2)
  98. {return (pdmap1.m_pdentryDomainID < pdmap2.m_pdentryDomainID);};
  99. friend bool operator >(CDomainMapping &pdmap1, CDomainMapping &pdmap2)
  100. {return (pdmap1.m_pdentryDomainID > pdmap2.m_pdentryDomainID);};
  101. friend bool operator <=(CDomainMapping &pdmap1, CDomainMapping &pdmap2)
  102. {return (pdmap1.m_pdentryDomainID <= pdmap2.m_pdentryDomainID);};
  103. friend bool operator >=(CDomainMapping &pdmap1, CDomainMapping &pdmap2)
  104. {return (pdmap1.m_pdentryDomainID >= pdmap2.m_pdentryDomainID);};
  105. //Compressed Queues will not be supported... this will be a sufficient test
  106. friend bool operator ==(CDomainMapping &pdmap1, CDomainMapping &pdmap2)
  107. {return (pdmap1.m_pdentryDomainID == pdmap2.m_pdentryDomainID);};
  108. CDomainEntry *pdentryGetQueueEntry() {return m_pdentryQueueID;};
  109. protected:
  110. CDomainEntry *m_pdentryDomainID;
  111. CDomainEntry *m_pdentryQueueID;
  112. };
  113. //---[ CDomainEntry ]----------------------------------------------------------
  114. //
  115. //
  116. // Hungarian: dentry pdentry
  117. //
  118. // Represents a entry in the Domain Name Mapping Table
  119. //-----------------------------------------------------------------------------
  120. class CDomainEntry : public CBaseObject
  121. {
  122. protected:
  123. DWORD m_dwSignature;
  124. CShareLockInst m_slPrivateData; //Share lock used to maintain lists
  125. CDomainMapping m_dmap; //Domain mapping for this domain
  126. DWORD m_cbDomainName;
  127. LPSTR m_szDomainName; //Domain name for this entry
  128. DWORD m_cQueues;
  129. DWORD m_cLinks;
  130. CAQSvrInst *m_paqinst;
  131. LIST_ENTRY m_liDestQueues; //linked list of dest queues for this domain name
  132. LIST_ENTRY m_liLinks; //linked list of links for this domain name
  133. friend class CDomainEntryIterator;
  134. friend class CDomainEntryLinkIterator;
  135. friend class CDomainEntryQueueIterator;
  136. public:
  137. CDomainEntry(CAQSvrInst *paqinst);
  138. ~CDomainEntry();
  139. HRESULT HrInitialize(
  140. DWORD cbDomainName, //string length of domain name
  141. LPSTR szDomainName, //domain name for entry
  142. CDomainEntry *pdentryQueueID, //primary entry for this domain
  143. CDestMsgQueue *pdmq, //queue prt for this entry
  144. //NULL if not primary
  145. CLinkMsgQueue *plmq);
  146. HRESULT HrDeinitialize();
  147. //Returns the Domain Mapping associated with this object
  148. HRESULT HrGetDomainMapping(OUT CDomainMapping *pdmap);
  149. //Returns the Domain Name associated with this object
  150. //Caller is responsible for freeing string
  151. HRESULT HrGetDomainName(OUT LPSTR *pszDomainName);
  152. //Returns a ptr to the DestMsgQueue associated with this object
  153. HRESULT HrGetDestMsgQueue(IN CAQMessageType *paqmt,
  154. OUT CDestMsgQueue **ppdmq);
  155. //Add a queue to this domain entry if one does not already exist for that message type
  156. HRESULT HrAddUniqueDestMsgQueue(IN CDestMsgQueue *pdmqNew,
  157. OUT CDestMsgQueue **ppdmqCurrent);
  158. //Returns a ptr to the DestMsgQueue associated with this object
  159. HRESULT HrGetLinkMsgQueue(IN CAQScheduleID *paqsched,
  160. OUT CLinkMsgQueue **pplmq);
  161. //Add a queue to this domain entry if one does not already exist for that message type
  162. HRESULT HrAddUniqueLinkMsgQueue(IN CLinkMsgQueue *plmqNew,
  163. OUT CLinkMsgQueue **pplmqCurrent);
  164. void RemoveDestMsgQueue(IN CDestMsgQueue *pdmq);
  165. void RemoveLinkMsgQueue(IN CLinkMsgQueue *plmq);
  166. //returns internal ptr to domain name... use HrGetDomainName if you
  167. //are not *directly* tied to the life span of a domain entry
  168. inline LPSTR szGetDomainName() {return m_szDomainName;};
  169. inline DWORD cbGetDomainNameLength() {return m_cbDomainName;};
  170. inline void InitDomainString(PDOMAIN_STRING pDomain);
  171. //Is it safe to get rid of this domain entry?
  172. inline BOOL fSafeToRemove() {
  173. return (BOOL) ((m_lReferences == 1) &&
  174. (m_cQueues == 0) &&
  175. (m_cLinks == 0));}
  176. };
  177. //---[ CDomainEntryIterator ]--------------------------------------------------
  178. //
  179. //
  180. // Description:
  181. // Base iterator class for domain entry. Provides a consistent snapshot
  182. // of the elements of a domain entry
  183. // Hungarian:
  184. // deit, pdeit
  185. //
  186. //-----------------------------------------------------------------------------
  187. class CDomainEntryIterator
  188. {
  189. protected:
  190. DWORD m_dwSignature;
  191. DWORD m_cItems;
  192. DWORD m_iCurrentItem;
  193. PVOID *m_rgpvItems;
  194. protected:
  195. CDomainEntryIterator();
  196. PVOID pvGetNext();
  197. VOID Recycle();
  198. virtual VOID ReleaseItem(PVOID pvItem)
  199. {_ASSERT(FALSE && "Base virtual function");};
  200. virtual PVOID pvItemFromListEntry(PLIST_ENTRY pli)
  201. {_ASSERT(FALSE && "Base virtual function");return NULL;};
  202. virtual PLIST_ENTRY pliHeadFromDomainEntry(CDomainEntry *pdentry)
  203. {_ASSERT(FALSE && "Base virtual function");return NULL;};
  204. virtual DWORD cItemsFromDomainEntry(CDomainEntry *pdentry)
  205. {_ASSERT(FALSE && "Base virtual function");return 0;};
  206. public:
  207. HRESULT HrInitialize(CDomainEntry *pdentry);
  208. VOID Reset() {m_iCurrentItem = 0;};
  209. };
  210. //---[ CDomainEntryLinkIterator ]----------------------------------------------
  211. //
  212. //
  213. // Description:
  214. // Implementation of CDomainEntryIterator for CLinkMsgQueues
  215. // Hungarian:
  216. // delit, pdelit
  217. //
  218. //-----------------------------------------------------------------------------
  219. class CDomainEntryLinkIterator : public CDomainEntryIterator
  220. {
  221. protected:
  222. virtual VOID ReleaseItem(PVOID pvItem);
  223. virtual PVOID pvItemFromListEntry(PLIST_ENTRY pli);
  224. virtual PLIST_ENTRY pliHeadFromDomainEntry(CDomainEntry *pdentry)
  225. {return &(pdentry->m_liLinks);};
  226. virtual DWORD cItemsFromDomainEntry(CDomainEntry *pdentry)
  227. {return pdentry->m_cLinks;};
  228. public:
  229. ~CDomainEntryLinkIterator() {Recycle();};
  230. CLinkMsgQueue *plmqGetNextLinkMsgQueue(CLinkMsgQueue *plmq);
  231. };
  232. //---[ CDomainEntryQueueIterator ]---------------------------------------------
  233. //
  234. //
  235. // Description:
  236. // Implementation of CDomainEntryIterator for CDestMsgQueues
  237. // Hungarian:
  238. // deqit, pdeqit
  239. //
  240. //-----------------------------------------------------------------------------
  241. class CDomainEntryQueueIterator : public CDomainEntryIterator
  242. {
  243. protected:
  244. virtual VOID ReleaseItem(PVOID pvItem);
  245. virtual PVOID pvItemFromListEntry(PLIST_ENTRY pli);
  246. virtual PLIST_ENTRY pliHeadFromDomainEntry(CDomainEntry *pdentry)
  247. {return &(pdentry->m_liDestQueues);};
  248. virtual DWORD cItemsFromDomainEntry(CDomainEntry *pdentry)
  249. {return pdentry->m_cQueues;};
  250. public:
  251. ~CDomainEntryQueueIterator() {Recycle();};
  252. CDestMsgQueue *pdmqGetNextDestMsgQueue(CDestMsgQueue *pdmq);
  253. };
  254. class CDomainMappingTable
  255. {
  256. private:
  257. DWORD m_dwSignature;
  258. DWORD m_dwInternalVersion; //version # used to keep track of queue deletions
  259. DWORD m_dwFlags;
  260. CAQSvrInst *m_paqinst;
  261. DWORD m_cOutstandingExternalShareLocks; //number of outstanding external sharelocks
  262. LIST_ENTRY m_liEmptyDMQHead; //head of list for empty DMQ's
  263. DWORD m_cThreadsForEmptyDMQList;
  264. DOMAIN_NAME_TABLE m_dnt; //where domain names are actually stored
  265. CShareLockInst m_slPrivateData; //Sharelock for accessing Domain Name Table
  266. CLocalLinkMsgQueue *m_plmqLocal; //Local link Queue
  267. CLinkMsgQueue *m_plmqCurrentlyUnreachable; //link for currently unreachable
  268. CLinkMsgQueue *m_plmqUnreachable; //link unreachable destinations
  269. CMailMsgAdminLink *m_pmmaqPreCategorized; //link for precat queue
  270. CMailMsgAdminLink *m_pmmaqPreRouting; //link for prerouting queue
  271. CMailMsgAdminLink *m_pmmaqPreSubmission; //link for prerouting queue
  272. DWORD m_cSpecialRetryMinutes;
  273. DWORD m_cResetRoutesRetriesPending;
  274. HRESULT HrInitLocalDomain(
  275. IN CDomainEntry *pdentry, //entry to init
  276. IN DOMAIN_STRING *pStrDomain, //Domain name
  277. IN CAQMessageType *paqmtMessageType, //Message type as returned by routing
  278. OUT CDomainMapping *pdmap); //domain mapping for domain
  279. HRESULT HrInitRemoteDomain(
  280. IN CDomainEntry *pdentry, //entry to init
  281. IN DOMAIN_STRING *pStrDomain, //Domain Name
  282. IN CInternalDomainInfo *pIntDomainInfo, //domain config
  283. IN CAQMessageType *paqmtMessageType, //Message type as returned by routing
  284. IN IMessageRouter *pIMessageRouter, //router for this message
  285. OUT CDomainMapping *pdmap, //domain mapping for domain
  286. OUT CDestMsgQueue **ppdmq, //destmsgqueue for domain
  287. OUT CLinkMsgQueue **pplmq);
  288. HRESULT HrCreateQueueForEntry(
  289. IN CDomainEntry *pdentry,
  290. IN DOMAIN_STRING *pStrDomain,
  291. IN CInternalDomainInfo *pIntDomainInfo,
  292. IN CAQMessageType *paqmtMessageType,
  293. IN IMessageRouter *pIMessageRouter,
  294. IN CDomainMapping *pdmap,
  295. OUT CDestMsgQueue **ppdmq);
  296. HRESULT HrGetNextHopLink(
  297. IN CDomainEntry *pdentry,
  298. IN LPSTR szDomain,
  299. IN DWORD cbDomain,
  300. IN CInternalDomainInfo *pIntDomainInfo,
  301. IN CAQMessageType *paqmtMessageType,
  302. IN IMessageRouter *pIMessageRouter,
  303. IN BOOL fDMTLocked,
  304. OUT CLinkMsgQueue **pplmq,
  305. OUT HRESULT *phrRoutingDiag);
  306. void LogDomainUnreachableEvent(BOOL fCurrentlyUnreachable,
  307. LPCSTR szDomain);
  308. //Checks head of EMPTY_LIST to see if there are any expired queues
  309. //or an excesive number of non-empty queues in the list
  310. BOOL fNeedToWalkEmptyQueueList();
  311. //Used to delete expired queues
  312. BOOL fDeleteExpiredQueues();
  313. //Domain Name Table iterator function to move a domain to the currently
  314. //unreachable link - used for re-routing
  315. static VOID MakeSingleDomainCurrentlyUnreachable(PVOID pvContext, PVOID pvData,
  316. BOOL fWildcard, BOOL *pfContinue,
  317. BOOL *pfDelete);
  318. HRESULT HrPrvGetDomainEntry(IN DWORD cbDomainNameLength,
  319. IN LPSTR szDomainName,
  320. IN BOOL fDMTLocked,
  321. OUT CDomainEntry **ppdentry);
  322. HRESULT HrInializeGlobalLink(IN LPCSTR szLinkName,
  323. IN DWORD cbLinkName,
  324. OUT CLinkMsgQueue **pplmq,
  325. DWORD dwSupportedActions = 0,
  326. DWORD dwLinkType = 0);
  327. HRESULT HrDeinitializeGlobalLink(IN OUT CLinkMsgQueue **pplmq);
  328. HRESULT HrPrvInsertDomainEntry(
  329. IN PDOMAIN_STRING pstrDomainName,
  330. IN CDomainEntry *pdentryNew,
  331. IN BOOL fTreatAsWildcard,
  332. OUT CDomainEntry **ppdentryOld);
  333. static void RetryResetRoutes(PVOID pvThis);
  334. void RequestResetRoutesRetryIfNecessary();
  335. public:
  336. CDomainMappingTable();
  337. ~CDomainMappingTable();
  338. HRESULT HrInitialize(
  339. CAQSvrInst *paqinst,
  340. CAsyncAdminMsgRefQueue *paradmq,
  341. CAsyncAdminMailMsgQueue *pmmaqPrecatQ,
  342. CAsyncAdminMailMsgQueue *pmmaqPreRoutingQ,
  343. CAsyncAdminMailMsgQueue *pmmaqPreSubmission);
  344. HRESULT HrDeinitialize();
  345. //Lookup Domain name; This will create a new entry if neccessary.
  346. HRESULT HrMapDomainName(
  347. IN LPSTR szDomainName, //Domain Name to map
  348. IN CAQMessageType *paqmtMessageType, //Message type as returned by routing
  349. IN IMessageRouter *pIMessageRouter, //router for this message
  350. OUT CDomainMapping *pdmap, //Mapping returned caller allocated
  351. OUT CDestMsgQueue **ppdmq);//ptr to Queue
  352. HRESULT HrGetDomainEntry(IN DWORD cbDomainNameLength,
  353. IN LPSTR szDomainName,
  354. OUT CDomainEntry **ppdentry)
  355. {
  356. return HrPrvGetDomainEntry(cbDomainNameLength,
  357. szDomainName, FALSE, ppdentry);
  358. }
  359. HRESULT HrIterateOverSubDomains(DOMAIN_STRING * pstrDomain,
  360. IN DOMAIN_ITR_FN pfn,
  361. IN PVOID pvContext)
  362. {
  363. HRESULT hr = S_OK;
  364. m_slPrivateData.ShareLock();
  365. hr = m_dnt.HrIterateOverSubDomains(pstrDomain, pfn, pvContext);
  366. m_slPrivateData.ShareUnlock();
  367. return hr;
  368. };
  369. // Functions for rerouting domains
  370. HRESULT HrBeginRerouteDomains();
  371. HRESULT HrCompleteRerouteDomains();
  372. // Reroute the queues on a given link
  373. HRESULT HrRerouteLink(CLinkMsgQueue *plmqReroute);
  374. HRESULT HrGetOrCreateLink(
  375. IN LPSTR szRouteAddress,
  376. IN DWORD cbRouteAddress,
  377. IN DWORD dwScheduleID,
  378. IN LPSTR szConnectorName,
  379. IN IMessageRouter *pIMessageRouter,
  380. IN BOOL fCreateIfNotExist,
  381. IN DWORD linkInfoType,
  382. OUT CLinkMsgQueue **pplmq,
  383. OUT BOOL *pfRemoveOwnedSchedule);
  384. //The following functions are used to check the version number of the DMT.
  385. //The version number is guananteed remain constant while the DMT Sharelock
  386. //is held. While it is not *required* to get lock before getting the
  387. //version number for the first time, it is required to get the lock (and
  388. //keep it) while verify that the version number has not changed. The
  389. //expected usage of these functions is:
  390. //DWORD dwDMTVersion = pdmt->dwGetDMTVersion();
  391. //...
  392. //pdmt->AquireDMTShareLock();
  393. //if (pdmt->dwGetDMTVersion() == dwDMTVersion)
  394. // ... do stuff that requires consitant DMT version
  395. //pdmt->ReleaseDMTShareLock();
  396. inline void AquireDMTShareLock();
  397. inline void ReleaseDMTShareLock();
  398. inline DWORD dwGetDMTVersion();
  399. //Used by DestMsgQueue to Add themselves from the empty queue list
  400. void AddDMQToEmptyList(CDestMsgQueue *pdmq);
  401. void ProcessSpecialLinks(DWORD cSpecialRetryMinutes, BOOL fRoutingLockHeld);
  402. static void SpecialRetryCallback(PVOID pvContext);
  403. CLinkMsgQueue *plmqGetLocalLink();
  404. CLinkMsgQueue *plmqGetCurrentlyUnreachable();
  405. CMailMsgAdminLink *pmmaqGetPreCategorized();
  406. CMailMsgAdminLink *pmmaqGetPreRouting();
  407. CMailMsgAdminLink *pmmaqGetPreSubmission();
  408. HRESULT HrPrepareForLocalDelivery(
  409. IN CMsgRef *pmsgref,
  410. IN BOOL fDelayDSN,
  411. IN OUT CDeliveryContext *pdcntxt,
  412. OUT DWORD *pcRecips,
  413. OUT DWORD **prgdwRecips);
  414. DWORD GetCurrentlyUnreachableTotalMsgCount();
  415. };
  416. //---[ CDomainEntry::InitDomainString ]----------------------------------------
  417. //
  418. //
  419. // Description:
  420. // Initialized a domain string based on this domain's info
  421. // Parameters:
  422. // pDomain - ptr to DOMAIN_STRING to initialize
  423. // Returns:
  424. // -
  425. // History:
  426. // 5/26/98 - MikeSwa Created
  427. //
  428. //-----------------------------------------------------------------------------
  429. void CDomainEntry::InitDomainString(PDOMAIN_STRING pDomain)
  430. {
  431. pDomain->Buffer = m_szDomainName;
  432. pDomain->Length = (USHORT) m_cbDomainName;
  433. pDomain->MaximumLength = pDomain->Length;
  434. }
  435. //---[ CDomainMappingTable::AquireDMTShareLock ]-------------------------------
  436. //
  437. //
  438. // Description:
  439. // Aquires a share lcok on the DMT's internal lock... must be released
  440. // with a call to ReleaseDMTShareLock.
  441. // Parameters:
  442. //
  443. // Returns:
  444. //
  445. // History:
  446. // 9/8/98 - MikeSwa Created
  447. //
  448. //-----------------------------------------------------------------------------
  449. void CDomainMappingTable::AquireDMTShareLock()
  450. {
  451. m_slPrivateData.ShareLock();
  452. DEBUG_DO_IT(InterlockedIncrement((PLONG) &m_cOutstandingExternalShareLocks));
  453. }
  454. //---[ CDomainMappingTable::ReleaseDMTShareLock ]-------------------------------
  455. //
  456. //
  457. // Description:
  458. // Releases a DMT sharelock aquired by AquireDMTShareLock
  459. // Parameters:
  460. // -
  461. // Returns:
  462. // -
  463. // History:
  464. // 9/8/98 - MikeSwa Created
  465. //
  466. //-----------------------------------------------------------------------------
  467. void CDomainMappingTable::ReleaseDMTShareLock()
  468. {
  469. _ASSERT(m_cOutstandingExternalShareLocks); //Count should not go below 0
  470. DEBUG_DO_IT(InterlockedDecrement((PLONG) &m_cOutstandingExternalShareLocks));
  471. m_slPrivateData.ShareUnlock();
  472. }
  473. //---[ CDomainMappingTable::dwGetDMTVersion ]----------------------------------
  474. //
  475. //
  476. // Description:
  477. // Returns the internal DMT version number
  478. // Parameters:
  479. // -
  480. // Returns:
  481. // DMT Version number
  482. // History:
  483. // 9/8/98 - MikeSwa Created
  484. //
  485. //-----------------------------------------------------------------------------
  486. DWORD CDomainMappingTable::dwGetDMTVersion()
  487. {
  488. return m_dwInternalVersion;
  489. }
  490. void ReUnreachableErrorToAqueueError(HRESULT reErr, HRESULT *aqErr);
  491. #endif //_DOMAIN_H_