1 /* $Id: name.c,v 1.13 2004/12/30 18:30:05 ion Exp $
3 * reactos/ntoskrnl/fs/name.c
9 /* FUNCTIONS ***************************************************************/
11 /**********************************************************************
13 * FsRtlAreNamesEqual@16
22 * From Bo Branten's ntifs.h v25.
27 FsRtlAreNamesEqual (IN PUNICODE_STRING Name1
,
28 IN PUNICODE_STRING Name2
,
29 IN BOOLEAN IgnoreCase
,
30 IN PWCHAR UpcaseTable OPTIONAL
)
33 UNICODE_STRING UpcaseName1
;
34 UNICODE_STRING UpcaseName2
;
35 BOOLEAN StringsAreEqual
;
37 /* Well, first check their size */
38 if (Name1
->Length
!= Name2
->Length
) {
43 /* Turn them into Upcase if we don't have a table */
44 if (IgnoreCase
&& !UpcaseTable
) {
45 RtlUpcaseUnicodeString(&UpcaseName1
, Name1
, TRUE
);
46 RtlUpcaseUnicodeString(&UpcaseName2
, Name2
, TRUE
);
53 /* Do a case-sensitive search */
57 /* Use a raw memory compare */
58 StringsAreEqual
= RtlEqualMemory(Name1
->Buffer
,
62 /* Clear the strings if we need to */
64 RtlFreeUnicodeString(&UpcaseName1
);
65 RtlFreeUnicodeString(&UpcaseName2
);
68 /* Return the equality */
69 return StringsAreEqual
;
73 /* Case in-sensitive search */
77 for (i
= Name1
->Length
/ sizeof(WCHAR
) - 1; i
>= 0; i
--) {
79 if (UpcaseTable
[Name1
->Buffer
[i
]] != UpcaseTable
[Name2
->Buffer
[i
]]) {
81 /* Non-match found! */
86 /* We finished the loop so we are equal */
92 /**********************************************************************
97 * Dissects a given path name into first and remaining part.
101 * Unicode string to dissect.
104 * Pointer to user supplied UNICODE_STRING, that will
105 * later point to the first part of the original name.
108 * Pointer to user supplied UNICODE_STRING, that will
109 * later point to the remaining part of the original name.
115 * Name: \test1\test2\test3
117 * RemainingPart: test2\test3
122 FsRtlDissectName (IN UNICODE_STRING Name
,
123 OUT PUNICODE_STRING FirstPart
,
124 OUT PUNICODE_STRING RemainingPart
)
126 USHORT NameOffset
= 0;
127 USHORT NameLength
= 0;
130 FirstPart
->Length
= 0;
131 FirstPart
->MaximumLength
= 0;
132 FirstPart
->Buffer
= NULL
;
134 RemainingPart
->Length
= 0;
135 RemainingPart
->MaximumLength
= 0;
136 RemainingPart
->Buffer
= NULL
;
138 if (Name
.Length
== 0)
141 /* Skip leading backslash */
142 if (Name
.Buffer
[0] == L
'\\')
145 Length
= Name
.Length
/ sizeof(WCHAR
);
147 /* Search for next backslash or end-of-string */
148 while ((NameOffset
+ NameLength
< Length
) &&
149 (Name
.Buffer
[NameOffset
+ NameLength
] != L
'\\'))
155 FirstPart
->MaximumLength
= NameLength
* sizeof(WCHAR
);
156 FirstPart
->Buffer
= &Name
.Buffer
[NameOffset
];
158 NameOffset
+= NameLength
+ 1;
159 if (NameOffset
< Length
)
161 RemainingPart
->Length
= (Length
- NameOffset
) * sizeof(WCHAR
);
162 RemainingPart
->MaximumLength
= (Length
- NameOffset
) * sizeof(WCHAR
);
163 RemainingPart
->Buffer
= &Name
.Buffer
[NameOffset
];
168 /**********************************************************************
170 * FsRtlDoesNameContainWildCards@4
179 * From Bo Branten's ntifs.h v12.
184 FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name
)
188 /* Loop through every character */
190 for (Ptr
= Name
->Buffer
+ (Name
->Length
/ sizeof(WCHAR
))-1;
191 Ptr
>= Name
->Buffer
&& *Ptr
!= L
'\\';Ptr
--) {
193 /* Check for Wildcard */
194 if (FsRtlIsUnicodeCharacterWild(*Ptr
)) {
205 /**********************************************************************
207 * FsRtlIsNameInExpression@16
216 * From Bo Branten's ntifs.h v12. This function should be rewritten
217 * to avoid recursion and better wildcard handling should be
218 * implemented (see FsRtlDoesNameContainWildCards).
223 FsRtlIsNameInExpression (IN PUNICODE_STRING Expression
,
224 IN PUNICODE_STRING Name
,
225 IN BOOLEAN IgnoreCase
,
226 IN PWCHAR UpcaseTable OPTIONAL
)
228 USHORT ExpressionPosition
, NamePosition
;
229 UNICODE_STRING TempExpression
, TempName
;
231 ExpressionPosition
= 0;
233 while (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
234 NamePosition
< (Name
->Length
/ sizeof(WCHAR
)))
236 if (Expression
->Buffer
[ExpressionPosition
] == L
'*')
238 ExpressionPosition
++;
239 if (ExpressionPosition
== (Expression
->Length
/ sizeof(WCHAR
)))
243 while (NamePosition
< (Name
->Length
/ sizeof(WCHAR
)))
245 TempExpression
.Length
=
246 TempExpression
.MaximumLength
=
247 Expression
->Length
- (ExpressionPosition
* sizeof(WCHAR
));
248 TempExpression
.Buffer
= Expression
->Buffer
+ ExpressionPosition
;
250 TempName
.MaximumLength
=
251 Name
->Length
- (NamePosition
* sizeof(WCHAR
));
252 TempName
.Buffer
= Name
->Buffer
+ NamePosition
;
253 /* FIXME: Rewrite to get rid of recursion */
254 if (FsRtlIsNameInExpression(&TempExpression
, &TempName
,
255 IgnoreCase
, UpcaseTable
))
264 /* FIXME: Take UpcaseTable into account! */
265 if (Expression
->Buffer
[ExpressionPosition
] == L
'?' ||
267 RtlUpcaseUnicodeChar(Expression
->Buffer
[ExpressionPosition
]) ==
268 RtlUpcaseUnicodeChar(Name
->Buffer
[NamePosition
])) ||
270 Expression
->Buffer
[ExpressionPosition
] ==
271 Name
->Buffer
[NamePosition
]))
274 ExpressionPosition
++;
283 /* Handle matching of "f0_*.*" expression to "f0_000" file name. */
284 if (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
285 Expression
->Buffer
[ExpressionPosition
] == L
'.')
287 while (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
288 (Expression
->Buffer
[ExpressionPosition
] == L
'.' ||
289 Expression
->Buffer
[ExpressionPosition
] == L
'*' ||
290 Expression
->Buffer
[ExpressionPosition
] == L
'?'))
292 ExpressionPosition
++;
296 if (ExpressionPosition
== (Expression
->Length
/ sizeof(WCHAR
)) &&
297 NamePosition
== (Name
->Length
/ sizeof(WCHAR
)))