Standardize comment headers. Patch by Trevor McCort
[reactos.git] / reactos / ntoskrnl / fs / name.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/fs/name.c
6 * PURPOSE: No purpose listed.
7 *
8 * PROGRAMMERS: No programmer listed.
9 */
10
11 #include <ntoskrnl.h>
12
13 /* FUNCTIONS ***************************************************************/
14
15 /**********************************************************************
16 * NAME EXPORTED
17 * FsRtlAreNamesEqual@16
18 *
19 * DESCRIPTION
20 *
21 * ARGUMENTS
22 *
23 * RETURN VALUE
24 *
25 * NOTE
26 * From Bo Branten's ntifs.h v25.
27 *
28 * @implemented
29 */
30 BOOLEAN STDCALL
31 FsRtlAreNamesEqual (IN PUNICODE_STRING Name1,
32 IN PUNICODE_STRING Name2,
33 IN BOOLEAN IgnoreCase,
34 IN PWCHAR UpcaseTable OPTIONAL)
35 {
36
37 UNICODE_STRING UpcaseName1;
38 UNICODE_STRING UpcaseName2;
39 BOOLEAN StringsAreEqual;
40
41 /* Well, first check their size */
42 if (Name1->Length != Name2->Length) {
43 /* Not equal! */
44 return FALSE;
45 }
46
47 /* Turn them into Upcase if we don't have a table */
48 if (IgnoreCase && !UpcaseTable) {
49 RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE);
50 RtlUpcaseUnicodeString(&UpcaseName2, Name2, TRUE);
51 Name1 = &UpcaseName1;
52 Name2 = &UpcaseName2;
53
54 goto ManualCase;
55 }
56
57 /* Do a case-sensitive search */
58 if (!IgnoreCase) {
59
60 ManualCase:
61 /* Use a raw memory compare */
62 StringsAreEqual = RtlEqualMemory(Name1->Buffer,
63 Name2->Buffer,
64 Name1->Length);
65
66 /* Clear the strings if we need to */
67 if (IgnoreCase) {
68 RtlFreeUnicodeString(&UpcaseName1);
69 RtlFreeUnicodeString(&UpcaseName2);
70 }
71
72 /* Return the equality */
73 return StringsAreEqual;
74
75 } else {
76
77 /* Case in-sensitive search */
78
79 LONG i;
80
81 for (i = Name1->Length / sizeof(WCHAR) - 1; i >= 0; i--) {
82
83 if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) {
84
85 /* Non-match found! */
86 return FALSE;
87 }
88 }
89
90 /* We finished the loop so we are equal */
91 return TRUE;
92 }
93 }
94
95
96 /**********************************************************************
97 * NAME EXPORTED
98 * FsRtlDissectName@16
99 *
100 * DESCRIPTION
101 * Dissects a given path name into first and remaining part.
102 *
103 * ARGUMENTS
104 * Name
105 * Unicode string to dissect.
106 *
107 * FirstPart
108 * Pointer to user supplied UNICODE_STRING, that will
109 * later point to the first part of the original name.
110 *
111 * RemainingPart
112 * Pointer to user supplied UNICODE_STRING, that will
113 * later point to the remaining part of the original name.
114 *
115 * RETURN VALUE
116 * None
117 *
118 * EXAMPLE
119 * Name: \test1\test2\test3
120 * FirstPart: test1
121 * RemainingPart: test2\test3
122 *
123 * @implemented
124 */
125 VOID STDCALL
126 FsRtlDissectName (IN UNICODE_STRING Name,
127 OUT PUNICODE_STRING FirstPart,
128 OUT PUNICODE_STRING RemainingPart)
129 {
130 USHORT NameOffset = 0;
131 USHORT NameLength = 0;
132 USHORT Length;
133
134 FirstPart->Length = 0;
135 FirstPart->MaximumLength = 0;
136 FirstPart->Buffer = NULL;
137
138 RemainingPart->Length = 0;
139 RemainingPart->MaximumLength = 0;
140 RemainingPart->Buffer = NULL;
141
142 if (Name.Length == 0)
143 return;
144
145 /* Skip leading backslash */
146 if (Name.Buffer[0] == L'\\')
147 NameOffset++;
148
149 Length = Name.Length / sizeof(WCHAR);
150
151 /* Search for next backslash or end-of-string */
152 while ((NameOffset + NameLength < Length) &&
153 (Name.Buffer[NameOffset + NameLength] != L'\\'))
154 {
155 NameLength++;
156 }
157
158 FirstPart->Length =
159 FirstPart->MaximumLength = NameLength * sizeof(WCHAR);
160 FirstPart->Buffer = &Name.Buffer[NameOffset];
161
162 NameOffset += NameLength + 1;
163 if (NameOffset < Length)
164 {
165 RemainingPart->Length = (Length - NameOffset) * sizeof(WCHAR);
166 RemainingPart->MaximumLength = (Length - NameOffset) * sizeof(WCHAR);
167 RemainingPart->Buffer = &Name.Buffer[NameOffset];
168 }
169 }
170
171
172 /**********************************************************************
173 * NAME EXPORTED
174 * FsRtlDoesNameContainWildCards@4
175 *
176 * DESCRIPTION
177 *
178 * ARGUMENTS
179 *
180 * RETURN VALUE
181 *
182 * NOTE
183 * From Bo Branten's ntifs.h v12.
184 *
185 * @implemented
186 */
187 BOOLEAN STDCALL
188 FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name)
189 {
190 PWCHAR Ptr;
191
192 /* Loop through every character */
193 if (Name->Length) {
194 for (Ptr = Name->Buffer + (Name->Length / sizeof(WCHAR))-1;
195 Ptr >= Name->Buffer && *Ptr != L'\\';Ptr--) {
196
197 /* Check for Wildcard */
198 if (FsRtlIsUnicodeCharacterWild(*Ptr)) {
199 return TRUE;
200 }
201 }
202 }
203
204 /* Nothing Found */
205 return FALSE;
206 }
207
208
209 /**********************************************************************
210 * NAME EXPORTED
211 * FsRtlIsNameInExpression@16
212 *
213 * DESCRIPTION
214 *
215 * ARGUMENTS
216 *
217 * RETURN VALUE
218 *
219 * NOTE
220 * From Bo Branten's ntifs.h v12. This function should be rewritten
221 * to avoid recursion and better wildcard handling should be
222 * implemented (see FsRtlDoesNameContainWildCards).
223 *
224 * @implemented
225 */
226 BOOLEAN STDCALL
227 FsRtlIsNameInExpression (IN PUNICODE_STRING Expression,
228 IN PUNICODE_STRING Name,
229 IN BOOLEAN IgnoreCase,
230 IN PWCHAR UpcaseTable OPTIONAL)
231 {
232 USHORT ExpressionPosition, NamePosition;
233 UNICODE_STRING TempExpression, TempName;
234
235 ExpressionPosition = 0;
236 NamePosition = 0;
237 while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
238 NamePosition < (Name->Length / sizeof(WCHAR)))
239 {
240 if (Expression->Buffer[ExpressionPosition] == L'*')
241 {
242 ExpressionPosition++;
243 if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)))
244 {
245 return TRUE;
246 }
247 while (NamePosition < (Name->Length / sizeof(WCHAR)))
248 {
249 TempExpression.Length =
250 TempExpression.MaximumLength =
251 Expression->Length - (ExpressionPosition * sizeof(WCHAR));
252 TempExpression.Buffer = Expression->Buffer + ExpressionPosition;
253 TempName.Length =
254 TempName.MaximumLength =
255 Name->Length - (NamePosition * sizeof(WCHAR));
256 TempName.Buffer = Name->Buffer + NamePosition;
257 /* FIXME: Rewrite to get rid of recursion */
258 if (FsRtlIsNameInExpression(&TempExpression, &TempName,
259 IgnoreCase, UpcaseTable))
260 {
261 return TRUE;
262 }
263 NamePosition++;
264 }
265 }
266 else
267 {
268 /* FIXME: Take UpcaseTable into account! */
269 if (Expression->Buffer[ExpressionPosition] == L'?' ||
270 (IgnoreCase &&
271 RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) ==
272 RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) ||
273 (!IgnoreCase &&
274 Expression->Buffer[ExpressionPosition] ==
275 Name->Buffer[NamePosition]))
276 {
277 NamePosition++;
278 ExpressionPosition++;
279 }
280 else
281 {
282 return FALSE;
283 }
284 }
285 }
286
287 /* Handle matching of "f0_*.*" expression to "f0_000" file name. */
288 if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
289 Expression->Buffer[ExpressionPosition] == L'.')
290 {
291 while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
292 (Expression->Buffer[ExpressionPosition] == L'.' ||
293 Expression->Buffer[ExpressionPosition] == L'*' ||
294 Expression->Buffer[ExpressionPosition] == L'?'))
295 {
296 ExpressionPosition++;
297 }
298 }
299
300 if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) &&
301 NamePosition == (Name->Length / sizeof(WCHAR)))
302 {
303 return TRUE;
304 }
305
306 return FALSE;
307 }
308
309 /* EOF */