1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
10 Abstract: FileName support routines
15 // '\dfdf\aaa\ffg' --> '\aaa\ffg'
16 // '\aaa\ffg' --> '\ffg'
27 #if defined (_X86_) && defined (_MSC_VER)
37 __asm cmp
[word ptr ebx
],L
'\\'
38 __asm jne No_IncPointer
40 __asm jmp Remove_leading_slash
42 __asm cmp
[word ptr ebx
],L
':'
48 __asm mov ax
,[word ptr ebx
]
71 #else // NO X86 optimization , use generic C/C++
73 while (Buffer
[0] == L
'\\') {
76 if (Buffer
[0] == L
':') {
80 for(i
= 0; ( Buffer
[i
] != L
'\\' &&
81 ((Buffer
[i
] != L
':') || !i
) &&
88 } // end UDFDissectName()
93 IN PUNICODE_STRING SearchPattern
,
94 OUT BOOLEAN
* StreamOpen
,
98 BOOLEAN _StreamOpen
= FALSE
;
102 if(StreamOpen
) (*StreamOpen
) = FALSE
;
103 // We can't create nameless file or too long path
104 if(!(l
= SearchPattern
->Length
/sizeof(WCHAR
)) ||
105 (l
>UDF_X_PATH_LEN
)) return FALSE
;
106 Buffer
= SearchPattern
->Buffer
;
107 for(Index
= 0; Index
<l
; Index
++, Buffer
++) {
108 // Check for disallowed characters
116 ((c
>= 0x0000) && (c
<= 0x001f)) ||
117 (c
== L
'?')) return FALSE
;
118 // check if this a Stream path (& validate it)
119 if(!(_StreamOpen
) && // sub-streams are not allowed
120 (Index
<(l
-1)) && // stream name must be specified
121 ((_StreamOpen
) = (c
== L
':'))) {
122 if(StreamOpen
) (*StreamOpen
) = TRUE
;
123 if(SNameIndex
) (*SNameIndex
) = Index
;
125 // According to NT IFS documentation neither SPACE nor DOT can be
126 // a trailing character
127 if(Index
&& (c
== L
'\\') ) {
129 (_StreamOpen
) || // stream is not a directory
130 (c0
== L
'.')) return FALSE
;
134 // According to NT IFS documentation neither SPACE nor DOT can be
135 // a trailing character
137 (c0
== L
'.')) return FALSE
;
139 } // end UDFIsNameValid()
147 This routine will compare two Unicode strings.
148 PtrSearchPattern may contain wildcards
152 BOOLEAN - TRUE if the expressions match, FALSE otherwise.
156 UDFIsNameInExpression(
158 IN PUNICODE_STRING FileName
,
159 IN PUNICODE_STRING PtrSearchPattern
,
160 OUT PBOOLEAN DosOpen
,
161 IN BOOLEAN IgnoreCase
,
162 IN BOOLEAN ContainsWC
,
163 IN BOOLEAN CanBe8dot3
,
164 IN BOOLEAN KeepIntact
// passed to UDFDOSName
167 BOOLEAN Match
= TRUE
;
168 UNICODE_STRING ShortName
;
171 if(!PtrSearchPattern
) return TRUE
;
172 // we try to open file by LFN by default
173 if(DosOpen
) (*DosOpen
) = FALSE
;
174 // If there are wildcards in the expression then we call the
175 // appropriate FsRtlRoutine.
177 Match
= FsRtlIsNameInExpression( PtrSearchPattern
, FileName
, IgnoreCase
, NULL
);
178 // Otherwise do a direct memory comparison for the name string.
179 } else if (RtlCompareUnicodeString(FileName
, PtrSearchPattern
, IgnoreCase
)) {
183 if(Match
) return TRUE
;
185 // check if SFN can match this pattern
189 // try to open by SFN
190 ShortName
.Buffer
= (PWCHAR
)(&Buffer
);
191 ShortName
.MaximumLength
= 13*sizeof(WCHAR
);
192 UDFDOSName(Vcb
, &ShortName
, FileName
, KeepIntact
);
194 // PtrSearchPattern is upcased if we are called with IgnoreCase=TRUE
195 // DOSName is always upcased
196 // thus, we can use case-sensetive compare here to improve performance
198 Match
= FsRtlIsNameInExpression( PtrSearchPattern
, &ShortName
, FALSE
, NULL
);
199 // Otherwise do a direct memory comparison for the name string.
200 } else if (!RtlCompareUnicodeString(&ShortName
, PtrSearchPattern
, FALSE
)) {
203 if(DosOpen
&& Match
) {
204 // remember that we've opened file by SFN
208 } // end UDFIsNameInExpression()
215 IN PUNICODE_STRING Name
,
224 Buffer
= Name
->Buffer
;
225 if(Name
->Length
== sizeof(WCHAR
)) {
226 // Win32-style wildcard
227 if((*Buffer
) != L
'*')
231 if(Name
->Length
== sizeof(WCHAR
)*(8+1+3)) {
232 // DOS-style wildcard
233 for(i
=0;i
<8;i
++,Buffer
++) {
234 if((*Buffer
) != DOS_QM
)
237 if((*Buffer
) != DOS_DOT
)
240 for(i
=9;i
<12;i
++,Buffer
++) {
241 if((*Buffer
) != DOS_QM
)
248 if(Name
->Length
== sizeof(WCHAR
)*(3)) {
249 // DOS-style wildcard
250 if(Buffer
[0] != DOS_STAR
)
252 if(Buffer
[1] != DOS_DOT
)
254 if(Buffer
[2] != DOS_STAR
)
262 } // end UDFIsMatchAllMask()
267 IN PUNICODE_STRING Name
270 if(Name
->Length
>= 13 * sizeof(WCHAR
))
276 PWCHAR buff
= Name
->Buffer
;
278 l
= Name
->Length
/ sizeof(WCHAR
);
280 for(i
=0; i
<l
; i
++, buff
++) {
281 if( ((*buff
) == L
'.') ||
282 ((*buff
) == DOS_DOT
) ) {
297 } // end UDFCanNameBeA8dot3()