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.

227 lines
8.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: prefix.hxx
  7. //
  8. // Contents: PREFIX table definition
  9. //
  10. // History: SethuR -- Implemented
  11. //
  12. // Notes: The DFS prefix table data structure consists of three
  13. // entities and methods to manipulate them. They are the
  14. // DFS_PREFIX_TABLE_ENTRY,DFS_PREFIX_TABLE_BUCKET and the
  15. // DFS_PREFIX_TABLE.
  16. //
  17. // The DFS_PREFIX_TABLE is a hash table of DFS_PREFIX_TABLE_ENTRY's
  18. // wherein collisions are resolved through linear chaining. The
  19. // hash table is organized as an array of collision lists
  20. // (DFS_PREFIX_TABLE_BUCKET). A brief description with each of
  21. // these entities is attached to the declaration.
  22. //
  23. // There are certain characterstics that distinguish this
  24. // hash table from other hash tables. These are the extensions
  25. // provided to accomodate the special operations.
  26. //
  27. //--------------------------------------------------------------------------
  28. #ifndef __PREFIX_HXX__
  29. #define __PREFIX_HXX__
  30. //+---------------------------------------------------------------------
  31. //
  32. // Struct: DFS_PREFIX_TABLE_ENTRY
  33. //
  34. // History:
  35. //
  36. // Notes: Each DFS_PREFIX_TABLE entry is in reality a member of two linked
  37. // lists -- a doubly linked list chaining the entries in a bucket
  38. // and a singly linked list establishing the path from any entry to
  39. // the root of the name space. In addition we have the data associated
  40. // with each entry, viz., the name and the data (pData). We also
  41. // keep track of the number of children of each entry. It can also
  42. // be defined as the number of paths to the root of which this entry
  43. // is a member.
  44. //
  45. //----------------------------------------------------------------------
  46. typedef struct _DFS_PREFIX_TABLE_ENTRY_
  47. {
  48. struct _DFS_PREFIX_TABLE_ENTRY_ *pParentEntry;
  49. struct _DFS_PREFIX_TABLE_ENTRY_ *pNextEntry;
  50. struct _DFS_PREFIX_TABLE_ENTRY_ *pPrevEntry;
  51. //
  52. // pFirstChildEntry and pSiblingEntry are used purely for enumeration
  53. //
  54. struct _DFS_PREFIX_TABLE_ENTRY_ *pFirstChildEntry;
  55. struct _DFS_PREFIX_TABLE_ENTRY_ *pSiblingEntry;
  56. ULONG NoOfChildren;
  57. UNICODE_STRING PathSegment;
  58. PVOID pData;
  59. } DFS_PREFIX_TABLE_ENTRY, *PDFS_PREFIX_TABLE_ENTRY;
  60. //+---------------------------------------------------------------------
  61. //
  62. // Struct: DFS_PREFIX_TABLE_BUCKET
  63. //
  64. // History:
  65. //
  66. // Notes: The DFS_PREFIX_TABLE_BUCKET is a doubly linked list of
  67. // DFS_PREFIX_TABLE_ENTRY's. The current implementation employs
  68. // the notion of a sentinel entry associated with each bucket. The
  69. // end pointers are never null but are always looped back to the
  70. // sentinel entry. The reason we employ such an organization is that
  71. // it considerably simplifies the list manipulation routines. The
  72. // reason this needs to be a doubly linked list is that we would like
  73. // to have the ability of deleting entries without having to traverse
  74. // the buckets from beginning.
  75. //
  76. // The following inline methods ( macro defns. ) are provided for
  77. // inserting, deleting and looking up an entry in the bucket.
  78. //
  79. //----------------------------------------------------------------------
  80. typedef struct _PREFIX_TABLE_BUCKET_
  81. {
  82. ULONG NoOfEntries; // High water mark for entries hashing to the bkt.
  83. DFS_PREFIX_TABLE_ENTRY SentinelEntry;
  84. } PREFIX_TABLE_BUCKET, *PPREFIX_TABLE_BUCKET;
  85. //+---------------------------------------------------------------------
  86. //
  87. // Struct: NAME_PAGE
  88. //
  89. // History:
  90. //
  91. // Notes: The name segments associated with the various entries are all
  92. // stored together in a name page. This allows us to amortize the
  93. // memory allocation costs over a number of entries and also allows
  94. // us to speed up traversal ( for details see DFS_PREFIX_TABLE
  95. // definition ).
  96. //
  97. //----------------------------------------------------------------------
  98. #define FREESPACE_IN_NAME_PAGE ((PAGE_SIZE - sizeof(ULONG) - sizeof(PVOID)) / sizeof(WCHAR))
  99. typedef struct _NAME_PAGE_
  100. {
  101. struct _NAME_PAGE_ *pNextPage;
  102. LONG cFreeSpace; // free space avilable in WCHAR's
  103. WCHAR Names[FREESPACE_IN_NAME_PAGE];
  104. } NAME_PAGE, *PNAME_PAGE;
  105. typedef struct _NAME_PAGE_LIST_
  106. {
  107. PNAME_PAGE pFirstPage;
  108. } NAME_PAGE_LIST, *PNAME_PAGE_LIST;
  109. //+---------------------------------------------------------------------
  110. //
  111. // Struct: DFS_PREFIX_TABLE
  112. //
  113. // History:
  114. //
  115. // Notes: The DFS_PREFIX_TABLE is a hashed collection of DFS_PREFIX_TABLE_ENTRY
  116. // organized in the form of buckets. In addition one other space
  117. // conserving measure is adopted. There is only one copy of each
  118. // name segment stored in the table. As an example consider the
  119. // two pathnames \foo\bar and \bar\foo. We only store one copy of foo
  120. // and bar eventhough we accomdate both these paths. A beneficial
  121. // side effect of storing single copies is that our traversal of the
  122. // collision chain is considerably speeded up since once we have
  123. // located the pointer to the name, subsequent comparisons need merely
  124. // compare pointers as opposed to strings.
  125. //
  126. //----------------------------------------------------------------------
  127. #define NO_OF_HASH_BUCKETS 57
  128. typedef struct _DFS_PREFIX_TABLE
  129. {
  130. BOOLEAN CaseSensitive;
  131. NAME_PAGE_LIST NamePageList;
  132. //
  133. // NextEntry is used purely for enumeration
  134. //
  135. PDFS_PREFIX_TABLE_ENTRY NextEntry;
  136. DFS_PREFIX_TABLE_ENTRY RootEntry;
  137. PREFIX_TABLE_BUCKET Buckets[NO_OF_HASH_BUCKETS];
  138. #ifdef KERNEL_MODE
  139. // Zone for allocating DFS_PREFIX_TABLE entries .....
  140. ZONE_HEADER PrefixTableEntryZone;
  141. #else
  142. // A DFS_PREFIX_TABLE is part of DS_DATA. We need to make the sizes of
  143. // these structures identical in user and kernel mode, so that user-mode
  144. // utilities like dfsdump can work.
  145. CHAR UnusedBuffer[sizeof(ZONE_HEADER)];
  146. #endif
  147. } DFS_PREFIX_TABLE, *PDFS_PREFIX_TABLE;
  148. //+---------------------------------------------------------------------
  149. //
  150. // Struct: DFS_PREFIX_TABLE API.
  151. //
  152. // History:
  153. //
  154. // Notes: The following API's are provided for manipulating the
  155. // DFS_PREFIX_TABLE.
  156. //
  157. //----------------------------------------------------------------------
  158. extern
  159. NTSTATUS DfsInitializePrefixTable(PDFS_PREFIX_TABLE pTable,
  160. BOOLEAN fCaseSensitive);
  161. extern
  162. NTSTATUS DfsInsertInPrefixTable(PDFS_PREFIX_TABLE pTable,
  163. PUNICODE_STRING pPath,
  164. PVOID pData);
  165. extern
  166. NTSTATUS DfsLookupPrefixTable(PDFS_PREFIX_TABLE pTable,
  167. PUNICODE_STRING pPath,
  168. PUNICODE_STRING pSuffix,
  169. PVOID *ppData);
  170. extern
  171. NTSTATUS DfsRemoveFromPrefixTable(PDFS_PREFIX_TABLE pTable,
  172. PUNICODE_STRING pPath);
  173. NTSTATUS
  174. DfsFreePrefixTable(
  175. PDFS_PREFIX_TABLE pTable);
  176. //
  177. // The RTL Prefix Table function signatures are slightly different.
  178. // For now we will define a mapping between them to ease the porting
  179. // effort. Subsequently we will change our signatures to confirm to
  180. // the RTL routine.
  181. //
  182. #define DfsInitializeUnicodePrefix(pTable) \
  183. (DfsInitializePrefixTable(pTable,FALSE) == STATUS_SUCCESS)
  184. #define DfsRemoveUnicodePrefix(pTable,pPath) \
  185. (DfsRemoveFromPrefixTable(pTable,pPath) == STATUS_SUCCESS)
  186. #define DfsInsertUnicodePrefix(pTable,pPath,pData) \
  187. (DfsInsertInPrefixTable(pTable,pPath,pData) == STATUS_SUCCESS)
  188. PVOID DfsFindUnicodePrefix(PDFS_PREFIX_TABLE pTable,
  189. PUNICODE_STRING pPath,
  190. PUNICODE_STRING pSuffix);
  191. PVOID DfsNextUnicodePrefix(PDFS_PREFIX_TABLE pTable,
  192. BOOLEAN fRestart);
  193. #endif // __PREFIX_HXX__