2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/fsrtl/name.c
5 * PURPOSE: Provides name parsing and other support routines for FSDs
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Filip Navara (navaraf@reactos.org)
10 /* INCLUDES ******************************************************************/
16 /* PUBLIC FUNCTIONS **********************************************************/
19 * @name FsRtlAreNamesEqual
38 * @remarks From Bo Branten's ntifs.h v25.
43 FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1
,
44 IN PCUNICODE_STRING Name2
,
45 IN BOOLEAN IgnoreCase
,
46 IN PCWCH UpcaseTable OPTIONAL
)
48 UNICODE_STRING UpcaseName1
;
49 UNICODE_STRING UpcaseName2
;
50 BOOLEAN StringsAreEqual
, MemoryAllocated
= FALSE
;
54 /* Well, first check their size */
55 if (Name1
->Length
!= Name2
->Length
) return FALSE
;
57 /* Check if the caller didn't give an upcase table */
58 if ((IgnoreCase
) && !(UpcaseTable
))
60 /* Upcase the string ourselves */
61 Status
= RtlUpcaseUnicodeString(&UpcaseName1
, Name1
, TRUE
);
62 if (!NT_SUCCESS(Status
)) RtlRaiseStatus(Status
);
64 /* Upcase the second string too */
65 RtlUpcaseUnicodeString(&UpcaseName2
, Name2
, TRUE
);
69 /* Make sure we go through the path below, but free the strings */
71 MemoryAllocated
= TRUE
;
74 /* Do a case-sensitive search */
77 /* Use a raw memory compare */
78 StringsAreEqual
= RtlEqualMemory(Name1
->Buffer
,
82 /* Check if we allocated strings */
86 RtlFreeUnicodeString(&UpcaseName1
);
87 RtlFreeUnicodeString(&UpcaseName2
);
90 /* Return the equality */
91 return StringsAreEqual
;
95 /* Case in-sensitive search */
96 for (i
= 0; i
< Name1
->Length
/ sizeof(WCHAR
); i
++)
98 /* Check if the character matches */
99 if (UpcaseTable
[Name1
->Buffer
[i
]] != UpcaseTable
[Name2
->Buffer
[i
]])
101 /* Non-match found! */
106 /* We finished the loop so we are equal */
112 * @name FsRtlDissectName
115 * Dissects a given path name into first and remaining part.
118 * Unicode string to dissect.
121 * Pointer to user supplied UNICODE_STRING, that will later point
122 * to the first part of the original name.
124 * @param RemainingPart
125 * Pointer to user supplied UNICODE_STRING, that will later point
126 * to the remaining part of the original name.
131 * Name: \test1\test2\test3
133 * RemainingPart: test2\test3
138 FsRtlDissectName(IN UNICODE_STRING Name
,
139 OUT PUNICODE_STRING FirstPart
,
140 OUT PUNICODE_STRING RemainingPart
)
146 * @name FsRtlDoesNameContainWildCards
152 * Pointer to a UNICODE_STRING containing Name to examine
154 * @return TRUE if Name contains wildcards, FALSE otherwise
156 * @remarks From Bo Branten's ntifs.h v12.
161 FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name
)
165 /* Loop through every character */
168 Ptr
= Name
->Buffer
+ (Name
->Length
/ sizeof(WCHAR
)) - 1;
169 while ((Ptr
>= Name
->Buffer
) && (*Ptr
!= L
'\\'))
171 /* Check for Wildcard */
172 if (FsRtlIsUnicodeCharacterWild(*Ptr
)) return TRUE
;
182 * @name FsRtlIsNameInExpression
187 * @param DeviceObject
193 * @return TRUE if Name is in Expression, FALSE otherwise
195 * @remarks From Bo Branten's ntifs.h v12. This function should be
196 * rewritten to avoid recursion and better wildcard handling
197 * should be implemented (see FsRtlDoesNameContainWildCards).
202 FsRtlIsNameInExpression(IN PUNICODE_STRING Expression
,
203 IN PUNICODE_STRING Name
,
204 IN BOOLEAN IgnoreCase
,
205 IN PWCHAR UpcaseTable OPTIONAL
)
207 USHORT ExpressionPosition
, NamePosition
;
208 UNICODE_STRING TempExpression
, TempName
;
210 ExpressionPosition
= 0;
212 while (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
213 NamePosition
< (Name
->Length
/ sizeof(WCHAR
)))
215 if (Expression
->Buffer
[ExpressionPosition
] == L
'*')
217 ExpressionPosition
++;
218 if (ExpressionPosition
== (Expression
->Length
/ sizeof(WCHAR
)))
222 while (NamePosition
< (Name
->Length
/ sizeof(WCHAR
)))
224 TempExpression
.Length
=
225 TempExpression
.MaximumLength
=
226 Expression
->Length
- (ExpressionPosition
* sizeof(WCHAR
));
227 TempExpression
.Buffer
= Expression
->Buffer
+ ExpressionPosition
;
229 TempName
.MaximumLength
=
230 Name
->Length
- (NamePosition
* sizeof(WCHAR
));
231 TempName
.Buffer
= Name
->Buffer
+ NamePosition
;
232 /* FIXME: Rewrite to get rid of recursion */
233 if (FsRtlIsNameInExpression(&TempExpression
, &TempName
,
234 IgnoreCase
, UpcaseTable
))
243 /* FIXME: Take UpcaseTable into account! */
244 if (Expression
->Buffer
[ExpressionPosition
] == L
'?' ||
246 RtlUpcaseUnicodeChar(Expression
->Buffer
[ExpressionPosition
]) ==
247 RtlUpcaseUnicodeChar(Name
->Buffer
[NamePosition
])) ||
249 Expression
->Buffer
[ExpressionPosition
] ==
250 Name
->Buffer
[NamePosition
]))
253 ExpressionPosition
++;
262 /* Handle matching of "f0_*.*" expression to "f0_000" file name. */
263 if (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
264 Expression
->Buffer
[ExpressionPosition
] == L
'.')
266 while (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
267 (Expression
->Buffer
[ExpressionPosition
] == L
'.' ||
268 Expression
->Buffer
[ExpressionPosition
] == L
'*' ||
269 Expression
->Buffer
[ExpressionPosition
] == L
'?'))
271 ExpressionPosition
++;
275 if (ExpressionPosition
== (Expression
->Length
/ sizeof(WCHAR
)) &&
276 NamePosition
== (Name
->Length
/ sizeof(WCHAR
)))