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'
38 __asm cmp
[word ptr ebx
],L
'\\'
39 __asm jne No_IncPointer
41 __asm jmp Remove_leading_slash
43 __asm cmp
[word ptr ebx
],L
':'
49 __asm mov ax
,[word ptr ebx
]
72 #else // NO X86 optimization , use generic C/C++
74 while (Buffer
[0] == L
'\\') {
77 if (Buffer
[0] == L
':') {
81 for(i
= 0; ( Buffer
[i
] != L
'\\' &&
82 ((Buffer
[i
] != L
':') || !i
) &&
89 } // end UDFDissectName()
94 IN PUNICODE_STRING SearchPattern
,
95 OUT BOOLEAN
* StreamOpen
,
99 BOOLEAN _StreamOpen
= FALSE
;
103 if(StreamOpen
) (*StreamOpen
) = FALSE
;
104 // We can't create nameless file or too long path
105 if(!(l
= SearchPattern
->Length
/sizeof(WCHAR
)) ||
106 (l
>UDF_X_PATH_LEN
)) return FALSE
;
107 Buffer
= SearchPattern
->Buffer
;
108 for(Index
= 0; Index
<l
; Index
++, Buffer
++) {
109 // Check for disallowed characters
117 ((c
>= 0x0000) && (c
<= 0x001f)) ||
118 (c
== L
'?')) return FALSE
;
119 // check if this a Stream path (& validate it)
120 if(!(_StreamOpen
) && // sub-streams are not allowed
121 (Index
<(l
-1)) && // stream name must be specified
122 ((_StreamOpen
) = (c
== L
':'))) {
123 if(StreamOpen
) (*StreamOpen
) = TRUE
;
124 if(SNameIndex
) (*SNameIndex
) = Index
;
126 // According to NT IFS documentation neither SPACE nor DOT can be
127 // a trailing character
128 if(Index
&& (c
== L
'\\') ) {
130 (_StreamOpen
) || // stream is not a directory
131 (c0
== L
'.')) return FALSE
;
135 // According to NT IFS documentation neither SPACE nor DOT can be
136 // a trailing character
138 (c0
== L
'.')) return FALSE
;
140 } // end UDFIsNameValid()
148 This routine will compare two Unicode strings.
149 PtrSearchPattern may contain wildcards
153 BOOLEAN - TRUE if the expressions match, FALSE otherwise.
157 UDFIsNameInExpression(
159 IN PUNICODE_STRING FileName
,
160 IN PUNICODE_STRING PtrSearchPattern
,
161 OUT PBOOLEAN DosOpen
,
162 IN BOOLEAN IgnoreCase
,
163 IN BOOLEAN ContainsWC
,
164 IN BOOLEAN CanBe8dot3
,
165 IN BOOLEAN KeepIntact
// passed to UDFDOSName
168 BOOLEAN Match
= TRUE
;
169 UNICODE_STRING ShortName
;
172 if(!PtrSearchPattern
) return TRUE
;
173 // we try to open file by LFN by default
174 if(DosOpen
) (*DosOpen
) = FALSE
;
175 // If there are wildcards in the expression then we call the
176 // appropriate FsRtlRoutine.
178 Match
= FsRtlIsNameInExpression( PtrSearchPattern
, FileName
, IgnoreCase
, NULL
);
179 // Otherwise do a direct memory comparison for the name string.
180 } else if (RtlCompareUnicodeString(FileName
, PtrSearchPattern
, IgnoreCase
)) {
184 if(Match
) return TRUE
;
186 // check if SFN can match this pattern
190 // try to open by SFN
191 ShortName
.Buffer
= (PWCHAR
)(&Buffer
);
192 ShortName
.MaximumLength
= 13*sizeof(WCHAR
);
193 UDFDOSName(Vcb
, &ShortName
, FileName
, KeepIntact
);
195 // PtrSearchPattern is upcased if we are called with IgnoreCase=TRUE
196 // DOSName is always upcased
197 // thus, we can use case-sensetive compare here to improve performance
199 Match
= FsRtlIsNameInExpression( PtrSearchPattern
, &ShortName
, FALSE
, NULL
);
200 // Otherwise do a direct memory comparison for the name string.
201 } else if (!RtlCompareUnicodeString(&ShortName
, PtrSearchPattern
, FALSE
)) {
204 if(DosOpen
&& Match
) {
205 // remember that we've opened file by SFN
209 } // end UDFIsNameInExpression()
216 IN PUNICODE_STRING Name
,
225 Buffer
= Name
->Buffer
;
226 if(Name
->Length
== sizeof(WCHAR
)) {
227 // Win32-style wildcard
228 if((*Buffer
) != L
'*')
232 if(Name
->Length
== sizeof(WCHAR
)*(8+1+3)) {
233 // DOS-style wildcard
234 for(i
=0;i
<8;i
++,Buffer
++) {
235 if((*Buffer
) != DOS_QM
)
238 if((*Buffer
) != DOS_DOT
)
241 for(i
=9;i
<12;i
++,Buffer
++) {
242 if((*Buffer
) != DOS_QM
)
249 if(Name
->Length
== sizeof(WCHAR
)*(3)) {
250 // DOS-style wildcard
251 if(Buffer
[0] != DOS_STAR
)
253 if(Buffer
[1] != DOS_DOT
)
255 if(Buffer
[2] != DOS_STAR
)
263 } // end UDFIsMatchAllMask()
268 IN PUNICODE_STRING Name
271 if(Name
->Length
>= 13 * sizeof(WCHAR
))
277 PWCHAR buff
= Name
->Buffer
;
279 l
= Name
->Length
/ sizeof(WCHAR
);
281 for(i
=0; i
<l
; i
++, buff
++) {
282 if( ((*buff
) == L
'.') ||
283 ((*buff
) == DOS_DOT
) ) {
298 } // end UDFCanNameBeA8dot3()