3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/fs/name.c
6 * PURPOSE: No purpose listed.
8 * PROGRAMMERS: No programmer listed.
13 /* FUNCTIONS ***************************************************************/
15 /**********************************************************************
17 * FsRtlAreNamesEqual@16
26 * From Bo Branten's ntifs.h v25.
31 FsRtlAreNamesEqual (IN PUNICODE_STRING Name1
,
32 IN PUNICODE_STRING Name2
,
33 IN BOOLEAN IgnoreCase
,
34 IN PWCHAR UpcaseTable OPTIONAL
)
37 UNICODE_STRING UpcaseName1
;
38 UNICODE_STRING UpcaseName2
;
39 BOOLEAN StringsAreEqual
;
41 /* Well, first check their size */
42 if (Name1
->Length
!= Name2
->Length
) {
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
);
57 /* Do a case-sensitive search */
61 /* Use a raw memory compare */
62 StringsAreEqual
= RtlEqualMemory(Name1
->Buffer
,
66 /* Clear the strings if we need to */
68 RtlFreeUnicodeString(&UpcaseName1
);
69 RtlFreeUnicodeString(&UpcaseName2
);
72 /* Return the equality */
73 return StringsAreEqual
;
77 /* Case in-sensitive search */
81 for (i
= Name1
->Length
/ sizeof(WCHAR
) - 1; i
>= 0; i
--) {
83 if (UpcaseTable
[Name1
->Buffer
[i
]] != UpcaseTable
[Name2
->Buffer
[i
]]) {
85 /* Non-match found! */
90 /* We finished the loop so we are equal */
96 /**********************************************************************
101 * Dissects a given path name into first and remaining part.
105 * Unicode string to dissect.
108 * Pointer to user supplied UNICODE_STRING, that will
109 * later point to the first part of the original name.
112 * Pointer to user supplied UNICODE_STRING, that will
113 * later point to the remaining part of the original name.
119 * Name: \test1\test2\test3
121 * RemainingPart: test2\test3
126 FsRtlDissectName (IN UNICODE_STRING Name
,
127 OUT PUNICODE_STRING FirstPart
,
128 OUT PUNICODE_STRING RemainingPart
)
130 USHORT NameOffset
= 0;
131 USHORT NameLength
= 0;
134 FirstPart
->Length
= 0;
135 FirstPart
->MaximumLength
= 0;
136 FirstPart
->Buffer
= NULL
;
138 RemainingPart
->Length
= 0;
139 RemainingPart
->MaximumLength
= 0;
140 RemainingPart
->Buffer
= NULL
;
142 if (Name
.Length
== 0)
145 /* Skip leading backslash */
146 if (Name
.Buffer
[0] == L
'\\')
149 Length
= Name
.Length
/ sizeof(WCHAR
);
151 /* Search for next backslash or end-of-string */
152 while ((NameOffset
+ NameLength
< Length
) &&
153 (Name
.Buffer
[NameOffset
+ NameLength
] != L
'\\'))
159 FirstPart
->MaximumLength
= NameLength
* sizeof(WCHAR
);
160 FirstPart
->Buffer
= &Name
.Buffer
[NameOffset
];
162 NameOffset
+= NameLength
+ 1;
163 if (NameOffset
< Length
)
165 RemainingPart
->Length
= (Length
- NameOffset
) * sizeof(WCHAR
);
166 RemainingPart
->MaximumLength
= (Length
- NameOffset
) * sizeof(WCHAR
);
167 RemainingPart
->Buffer
= &Name
.Buffer
[NameOffset
];
172 /**********************************************************************
174 * FsRtlDoesNameContainWildCards@4
183 * From Bo Branten's ntifs.h v12.
188 FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name
)
192 /* Loop through every character */
194 for (Ptr
= Name
->Buffer
+ (Name
->Length
/ sizeof(WCHAR
))-1;
195 Ptr
>= Name
->Buffer
&& *Ptr
!= L
'\\';Ptr
--) {
197 /* Check for Wildcard */
198 if (FsRtlIsUnicodeCharacterWild(*Ptr
)) {
209 /**********************************************************************
211 * FsRtlIsNameInExpression@16
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).
227 FsRtlIsNameInExpression (IN PUNICODE_STRING Expression
,
228 IN PUNICODE_STRING Name
,
229 IN BOOLEAN IgnoreCase
,
230 IN PWCHAR UpcaseTable OPTIONAL
)
232 USHORT ExpressionPosition
, NamePosition
;
233 UNICODE_STRING TempExpression
, TempName
;
235 ExpressionPosition
= 0;
237 while (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
238 NamePosition
< (Name
->Length
/ sizeof(WCHAR
)))
240 if (Expression
->Buffer
[ExpressionPosition
] == L
'*')
242 ExpressionPosition
++;
243 if (ExpressionPosition
== (Expression
->Length
/ sizeof(WCHAR
)))
247 while (NamePosition
< (Name
->Length
/ sizeof(WCHAR
)))
249 TempExpression
.Length
=
250 TempExpression
.MaximumLength
=
251 Expression
->Length
- (ExpressionPosition
* sizeof(WCHAR
));
252 TempExpression
.Buffer
= Expression
->Buffer
+ ExpressionPosition
;
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
))
268 /* FIXME: Take UpcaseTable into account! */
269 if (Expression
->Buffer
[ExpressionPosition
] == L
'?' ||
271 RtlUpcaseUnicodeChar(Expression
->Buffer
[ExpressionPosition
]) ==
272 RtlUpcaseUnicodeChar(Name
->Buffer
[NamePosition
])) ||
274 Expression
->Buffer
[ExpressionPosition
] ==
275 Name
->Buffer
[NamePosition
]))
278 ExpressionPosition
++;
287 /* Handle matching of "f0_*.*" expression to "f0_000" file name. */
288 if (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
289 Expression
->Buffer
[ExpressionPosition
] == L
'.')
291 while (ExpressionPosition
< (Expression
->Length
/ sizeof(WCHAR
)) &&
292 (Expression
->Buffer
[ExpressionPosition
] == L
'.' ||
293 Expression
->Buffer
[ExpressionPosition
] == L
'*' ||
294 Expression
->Buffer
[ExpressionPosition
] == L
'?'))
296 ExpressionPosition
++;
300 if (ExpressionPosition
== (Expression
->Length
/ sizeof(WCHAR
)) &&
301 NamePosition
== (Name
->Length
/ sizeof(WCHAR
)))