Source code of Windows XP (NT5)
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.

502 lines
9.7 KiB

  1. /*++
  2. DANGER DANGER DANGER
  3. ALL THE STUFF IN THIS FILE IS OBSOLETE BUT IS BEING TEMPORARILY MAINTAINED
  4. IN CASE WE WANT TO GRAP SOMETHING. ALL THE CODE IS IFDEF'D OUT.
  5. Copyright (c) 1989 Microsoft Corporation
  6. Module Name:
  7. PrefxSup.c
  8. Abstract:
  9. This module implements the Rx Name lookup Suport routines
  10. Author:
  11. David Goebel [DavidGoe] 31-Jan-1994
  12. Revision History:
  13. --*/
  14. // ----------------------joejoe-----------found-------------#include "RxProcs.h"
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #ifdef RDBSS_OBSOLETE
  18. //
  19. // The Bug check file id for this module
  20. //
  21. #define BugCheckFileId (RDBSS_BUG_CHECK_SPLAYSUP)
  22. //
  23. // The debug trace level for this module
  24. //
  25. #define Dbg (DEBUG_TRACE_SPLAYSUP)
  26. //
  27. // Local procedures and types used only in this package
  28. //
  29. typedef enum _COMPARISON {
  30. IsLessThan,
  31. IsGreaterThan,
  32. IsEqual
  33. } COMPARISON;
  34. COMPARISON
  35. RxCompareNames (
  36. IN PSTRING NameA,
  37. IN PSTRING NameB
  38. );
  39. //
  40. // Do a macro here to check for a common case.
  41. //
  42. #define CompareNames(NAMEA,NAMEB) ( \
  43. *(PUCHAR)(NAMEA)->Buffer != *(PUCHAR)(NAMEB)->Buffer ? \
  44. *(PUCHAR)(NAMEA)->Buffer < *(PUCHAR)(NAMEB)->Buffer ? \
  45. IsLessThan : IsGreaterThan : \
  46. RxCompareNames((PSTRING)(NAMEA), (PSTRING)(NAMEB)) \
  47. )
  48. #ifdef ALLOC_PRAGMA
  49. #pragma alloc_text(PAGE, RxInsertName)
  50. #pragma alloc_text(PAGE, RxRemoveNames)
  51. #pragma alloc_text(PAGE, RxFindFcb)
  52. #pragma alloc_text(PAGE, RxCompareNames)
  53. #endif
  54. VOID
  55. RxInsertName (
  56. IN PRX_CONTEXT RxContext,
  57. IN PRTL_SPLAY_LINKS *RootNode,
  58. IN PFILE_NAME_NODE Name
  59. )
  60. /*++
  61. Routine Description:
  62. This routine will insert a name in the splay tree pointed to
  63. by RootNode.
  64. The name must not already exist in the splay tree.
  65. Arguments:
  66. RootNode - Supplies a pointer to the table.
  67. Name - Contains the New name to enter.
  68. Return Value:
  69. None.
  70. --*/
  71. {
  72. COMPARISON Comparison;
  73. PFILE_NAME_NODE Node;
  74. RtlInitializeSplayLinks(&Name->Links);
  75. //
  76. // If we are the first entry in the tree, just become the root.
  77. //
  78. if (*RootNode == NULL) {
  79. *RootNode = &Name->Links;
  80. return;
  81. }
  82. Node = CONTAINING_RECORD( *RootNode, FILE_NAME_NODE, Links );
  83. while (TRUE) {
  84. //
  85. // Compare the prefix in the tree with the prefix we want
  86. // to insert. Note that Oem here doesn't mean anything.
  87. //
  88. Comparison = CompareNames(&Node->Name.Oem, &Name->Name.Oem);
  89. //
  90. // We should never find the name in the table already.
  91. //
  92. if (Comparison == IsEqual) {
  93. RxBugCheck( 0, 0, 0 );
  94. }
  95. //
  96. // If the tree prefix is greater than the new prefix then
  97. // we go down the left subtree
  98. //
  99. if (Comparison == IsGreaterThan) {
  100. //
  101. // We want to go down the left subtree, first check to see
  102. // if we have a left subtree
  103. //
  104. if (RtlLeftChild(&Node->Links) == NULL) {
  105. //
  106. // there isn't a left child so we insert ourselves as the
  107. // new left child
  108. //
  109. RtlInsertAsLeftChild(&Node->Links, &Name->Links);
  110. //
  111. // and exit the while loop
  112. //
  113. break;
  114. } else {
  115. //
  116. // there is a left child so simply go down that path, and
  117. // go back to the top of the loop
  118. //
  119. Node = CONTAINING_RECORD( RtlLeftChild(&Node->Links),
  120. FILE_NAME_NODE,
  121. Links );
  122. }
  123. } else {
  124. //
  125. // The tree prefix is either less than or a proper prefix
  126. // of the new string. We treat both cases a less than when
  127. // we do insert. So we want to go down the right subtree,
  128. // first check to see if we have a right subtree
  129. //
  130. if (RtlRightChild(&Node->Links) == NULL) {
  131. //
  132. // These isn't a right child so we insert ourselves as the
  133. // new right child
  134. //
  135. RtlInsertAsRightChild(&Node->Links, &Name->Links);
  136. //
  137. // and exit the while loop
  138. //
  139. break;
  140. } else {
  141. //
  142. // there is a right child so simply go down that path, and
  143. // go back to the top of the loop
  144. //
  145. Node = CONTAINING_RECORD( RtlRightChild(&Node->Links),
  146. FILE_NAME_NODE,
  147. Links );
  148. }
  149. }
  150. }
  151. return;
  152. }
  153. VOID
  154. RxRemoveNames (
  155. IN PRX_CONTEXT RxContext,
  156. IN PFCB Fcb
  157. )
  158. /*++
  159. Routine Description:
  160. This routine will remove the short name and any long names associated
  161. with the files from their repsective splay tree.
  162. Arguments:
  163. Name - Supplies the Fcb to process.
  164. Return Value:
  165. None.
  166. --*/
  167. {
  168. PDCB Parent;
  169. PRTL_SPLAY_LINKS NewRoot;
  170. Parent = Fcb->ParentDcb;
  171. ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_NAMES_IN_SPLAY_TREE ));
  172. if (FlagOn( Fcb->FcbState, FCB_STATE_NAMES_IN_SPLAY_TREE )) {
  173. //
  174. // Delete the node short name.
  175. //
  176. NewRoot = RtlDelete(&Fcb->ShortName.Links);
  177. Parent->Specific.Dcb.RootOemNode = NewRoot;
  178. //
  179. // Now check for the presence of long name and delete it.
  180. //
  181. if (FlagOn( Fcb->FcbState, FCB_STATE_HAS_OEM_LONG_NAME )) {
  182. NewRoot = RtlDelete(&Fcb->LongName.Oem.Links);
  183. Parent->Specific.Dcb.RootOemNode = NewRoot;
  184. RtlFreeOemString( &Fcb->LongName.Oem.Name.Oem );
  185. ClearFlag( Fcb->FcbState, FCB_STATE_HAS_OEM_LONG_NAME );
  186. }
  187. if (FlagOn( Fcb->FcbState, FCB_STATE_HAS_UNICODE_LONG_NAME )) {
  188. NewRoot = RtlDelete(&Fcb->LongName.Unicode.Links);
  189. Parent->Specific.Dcb.RootUnicodeNode = NewRoot;
  190. RtlFreeUnicodeString( &Fcb->LongName.Unicode.Name.Unicode );
  191. ClearFlag( Fcb->FcbState, FCB_STATE_HAS_UNICODE_LONG_NAME );
  192. }
  193. ClearFlag( Fcb->FcbState, FCB_STATE_NAMES_IN_SPLAY_TREE );
  194. }
  195. return;
  196. }
  197. PFCB
  198. RxFindFcb (
  199. IN PRX_CONTEXT RxContext,
  200. IN OUT PRTL_SPLAY_LINKS *RootNode,
  201. IN PSTRING Name
  202. )
  203. /*++
  204. Routine Description:
  205. This routine searches either the Oem or Unicode splay tree looking
  206. for an Fcb with the specified name. In the case the Fcb is found,
  207. rebalance the tree.
  208. Arguments:
  209. RootNode - Supplies the parent to search.
  210. Name - If present, search the Oem tree.
  211. UnicodeName - If present, search the Unicode tree.
  212. Return Value:
  213. PFCB - The Fcb, or NULL if none was found.
  214. --*/
  215. {
  216. COMPARISON Comparison;
  217. PFILE_NAME_NODE Node;
  218. PRTL_SPLAY_LINKS Links;
  219. Links = *RootNode;
  220. while (Links != NULL) {
  221. Node = CONTAINING_RECORD(Links, FILE_NAME_NODE, Links);
  222. //
  223. // Compare the prefix in the tree with the full name
  224. //
  225. Comparison = CompareNames(&Node->Name.Oem, Name);
  226. //
  227. // See if they don't match
  228. //
  229. if (Comparison == IsGreaterThan) {
  230. //
  231. // The prefix is greater than the full name
  232. // so we go down the left child
  233. //
  234. Links = RtlLeftChild(Links);
  235. //
  236. // And continue searching down this tree
  237. //
  238. } else if (Comparison == IsLessThan) {
  239. //
  240. // The prefix is less than the full name
  241. // so we go down the right child
  242. //
  243. Links = RtlRightChild(Links);
  244. //
  245. // And continue searching down this tree
  246. //
  247. } else {
  248. //
  249. // We found it.
  250. //
  251. // Splay the tree and save the new root.
  252. //
  253. *RootNode = RtlSplay(Links);
  254. return Node->Fcb;
  255. }
  256. }
  257. //
  258. // We didn't find the Fcb.
  259. //
  260. return NULL;
  261. }
  262. //
  263. // Local support routine
  264. //
  265. COMPARISON
  266. RxCompareNames (
  267. IN PSTRING NameA,
  268. IN PSTRING NameB
  269. )
  270. /*++
  271. Routine Description:
  272. This function compares two names as fast as possible. Note that since
  273. this comparison is case sensitive, I neither know nor case if the names
  274. are UNICODE or OEM. All that is important is that the result is
  275. deterministic.
  276. Arguments:
  277. NameA & NameB - The names to compare.
  278. Return Value:
  279. COMPARISON - returns
  280. IsLessThan if NameA < NameB lexicalgraphically,
  281. IsGreaterThan if NameA > NameB lexicalgraphically,
  282. IsEqual if NameA is equal to NameB
  283. --*/
  284. {
  285. ULONG i;
  286. ULONG MinLength;
  287. PAGED_CODE();
  288. //
  289. // Figure out the minimum of the two lengths
  290. //
  291. MinLength = NameA->Length < NameB->Length ? NameA->Length :
  292. NameB->Length;
  293. //
  294. // Loop through looking at all of the characters in both strings
  295. // testing for equalilty, less than, and greater than
  296. //
  297. i = RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength );
  298. if (i < MinLength) {
  299. return NameA->Buffer[i] < NameB->Buffer[i] ? IsLessThan :
  300. IsGreaterThan;
  301. }
  302. if (NameA->Length < NameB->Length) {
  303. return IsLessThan;
  304. }
  305. if (NameA->Length > NameB->Length) {
  306. return IsGreaterThan;
  307. }
  308. return IsEqual;
  309. }
  310. #endif if //RDBSS_OBSOLETE ...global to remove this code