2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Unicode Prefix implementation
5 * FILE: lib/rtl/unicodeprefix.c
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES *****************************************************************/
17 * FIXME: Try to find the official names and add to NDK
18 * Definitions come from fastfat driver.
20 typedef USHORT NODE_TYPE_CODE
;
21 #define PFX_NTC_TABLE ((NODE_TYPE_CODE)0x0800)
22 #define PFX_NTC_ROOT ((NODE_TYPE_CODE)0x0801)
23 #define PFX_NTC_CHILD ((NODE_TYPE_CODE)0x0802)
24 #define PFX_NTC_CASE_MATCH ((NODE_TYPE_CODE)0x0803)
26 /* FUNCTIONS ***************************************************************/
31 ComputeUnicodeNameLength(IN PUNICODE_STRING UnicodeName
)
33 ULONG Chars
= UnicodeName
->Length
/ sizeof(WCHAR
);
34 ULONG i
, NamesFound
= 1;
37 for (i
= 0; i
< (Chars
- 1); i
++)
39 /* Check if we found a backslash, meaning another name */
40 if (UnicodeName
->Buffer
[i
] == '\\') NamesFound
++;
43 /* Return the number of names found */
50 PUNICODE_PREFIX_TABLE_ENTRY
52 RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable
,
53 PUNICODE_STRING FullName
,
54 ULONG CaseInsensitiveIndex
)
65 RtlInitializeUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable
)
68 PrefixTable
->NameLength
= 0;
69 PrefixTable
->LastNextEntry
= NULL
;
70 PrefixTable
->NodeTypeCode
= PFX_NTC_TABLE
;
71 PrefixTable
->NextPrefixTree
= (PUNICODE_PREFIX_TABLE_ENTRY
)PrefixTable
;
79 RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable
,
80 PUNICODE_STRING Prefix
,
81 PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
)
84 * implementation notes:
85 * - get name length (number of names)
87 * - find a matching tree
88 * - if !found, insert a new NTC_ROOT entry and return TRUE;
89 * - if found, loop tree and compare strings:
90 * if equal, handle casematch/nomatch
91 * if greater or lesser equal, then add left/right childs accordingly
101 PUNICODE_PREFIX_TABLE_ENTRY
103 RtlNextUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable
,
106 PRTL_SPLAY_LINKS SplayLinks
;
107 PUNICODE_PREFIX_TABLE_ENTRY Entry
;
108 PUNICODE_PREFIX_TABLE_ENTRY CaseMatchEntry
;
110 /* We might need this entry 2/3rd of the time, so cache it now */
111 CaseMatchEntry
= PrefixTable
->LastNextEntry
->CaseMatch
;
113 /* Check if this is a restart or if we don't have a last entry */
114 if ((Restart
) || !(PrefixTable
->LastNextEntry
))
116 /* Get the next entry and validate it */
117 Entry
= PrefixTable
->NextPrefixTree
;
118 if (Entry
->NodeTypeCode
== PFX_NTC_TABLE
) return NULL
;
120 /* Now get the Splay Tree Links */
121 SplayLinks
= &Entry
->Links
;
123 /* Loop until we get the first node in the tree */
124 while (RtlLeftChild(SplayLinks
)) SplayLinks
= RtlLeftChild(SplayLinks
);
126 /* Get the entry from it */
127 Entry
= CONTAINING_RECORD(SplayLinks
,
128 UNICODE_PREFIX_TABLE_ENTRY
,
131 else if (CaseMatchEntry
->NodeTypeCode
== PFX_NTC_CASE_MATCH
)
133 /* If the last entry was a Case Match, then return it */
134 Entry
= CaseMatchEntry
;
138 /* Find the successor */
139 SplayLinks
= RtlRealSuccessor(&CaseMatchEntry
->Links
);
142 /* Didn't find one, we'll have to search the tree */
143 SplayLinks
= &PrefixTable
->LastNextEntry
->Links
;
145 /* Get the topmost node (root) */
146 while (!RtlIsRoot(SplayLinks
)) SplayLinks
= RtlParent(SplayLinks
);
147 Entry
= CONTAINING_RECORD(SplayLinks
,
148 UNICODE_PREFIX_TABLE_ENTRY
,
151 /* Get its tree and make sure somethign is in it */
152 Entry
= Entry
->NextPrefixTree
;
153 if (Entry
->NameLength
<= 0) return NULL
;
155 /* Select these new links and find the first node */
156 while (RtlLeftChild(SplayLinks
)) SplayLinks
= RtlLeftChild(SplayLinks
);
159 /* Get the entry from it */
160 Entry
= CONTAINING_RECORD(SplayLinks
,
161 UNICODE_PREFIX_TABLE_ENTRY
,
165 /* Save this entry as the last one returned, and return it */
166 PrefixTable
->LastNextEntry
= Entry
;
175 RtlRemoveUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable
,
176 PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
)