Handle matching of "f0_*.*" expression to "f0_000" file name in FsRtlIsNameInExpressi...
[reactos.git] / reactos / ntoskrnl / fs / name.c
1 /* $Id: name.c,v 1.11 2004/09/04 15:02:00 navaraf Exp $
2 *
3 * reactos/ntoskrnl/fs/name.c
4 *
5 */
6
7 #include <ntoskrnl.h>
8
9 /* DATA */
10
11 PUCHAR * FsRtlLegalAnsiCharacterArray = NULL;
12
13 /**********************************************************************
14 * NAME EXPORTED
15 * FsRtlAreNamesEqual@16
16 *
17 * DESCRIPTION
18 *
19 * ARGUMENTS
20 *
21 * RETURN VALUE
22 *
23 * NOTE
24 * From Bo Branten's ntifs.h v25.
25 *
26 * @unimplemented
27 */
28 BOOLEAN STDCALL
29 FsRtlAreNamesEqual (IN PUNICODE_STRING Name1,
30 IN PUNICODE_STRING Name2,
31 IN BOOLEAN IgnoreCase,
32 IN PWCHAR UpcaseTable OPTIONAL)
33 {
34 return FALSE;
35 }
36
37
38 /**********************************************************************
39 * NAME EXPORTED
40 * FsRtlDissectName@16
41 *
42 * DESCRIPTION
43 * Dissects a given path name into first and remaining part.
44 *
45 * ARGUMENTS
46 * Name
47 * Unicode string to dissect.
48 *
49 * FirstPart
50 * Pointer to user supplied UNICODE_STRING, that will
51 * later point to the first part of the original name.
52 *
53 * RemainingPart
54 * Pointer to user supplied UNICODE_STRING, that will
55 * later point to the remaining part of the original name.
56 *
57 * RETURN VALUE
58 * None
59 *
60 * EXAMPLE
61 * Name: \test1\test2\test3
62 * FirstPart: test1
63 * RemainingPart: test2\test3
64 *
65 * @implemented
66 */
67 VOID STDCALL
68 FsRtlDissectName (IN UNICODE_STRING Name,
69 OUT PUNICODE_STRING FirstPart,
70 OUT PUNICODE_STRING RemainingPart)
71 {
72 USHORT NameOffset = 0;
73 USHORT NameLength = 0;
74 USHORT Length;
75
76 FirstPart->Length = 0;
77 FirstPart->MaximumLength = 0;
78 FirstPart->Buffer = NULL;
79
80 RemainingPart->Length = 0;
81 RemainingPart->MaximumLength = 0;
82 RemainingPart->Buffer = NULL;
83
84 if (Name.Length == 0)
85 return;
86
87 /* Skip leading backslash */
88 if (Name.Buffer[0] == L'\\')
89 NameOffset++;
90
91 Length = Name.Length / sizeof(WCHAR);
92
93 /* Search for next backslash or end-of-string */
94 while ((NameOffset + NameLength < Length) &&
95 (Name.Buffer[NameOffset + NameLength] != L'\\'))
96 {
97 NameLength++;
98 }
99
100 FirstPart->Length =
101 FirstPart->MaximumLength = NameLength * sizeof(WCHAR);
102 FirstPart->Buffer = &Name.Buffer[NameOffset];
103
104 NameOffset += NameLength + 1;
105 if (NameOffset < Length)
106 {
107 RemainingPart->Length = (Length - NameOffset) * sizeof(WCHAR);
108 RemainingPart->MaximumLength = (Length - NameOffset) * sizeof(WCHAR);
109 RemainingPart->Buffer = &Name.Buffer[NameOffset];
110 }
111 }
112
113
114 /**********************************************************************
115 * NAME EXPORTED
116 * FsRtlDoesNameContainWildCards@4
117 *
118 * DESCRIPTION
119 *
120 * ARGUMENTS
121 *
122 * RETURN VALUE
123 *
124 * NOTE
125 * From Bo Branten's ntifs.h v12.
126 *
127 * @implemented
128 */
129 BOOLEAN STDCALL
130 FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name)
131 {
132 PWCHAR Ptr;
133
134 if (Name->Length == 0)
135 return FALSE;
136
137 /* Set pointer to last character of the string */
138 Ptr = Name->Buffer + (Name->Length / sizeof(WCHAR));
139
140 while (Ptr >= Name->Buffer)
141 {
142 /* Stop at backslash */
143 if (*Ptr == L'\\')
144 return FALSE;
145
146 /* Check for wildcards */
147 if ((*Ptr < L'@') &&
148 (*Ptr == L'\"' || *Ptr == L'*' || *Ptr == L'<' ||
149 *Ptr == L'>' || *Ptr == L'?'))
150 return TRUE;
151
152 /* Move to previous character */
153 Ptr--;
154 }
155
156 return FALSE;
157 }
158
159
160 /**********************************************************************
161 * NAME EXPORTED
162 * FsRtlIsNameInExpression@16
163 *
164 * DESCRIPTION
165 *
166 * ARGUMENTS
167 *
168 * RETURN VALUE
169 *
170 * NOTE
171 * From Bo Branten's ntifs.h v12. This function should be rewritten
172 * to avoid recursion and better wildcard handling should be
173 * implemented (see FsRtlDoesNameContainWildCards).
174 *
175 * @implemented
176 */
177 BOOLEAN STDCALL
178 FsRtlIsNameInExpression (IN PUNICODE_STRING Expression,
179 IN PUNICODE_STRING Name,
180 IN BOOLEAN IgnoreCase,
181 IN PWCHAR UpcaseTable OPTIONAL)
182 {
183 USHORT ExpressionPosition, NamePosition;
184 UNICODE_STRING TempExpression, TempName;
185
186 ExpressionPosition = 0;
187 NamePosition = 0;
188 while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
189 NamePosition < (Name->Length / sizeof(WCHAR)))
190 {
191 if (Expression->Buffer[ExpressionPosition] == L'*')
192 {
193 ExpressionPosition++;
194 if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)))
195 {
196 return TRUE;
197 }
198 while (NamePosition < (Name->Length / sizeof(WCHAR)))
199 {
200 TempExpression.Length =
201 TempExpression.MaximumLength =
202 Expression->Length - (ExpressionPosition * sizeof(WCHAR));
203 TempExpression.Buffer = Expression->Buffer + ExpressionPosition;
204 TempName.Length =
205 TempName.MaximumLength =
206 Name->Length - (NamePosition * sizeof(WCHAR));
207 TempName.Buffer = Name->Buffer + NamePosition;
208 /* FIXME: Rewrite to get rid of recursion */
209 if (FsRtlIsNameInExpression(&TempExpression, &TempName,
210 IgnoreCase, UpcaseTable))
211 {
212 return TRUE;
213 }
214 NamePosition++;
215 }
216 }
217 else
218 {
219 /* FIXME: Take UpcaseTable into account! */
220 if (Expression->Buffer[ExpressionPosition] == L'?' ||
221 (IgnoreCase &&
222 RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) ==
223 RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) ||
224 (!IgnoreCase &&
225 Expression->Buffer[ExpressionPosition] ==
226 Name->Buffer[NamePosition]))
227 {
228 NamePosition++;
229 ExpressionPosition++;
230 }
231 else
232 {
233 return FALSE;
234 }
235 }
236 }
237
238 /* Handle matching of "f0_*.*" expression to "f0_000" file name. */
239 if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
240 Expression->Buffer[ExpressionPosition] == L'.')
241 {
242 while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
243 (Expression->Buffer[ExpressionPosition] == L'.' ||
244 Expression->Buffer[ExpressionPosition] == L'*' ||
245 Expression->Buffer[ExpressionPosition] == L'?'))
246 {
247 ExpressionPosition++;
248 }
249 }
250
251 if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) &&
252 NamePosition == (Name->Length / sizeof(WCHAR)))
253 {
254 return TRUE;
255 }
256
257 return FALSE;
258 }
259
260 /* EOF */