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.

443 lines
11 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2000, Microsoft Corporation
  4. //
  5. // File: DfsFolder.hxx
  6. //
  7. // Contents: the base DFS Folder class, this contains the common
  8. // Meta information functionality.
  9. //
  10. // Classes: DfsFolder.
  11. //
  12. // History: Dec. 8 2000, Author: udayh
  13. //
  14. //-----------------------------------------------------------------------------
  15. #ifndef __DFS_FOLDER__
  16. #define __DFS_FOLDER__
  17. #include "DfsGeneric.hxx"
  18. #include "DfsInit.hxx"
  19. #include "dfsreferraldata.h"
  20. //+----------------------------------------------------------------------------
  21. //
  22. // Class: DfsFolder
  23. //
  24. // Synopsis: This class implements a basic DfsFolder class.
  25. //
  26. //-----------------------------------------------------------------------------
  27. //
  28. // Declare DfsFolderReferralData as a class, since we will be including
  29. // a pointer to that class within the DfsFolder class.
  30. //
  31. class DfsFolderReferralData;
  32. //
  33. // The DfsFolder can be in any of the following loaded state.
  34. //
  35. enum DfsFolderLoadState
  36. {
  37. DfsFolderStateUnknown = 0,
  38. DfsFolderLoaded,
  39. DfsFolderNotLoaded,
  40. DfsFolderLoadInProgress,
  41. DfsFolderLoadFailed,
  42. };
  43. //
  44. // Definition of some of the bits in the flags field.
  45. //
  46. #define DFS_FOLDER_IN_LOGICAL_TABLE 0x0001
  47. #define DFS_FOLDER_IN_METADATA_TABLE 0x0002
  48. #define DFS_FOLDER_DELETE_IN_PROGRESS 0x0004
  49. #define DFS_FOLDER_INSITE_REFERRALS 0x0008
  50. #define DFS_FOLDER_OUT_OF_DOMAIN 0x0010
  51. #define DFS_FOLDER_COST_BASED_SITE_SELECTION 0x0020 // site-costing enabled on this folder
  52. #define DFS_FOLDER_OFFLINE 0x0040
  53. #define DFS_FOLDER_ROOT 0x1000
  54. class DfsFolder: public DfsGeneric
  55. {
  56. private:
  57. DfsFolder *_pParent; // the root DfsFolder.
  58. UINT64 _LastUSN; //??
  59. ULONG _Timeout; //timeout to send back in referral
  60. ULONG _RetryFailedLoadTimeout; // Fired if the folder data failed to load
  61. public:
  62. CRITICAL_SECTION * _pLock; // lock for this folder.
  63. ULONG _Flags; // flags, bits specified above.
  64. DfsFolderReferralData *_pReferralData; // The loaded referral data
  65. UNICODE_STRING _MetadataName; // the metadat name of this folder
  66. UNICODE_STRING _LogicalName; // the dfs logical name of folder
  67. DFSSTATUS _LoadStatus; // Status of last load.
  68. DfsFolderLoadState _LoadState; // current load state of folder
  69. public:
  70. //
  71. // Function DfsFolder: the constructor for the DfsFolder class.
  72. // This initializes all the private and public variables
  73. // of the DfsFolder class.
  74. //
  75. DfsFolder( DfsFolder *pParent,
  76. CRITICAL_SECTION *pLock,
  77. DfsObjectTypeEnumeration ObType = DFS_OBJECT_TYPE_FOLDER ) :
  78. DfsGeneric(ObType)
  79. {
  80. //
  81. // Initialize the local variables of this class.
  82. // The parent is going to set the logical and metadata name
  83. // for this instance.
  84. //
  85. RtlInitUnicodeString(&_LogicalName, NULL);
  86. RtlInitUnicodeString(&_MetadataName, NULL);
  87. _LastUSN = 0;
  88. _LoadStatus = 0;
  89. _pReferralData = NULL;
  90. _Flags = 0;
  91. _Timeout = DFS_DEFAULT_REFERRAL_TIMEOUT;
  92. _RetryFailedLoadTimeout = 0;
  93. _pLock = pLock;
  94. _LoadState = DfsFolderNotLoaded;
  95. // If the parent is not ourselves, acquire a reference on
  96. // the parent so that we can save a pointer to the parent.
  97. // The only exception is the case where there is no parent,
  98. // and we are pointing to ourselves: in that case avoid
  99. // acquiring a reference to ourself since this would cause
  100. // this obect from never being destroyed.
  101. //
  102. if ( pParent != NULL )
  103. {
  104. pParent->AcquireReference();
  105. _pParent = pParent;
  106. } else
  107. {
  108. _pParent = this;
  109. }
  110. }
  111. //
  112. // The destructor is virtual so that classes derived from this
  113. // class will end up calling the right set of destructors
  114. //
  115. virtual
  116. ~DfsFolder()
  117. {
  118. //
  119. // If we had saved a parent, release our reference at this point.
  120. //
  121. if ( (_pParent != NULL) && (_pParent != this) )
  122. {
  123. _pParent->ReleaseReference();
  124. }
  125. if (_LogicalName.Buffer != NULL)
  126. {
  127. DfsFreeUnicodeString(&_LogicalName);
  128. }
  129. if (_MetadataName.Buffer != NULL)
  130. {
  131. DfsFreeUnicodeString(&_MetadataName);
  132. }
  133. _pParent = NULL;
  134. }
  135. //
  136. // Function ReleaseLock: release the folder lock.
  137. //
  138. VOID
  139. ReleaseLock()
  140. {
  141. DfsReleaseLock(_pLock);
  142. }
  143. //
  144. // Function AcquireWriteLock: Acquire the folder lock exclusively.
  145. // Currently all locks are exclusive, but this could change.
  146. //
  147. DFSSTATUS
  148. AcquireWriteLock()
  149. {
  150. return DfsAcquireWriteLock( _pLock );
  151. }
  152. //
  153. // Function AcquireReadLock: Acquire the folder lock shared
  154. // Currently all locks are exclusive, but this could change.
  155. //
  156. DFSSTATUS
  157. AcquireReadLock()
  158. {
  159. return DfsAcquireReadLock( _pLock );
  160. }
  161. //
  162. // Function InitializeMetadataName: Set the metadata name of this
  163. // instance to the passed in unicode string name.
  164. //
  165. DFSSTATUS
  166. InitializeMetadataName( PUNICODE_STRING pName )
  167. {
  168. return DfsCreateUnicodeString( &_MetadataName, pName );
  169. }
  170. //
  171. // Function InitializeMetadataName: Set the metadata name of this
  172. // instance to the passed in string name.
  173. //
  174. DFSSTATUS
  175. InitializeMetadataName( LPWSTR pNameString )
  176. {
  177. return DfsCreateUnicodeStringFromString( &_MetadataName, pNameString );
  178. }
  179. //
  180. // Function InitializeLogicalName: Set the logical name of this
  181. // instance to the passed in unciode string name.
  182. //
  183. DFSSTATUS
  184. InitializeLogicalName( PUNICODE_STRING pName )
  185. {
  186. return DfsCreateUnicodeString( &_LogicalName, pName );
  187. }
  188. //
  189. // Function LoadReferralData: This is defined virtual and the parent
  190. // DfsRootFolder which is derived from the DfsFolder class is expected
  191. // to override this function.
  192. // Call the parent's LoadReferralData routine.
  193. //
  194. virtual
  195. DFSSTATUS
  196. LoadReferralData(
  197. IN DfsFolderReferralData *pReferralData )
  198. {
  199. return _pParent->LoadReferralData( pReferralData );
  200. }
  201. //
  202. // Function UnloadReferralData: This is defined virtual and the parent
  203. // DfsRootFolder which is derived from the DfsFolder class is expected
  204. // to override this function.
  205. // Call the parent's UnloadReferralData routine.
  206. //
  207. virtual
  208. DFSSTATUS
  209. UnloadReferralData(
  210. IN DfsFolderReferralData *pReferralData )
  211. {
  212. return _pParent->UnloadReferralData( pReferralData );
  213. }
  214. //
  215. // Function UpdateRequired: Checks if the passed in USN is greater
  216. // than the one stored by us. If so, return true indicating that
  217. // we need to be updated.
  218. //
  219. BOOLEAN
  220. UpdateRequired( UINT64 ModifiedUSN )
  221. {
  222. if ( ModifiedUSN > _LastUSN ) return TRUE;
  223. else return FALSE;
  224. }
  225. //
  226. // Function SetUSN
  227. //
  228. VOID
  229. SetUSN( UINT64 ModifiedUSN )
  230. {
  231. _LastUSN = ModifiedUSN;
  232. return NOTHING;
  233. }
  234. //
  235. // Function SetFlag
  236. //
  237. VOID
  238. SetFlag( ULONG Bits )
  239. {
  240. _Flags |= Bits;
  241. }
  242. //
  243. // Function ResetFlag
  244. //
  245. VOID
  246. ResetFlag( ULONG Bits )
  247. {
  248. _Flags &= ~Bits;
  249. }
  250. //
  251. // Function SetTimeout
  252. //
  253. VOID
  254. SetTimeout( ULONG Timeout )
  255. {
  256. _Timeout = Timeout;
  257. }
  258. ULONG
  259. GetTimeout(void)
  260. {
  261. return _Timeout;
  262. }
  263. //
  264. // Function GetFolderMetadataName: Returns the unicode string
  265. // that is this folders metadata name
  266. //
  267. PUNICODE_STRING
  268. GetFolderMetadataName()
  269. {
  270. return &_MetadataName;
  271. }
  272. //
  273. // Function GetFolderMetadataNameString:Returns a wide string
  274. // that is this folders metadata name. Note that since the unicode
  275. // string is stored with a null terminiated buffer, we can just
  276. // use the unicode strings buffer.
  277. //
  278. LPWSTR
  279. GetFolderMetadataNameString()
  280. {
  281. return _MetadataName.Buffer;
  282. }
  283. //
  284. // Function GetFolderLogicalName: Returns a unicode string that is
  285. // this folders logical name.
  286. //
  287. PUNICODE_STRING
  288. GetFolderLogicalName()
  289. {
  290. return &_LogicalName;
  291. }
  292. LPWSTR
  293. GetFolderLogicalNameString()
  294. {
  295. return _LogicalName.Buffer;
  296. }
  297. BOOLEAN
  298. IsFolderRoot()
  299. {
  300. return ( (_Flags & DFS_FOLDER_ROOT) == DFS_FOLDER_ROOT );
  301. }
  302. BOOLEAN
  303. IsFolderInMetadataTable()
  304. {
  305. return ( (_Flags & DFS_FOLDER_IN_METADATA_TABLE) == DFS_FOLDER_IN_METADATA_TABLE );
  306. }
  307. BOOLEAN
  308. IsFolderInLogicalTable()
  309. {
  310. return ( (_Flags & DFS_FOLDER_IN_LOGICAL_TABLE) == DFS_FOLDER_IN_LOGICAL_TABLE );
  311. }
  312. BOOLEAN
  313. IsFolderDeleteInProgress()
  314. {
  315. return ( (_Flags & DFS_FOLDER_DELETE_IN_PROGRESS) == DFS_FOLDER_DELETE_IN_PROGRESS);
  316. }
  317. BOOLEAN
  318. IsFolderInSiteReferrals()
  319. {
  320. return ( (_Flags & DFS_FOLDER_INSITE_REFERRALS) == DFS_FOLDER_INSITE_REFERRALS);
  321. }
  322. BOOLEAN
  323. IsFolderSiteCostingEnabled()
  324. {
  325. return ( (_Flags & DFS_FOLDER_COST_BASED_SITE_SELECTION) ==
  326. DFS_FOLDER_COST_BASED_SITE_SELECTION);
  327. }
  328. BOOLEAN
  329. IsFolderOutOfDomain()
  330. {
  331. return ( (_Flags & DFS_FOLDER_OUT_OF_DOMAIN) == DFS_FOLDER_OUT_OF_DOMAIN );
  332. }
  333. BOOLEAN
  334. IsFolderOffline()
  335. {
  336. return ( (_Flags & DFS_FOLDER_OFFLINE) == DFS_FOLDER_OFFLINE );
  337. }
  338. BOOLEAN
  339. IsTimeToRetry(VOID)
  340. {
  341. ULONG CurrentTime = GetTickCount();
  342. if ((CurrentTime > _RetryFailedLoadTimeout) &&
  343. ((CurrentTime - _RetryFailedLoadTimeout) > DfsServerGlobalData.RetryFailedReferralLoadInterval))
  344. {
  345. return TRUE;
  346. }
  347. // overflow
  348. if ((CurrentTime < _RetryFailedLoadTimeout) &&
  349. ((CurrentTime - 0) + (0xFFFFFFFF - _RetryFailedLoadTimeout) > DfsServerGlobalData.RetryFailedReferralLoadInterval))
  350. {
  351. return TRUE;
  352. }
  353. return FALSE;
  354. }
  355. //
  356. // Function GetReferralData: Returns the referral data for this
  357. // folder, and indicates if the referral data was cached or needed
  358. // to be loaded.
  359. //
  360. DFSSTATUS
  361. GetReferralData( IN DfsFolderReferralData **ppReferralData,
  362. OUT BOOLEAN *pCacheHit,
  363. IN BOOLEAN AddToLoadedList=TRUE );
  364. //
  365. // Function RemoveReferralData: discards any cached referral data
  366. // from the folder.
  367. //
  368. DFSSTATUS
  369. RemoveReferralData( IN DfsFolderReferralData *pRefData,
  370. IN PBOOLEAN pRemoved = NULL );
  371. };
  372. #endif // __DFS_FOLDER__