Author: pschweitzer Date: Wed Apr 24 20:36:33 2013 New Revision: 58847 URL: http://svn.reactos.org/svn/reactos?rev=58847&view=rev Log: [NTOSKRNL] Reimplement (yes, once more...) all the DOS wildcards in FsRtlIs*InExpression(). This time with a better understanding of MSDN (doc can be sometimes quite cryptic...). Which means that now the functions are passing all the tests and are even simpler.
Modified: trunk/reactos/ntoskrnl/fsrtl/dbcsname.c trunk/reactos/ntoskrnl/fsrtl/name.c Modified: trunk/reactos/ntoskrnl/fsrtl/dbcsname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/dbcsname.c?rev=58847&r1=58846&r2=58847&view=diff ============================================================================== --- trunk/reactos/ntoskrnl/fsrtl/dbcsname.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/fsrtl/dbcsname.c [iso-8859-1] Wed Apr 24 20:36:33 2013 @@ -160,10 +160,9 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, IN PANSI_STRING Name) { - SHORT StarFound = -1; - PUSHORT BackTracking = NULL; - USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars; - BOOLEAN BeyondName; + SHORT StarFound = -1, DosStarFound = -1; + PUSHORT BackTracking = NULL, DosBackTracking = NULL; + USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot; PAGED_CODE(); ASSERT(Name->Length); @@ -222,129 +221,83 @@ /* Check DOS_STAR */ else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR) { - /* We can only consume dot if that's not the last one - * Otherwise, we null match - */ - if (Name->Buffer[NamePosition] == '.') - { - MatchingChars = NamePosition + 1; - while (MatchingChars < Name->Length) - { - if (Name->Buffer[MatchingChars] == '.') - { - NamePosition++; - break; - } - MatchingChars++; - } - - /* In case we were already at last dot, simply accept it */ - if (MatchingChars == Name->Length) - { - NamePosition++; - } - } - else - { - /* XXX: Eat everything till the end */ - if (ExpressionPosition + 1 == Expression->Length) - { - NamePosition = Name->Length; - } - - /* Try to eat till the next matching char or . */ - MatchingChars = NamePosition; - while (MatchingChars < Name->Length) - { - if (ExpressionPosition + 1 < Expression->Length && - Name->Buffer[MatchingChars] == Expression->Buffer[ExpressionPosition + 1]) - { - NamePosition = MatchingChars; - break; - } - else if (Name->Buffer[MatchingChars] == '.') - { - NamePosition = MatchingChars + 1; - break; - } - MatchingChars++; - } - } - ExpressionPosition++; - } - /* Check DOS_DOT */ - else if (Expression->Buffer[ExpressionPosition] == DOS_DOT) - { - /* First try to find whether we are beyond last dot (beyond name) */ - BeyondName = TRUE; - MatchingChars = NamePosition + 1; + /* Skip contigous stars */ + while (ExpressionPosition + 1 < Expression->Length && Expression->Buffer[ExpressionPosition + 1] == ANSI_DOS_STAR) + { + ExpressionPosition++; + } + + /* Look for last dot */ + MatchingChars = 0; + LastDot = (USHORT)-1; while (MatchingChars < Name->Length) { if (Name->Buffer[MatchingChars] == '.') { - BeyondName = FALSE; - break; + LastDot = MatchingChars; + if (LastDot > NamePosition) + break; } + MatchingChars++; } - /* If we are beyond name, we null match */ - if (BeyondName) - { + /* If we don't have dots or we didn't find last yet + * start eating everything + */ + if (MatchingChars != Name->Length || LastDot == (USHORT)-1) + { + if (!DosBackTracking) DosBackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, + Expression->Length * sizeof(USHORT), 'nrSF'); + DosBackTracking[++DosStarFound] = ExpressionPosition++; + + /* Not the same char, start exploring */ + if (Expression->Buffer[ExpressionPosition] != Name->Buffer[NamePosition]) + NamePosition++; + } + else + { + /* Else, if we are at last dot, eat it - otherwise, null match */ if (Name->Buffer[NamePosition] == '.') - { NamePosition++; - } - ExpressionPosition++; - continue; - } - /* If not, we only match a dot */ - else if (Name->Buffer[NamePosition] == '.') + + ExpressionPosition++; + } + } + /* Check DOS_DOT */ + else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT) + { + /* We only match dots */ + if (Name->Buffer[NamePosition] == '.') { NamePosition++; - ExpressionPosition++; - continue; - } - /* Otherwise, fail */ - else - { - break; - } + } + /* Try to explore later on for null matching */ + else if (ExpressionPosition + 1 < Expression->Length && + Name->Buffer[NamePosition] == Expression->Buffer[ExpressionPosition + 1]) + { + NamePosition++; + } + ExpressionPosition++; } /* Check DOS_QM */ else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM) { - /* Check whether we are upon a dot */ - MatchingChars = 0; - while (MatchingChars < NamePosition) - { - if (Name->Buffer[MatchingChars] == '.') - { - break; - } - MatchingChars++; - } - - /* If not, we match a single char */ - if (MatchingChars == NamePosition && Name->Buffer[NamePosition] != '.') + /* We match everything except dots */ + if (Name->Buffer[NamePosition] != '.') { NamePosition++; - ExpressionPosition++; - } - else - { - /* If we are, we just go through QMs */ - while (ExpressionPosition < Expression->Length && - Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM) - { - ExpressionPosition++; - } - } + } + ExpressionPosition++; } /* If nothing match, try to backtrack */ else if (StarFound >= 0) { ExpressionPosition = BackTracking[StarFound--]; + } + else if (DosStarFound >= 0) + { + ExpressionPosition = DosBackTracking[DosStarFound--]; } /* Otherwise, fail */ else @@ -378,6 +331,10 @@ if (BackTracking) { ExFreePoolWithTag(BackTracking, 'nrSF'); + } + if (DosBackTracking) + { + ExFreePoolWithTag(DosBackTracking, 'nrSF'); } return (ExpressionPosition == Expression->Length && NamePosition == Name->Length); Modified: trunk/reactos/ntoskrnl/fsrtl/name.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/name.c?rev=58847&r1=58846&r2=58847&view=diff ============================================================================== --- trunk/reactos/ntoskrnl/fsrtl/name.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/fsrtl/name.c [iso-8859-1] Wed Apr 24 20:36:33 2013 @@ -23,12 +23,11 @@ IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL) { - SHORT StarFound = -1; - PUSHORT BackTracking = NULL; + SHORT StarFound = -1, DosStarFound = -1; + PUSHORT BackTracking = NULL, DosBackTracking = NULL; UNICODE_STRING IntExpression; - USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars; + USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot; WCHAR CompareChar; - BOOLEAN BeyondName; PAGED_CODE(); /* Check if we were given strings at all */ @@ -153,129 +152,85 @@ /* Check DOS_STAR */ else if (Expression->Buffer[ExpressionPosition] == DOS_STAR) { - /* We can only consume dot if that's not the last one - * Otherwise, we null match + /* Skip contigous stars */ + while ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) && + (Expression->Buffer[ExpressionPosition + 1] == DOS_STAR)) + { + ExpressionPosition++; + } + + /* Look for last dot */ + MatchingChars = 0; + LastDot = (USHORT)-1; + while (MatchingChars < Name->Length / sizeof(WCHAR)) + { + if (Name->Buffer[MatchingChars] == L'.') + { + LastDot = MatchingChars; + if (LastDot > NamePosition) + break; + } + + MatchingChars++; + } + + /* If we don't have dots or we didn't find last yet + * start eating everything */ - if (Name->Buffer[NamePosition] == L'.') - { - MatchingChars = NamePosition + 1; - while (MatchingChars < Name->Length / sizeof(WCHAR)) - { - if (Name->Buffer[MatchingChars] == L'.') - { - NamePosition++; - break; - } - MatchingChars++; - } - - /* In case we were already at last dot, simply accept it */ - if (MatchingChars == Name->Length / sizeof(WCHAR)) - { + if (MatchingChars != Name->Length || LastDot == (USHORT)-1) + { + if (!DosBackTracking) DosBackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, + (Expression->Length / sizeof(WCHAR)) * sizeof(USHORT), + 'nrSF'); + DosBackTracking[++DosStarFound] = ExpressionPosition++; + + /* Not the same char, start exploring */ + if (Expression->Buffer[ExpressionPosition] != Name->Buffer[NamePosition]) NamePosition++; - } } else { - /* XXX: Eat everything till the end */ - if (ExpressionPosition + 1 == Expression->Length / sizeof(WCHAR)) - { - NamePosition = Name->Length; - } - - /* Try to eat till the next matching char or . */ - MatchingChars = NamePosition; - while (MatchingChars < Name->Length / sizeof(WCHAR)) - { - if (ExpressionPosition + 1 < Expression->Length / sizeof(WCHAR) && - Name->Buffer[MatchingChars] == Expression->Buffer[ExpressionPosition + 1]) - { - NamePosition = MatchingChars; - break; - } - else if (Name->Buffer[MatchingChars] == L'.') - { - NamePosition = MatchingChars + 1; - break; - } - MatchingChars++; - } - } - ExpressionPosition++; + /* Else, if we are at last dot, eat it - otherwise, null match */ + if (Name->Buffer[NamePosition] == '.') + NamePosition++; + + ExpressionPosition++; + } } /* Check DOS_DOT */ else if (Expression->Buffer[ExpressionPosition] == DOS_DOT) { - /* First try to find whether we are beyond last dot (beyond name) */ - BeyondName = TRUE; - MatchingChars = NamePosition + 1; - while (MatchingChars < Name->Length / sizeof(WCHAR)) - { - if (Name->Buffer[MatchingChars] == L'.') - { - BeyondName = FALSE; - break; - } - MatchingChars++; - } - - /* If we are beyond name, we null match */ - if (BeyondName) - { - if (Name->Buffer[NamePosition] == L'.') - { - NamePosition++; - } - ExpressionPosition++; - continue; - } - /* If not, we only match a dot */ - else if (Name->Buffer[NamePosition] == L'.') + /* We only match dots */ + if (Name->Buffer[NamePosition] == L'.') { NamePosition++; - ExpressionPosition++; - continue; - } - /* Otherwise, fail */ - else - { - break; - } + } + /* Try to explore later on for null matching */ + else if ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) && + (Name->Buffer[NamePosition] == Expression->Buffer[ExpressionPosition + 1])) + { + NamePosition++; + } + ExpressionPosition++; } /* Check DOS_QM */ else if (Expression->Buffer[ExpressionPosition] == DOS_QM) { - /* Check whether we are upon a dot */ - MatchingChars = 0; - while (MatchingChars < NamePosition) - { - if (Name->Buffer[MatchingChars] == L'.') - { - break; - } - MatchingChars++; - } - - /* If not, we match a single char */ - if (MatchingChars == NamePosition && Name->Buffer[NamePosition] != L'.') + /* We match everything except dots */ + if (Name->Buffer[NamePosition] != L'.') { NamePosition++; - ExpressionPosition++; - } - else - { - /* If we are, we just go through QMs */ - while (ExpressionPosition < Expression->Length / sizeof(WCHAR) && - Expression->Buffer[ExpressionPosition] == DOS_QM) - { - ExpressionPosition++; - } - } + } + ExpressionPosition++; } /* If nothing match, try to backtrack */ else if (StarFound >= 0) { ExpressionPosition = BackTracking[StarFound--]; + } + else if (DosStarFound >= 0) + { + ExpressionPosition = DosBackTracking[DosStarFound--]; } /* Otherwise, fail */ else @@ -310,6 +265,10 @@ if (BackTracking) { ExFreePoolWithTag(BackTracking, 'nrSF'); + } + if (DosBackTracking) + { + ExFreePoolWithTag(DosBackTracking, 'nrSF'); } return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));