Something went wrong. Try again.
Reactos
Something went wrong. Try again.
7.5 kB · 297 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298////////////////////////////////////////////////////////////////////// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine// All rights reserved// This file was released under the GPLv2 on June 2015./////////////////////////////////////////////////////////////////////* Module: Namesup.cpp
Abstract: FileName support routines*/
#include "udffs.h"
// '\dfdf\aaa\ffg' --> '\aaa\ffg'// '\aaa\ffg' --> '\ffg'PWCHAR__fastcallUDFDissectName( IN PWCHAR Buffer, OUT PUSHORT Length ){
USHORT i;
#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
PWCHAR retval;
__asm push ebx __asm push ecx
__asm mov ebx,Buffer __asm xor ecx,ecxRemove_leading_slash: __asm cmp [word ptr ebx],L'\\' __asm jne No_IncPointer __asm add ebx,2 __asm jmp Remove_leading_slashNo_IncPointer: __asm cmp [word ptr ebx],L':' __asm jne Scan_1 __asm add ebx,2 __asm inc ecx __asm jmp EO_DissectScan_1: __asm mov ax,[word ptr ebx] __asm cmp ax,L'\\' __asm je EO_Dissect __asm or ax,ax __asm jz EO_Dissect __asm cmp ax,L':' __asm jne Cont_scan __asm or ecx,ecx __asm jnz EO_DissectCont_scan: __asm inc ecx __asm add ebx,2 __asm jmp Scan_1EO_Dissect: __asm mov retval,ebx __asm mov i,cx
__asm pop ecx __asm pop ebx
*Length = i; return retval;
#else // NO X86 optimization , use generic C/C++
while (Buffer[0] == L'\\') { Buffer++; } if (Buffer[0] == L':') { *Length = 1; return &(Buffer[1]); } for(i = 0; ( Buffer[i] != L'\\' && ((Buffer[i] != L':') || !i) && Buffer[i]); i++); *Length = i; return &(Buffer[i]);
#endif // _X86_
} // end UDFDissectName()
BOOLEAN__fastcallUDFIsNameValid( IN PUNICODE_STRING SearchPattern, OUT BOOLEAN* StreamOpen, OUT ULONG* SNameIndex) { LONG Index, l; BOOLEAN _StreamOpen = FALSE; PWCHAR Buffer; WCHAR c, c0;
if(StreamOpen) (*StreamOpen) = FALSE; // We can't create nameless file or too long path if(!(l = SearchPattern->Length/sizeof(WCHAR)) || (l>UDF_X_PATH_LEN)) return FALSE; Buffer = SearchPattern->Buffer; for(Index = 0; Index<l; Index++, Buffer++) { // Check for disallowed characters c = (*Buffer); if((c == L'*') || (c == L'>') || (c == L'\"') || (c == L'/') || (c == L'<') || (c == L'|') || ((c >= 0x0000) && (c <= 0x001f)) || (c == L'?')) return FALSE; // check if this a Stream path (& validate it) if(!(_StreamOpen) && // sub-streams are not allowed (Index<(l-1)) && // stream name must be specified ((_StreamOpen) = (c == L':'))) { if(StreamOpen) (*StreamOpen) = TRUE; if(SNameIndex) (*SNameIndex) = Index; } // According to NT IFS documentation neither SPACE nor DOT can be // a trailing character if(Index && (c == L'\\') ) { if((c0 == L' ') || (_StreamOpen) || // stream is not a directory (c0 == L'.')) return FALSE; } c0 = c; } // According to NT IFS documentation neither SPACE nor DOT can be // a trailing character if((c0 == L' ') || (c0 == L'.')) return FALSE; return TRUE;} // end UDFIsNameValid()
#ifndef _CONSOLE/*
Routine Description:
This routine will compare two Unicode strings. PtrSearchPattern may contain wildcards
Return Value:
BOOLEAN - TRUE if the expressions match, FALSE otherwise.
*/BOOLEANUDFIsNameInExpression( IN PVCB Vcb, IN PUNICODE_STRING FileName, IN PUNICODE_STRING PtrSearchPattern, OUT PBOOLEAN DosOpen, IN BOOLEAN IgnoreCase, IN BOOLEAN ContainsWC, IN BOOLEAN CanBe8dot3, IN BOOLEAN KeepIntact // passed to UDFDOSName ){ BOOLEAN Match = TRUE; UNICODE_STRING ShortName; WCHAR Buffer[13];
if(!PtrSearchPattern) return TRUE; // we try to open file by LFN by default if(DosOpen) (*DosOpen) = FALSE; // If there are wildcards in the expression then we call the // appropriate FsRtlRoutine. if(ContainsWC) { Match = FsRtlIsNameInExpression( PtrSearchPattern, FileName, IgnoreCase, NULL ); // Otherwise do a direct memory comparison for the name string. } else if (RtlCompareUnicodeString(FileName, PtrSearchPattern, IgnoreCase)) { Match = FALSE; }
if(Match) return TRUE;
// check if SFN can match this pattern if(!CanBe8dot3) return FALSE;
// try to open by SFN ShortName.Buffer = (PWCHAR)(&Buffer); ShortName.MaximumLength = 13*sizeof(WCHAR); UDFDOSName(Vcb, &ShortName, FileName, KeepIntact);
// PtrSearchPattern is upcased if we are called with IgnoreCase=TRUE // DOSName is always upcased // thus, we can use case-sensetive compare here to improve performance if(ContainsWC) { Match = FsRtlIsNameInExpression( PtrSearchPattern, &ShortName, FALSE, NULL ); // Otherwise do a direct memory comparison for the name string. } else if (!RtlCompareUnicodeString(&ShortName, PtrSearchPattern, FALSE)) { Match = TRUE; } if(DosOpen && Match) { // remember that we've opened file by SFN (*DosOpen) = TRUE; } return Match;} // end UDFIsNameInExpression()
#endif
BOOLEAN__fastcallUDFIsMatchAllMask( IN PUNICODE_STRING Name, OUT BOOLEAN* DosOpen ){ USHORT i; PWCHAR Buffer;
if(DosOpen) *DosOpen = FALSE; Buffer = Name->Buffer; if(Name->Length == sizeof(WCHAR)) { // Win32-style wildcard if((*Buffer) != L'*') return FALSE; return TRUE; } else if(Name->Length == sizeof(WCHAR)*(8+1+3)) { // DOS-style wildcard for(i=0;i<8;i++,Buffer++) { if((*Buffer) != DOS_QM) return FALSE; } if((*Buffer) != DOS_DOT) return FALSE; Buffer++; for(i=9;i<12;i++,Buffer++) { if((*Buffer) != DOS_QM) return FALSE; } if(DosOpen) *DosOpen = TRUE; return TRUE; } else if(Name->Length == sizeof(WCHAR)*(3)) { // DOS-style wildcard if(Buffer[0] != DOS_STAR) return FALSE; if(Buffer[1] != DOS_DOT) return FALSE; if(Buffer[2] != DOS_STAR) return FALSE; if(DosOpen) *DosOpen = TRUE; return TRUE; } else { return FALSE; }} // end UDFIsMatchAllMask()
BOOLEAN__fastcallUDFCanNameBeA8dot3( IN PUNICODE_STRING Name ){ if(Name->Length >= 13 * sizeof(WCHAR)) return FALSE;
ULONG i,l; ULONG dot_pos=0; ULONG ext_len=0; PWCHAR buff = Name->Buffer;
l = Name->Length / sizeof(WCHAR);
for(i=0; i<l; i++, buff++) { if( ((*buff) == L'.') || ((*buff) == DOS_DOT) ) { if(dot_pos) return FALSE; dot_pos = i+1; } else if(dot_pos) { ext_len++; if(ext_len > 3) return FALSE; } else if(i >= 8) { return FALSE; } } return TRUE;} // end UDFCanNameBeA8dot3()