- Fix FsRtlDoesNameContainWildCards loop to take into account the first and lst lette...
[reactos.git] / reactos / ntoskrnl / fs / name.c
1 /* $Id: name.c,v 1.10 2004/08/18 02:32: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.
172 *
173 * @implemented
174 */
175 BOOLEAN STDCALL
176 FsRtlIsNameInExpression (IN PUNICODE_STRING Expression,
177 IN PUNICODE_STRING Name,
178 IN BOOLEAN IgnoreCase,
179 IN PWCHAR UpcaseTable OPTIONAL)
180 {
181 USHORT ExpressionPosition, NamePosition;
182 UNICODE_STRING TempExpression, TempName;
183
184 ExpressionPosition = 0;
185 NamePosition = 0;
186 while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
187 NamePosition < (Name->Length / sizeof(WCHAR)))
188 {
189 if (Expression->Buffer[ExpressionPosition] == L'*')
190 {
191 ExpressionPosition++;
192 if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)))
193 {
194 return TRUE;
195 }
196 while (NamePosition < (Name->Length / sizeof(WCHAR)))
197 {
198 TempExpression.Length =
199 TempExpression.MaximumLength =
200 Expression->Length - (ExpressionPosition * sizeof(WCHAR));
201 TempExpression.Buffer = Expression->Buffer + ExpressionPosition;
202 TempName.Length =
203 TempName.MaximumLength =
204 Name->Length - (NamePosition * sizeof(WCHAR));
205 TempName.Buffer = Name->Buffer + NamePosition;
206 /* FIXME: Rewrite to get rid of recursion */
207 if (FsRtlIsNameInExpression(&TempExpression, &TempName,
208 IgnoreCase, UpcaseTable))
209 {
210 return TRUE;
211 }
212 NamePosition++;
213 }
214 }
215
216 /* FIXME: Take UpcaseTable into account! */
217 if (Expression->Buffer[ExpressionPosition] == L'?' ||
218 (IgnoreCase &&
219 RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) ==
220 RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) ||
221 (!IgnoreCase &&
222 Expression->Buffer[ExpressionPosition] ==
223 Name->Buffer[NamePosition]))
224 {
225 NamePosition++;
226 ExpressionPosition++;
227 }
228 else
229 {
230 return FALSE;
231 }
232 }
233
234 if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) &&
235 NamePosition == (Name->Length / sizeof(WCHAR)))
236 {
237 return TRUE;
238 }
239
240 return FALSE;
241 }
242
243 /* EOF */