Don't forget to apply the changes (not reviewed, sorry, no time) to FsRtlIsDbcsInExpression.
Le 28/09/2016 à 01:00, dchapyshev@svn.reactos.org a écrit :
Author: dchapyshev Date: Tue Sep 27 23:00:20 2016 New Revision: 72835
URL: http://svn.reactos.org/svn/reactos?rev=72835&view=rev Log: [NTOS:FSRTL] Rework FsRtlIsNameInExpressionPrivate for correct parsing some expressions
- Fixes 1 test for kmtest:FsRtlExpression and 15 tests for kernel32:file
Modified: trunk/reactos/ntoskrnl/fsrtl/name.c
Modified: trunk/reactos/ntoskrnl/fsrtl/name.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/name.c?rev=7... ============================================================================== --- trunk/reactos/ntoskrnl/fsrtl/name.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/fsrtl/name.c [iso-8859-1] Tue Sep 27 23:00:20 2016 @@ -23,13 +23,14 @@ IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL) {
- SHORT StarFound = -1, DosStarFound = -1;
- USHORT BackTrackingBuffer[5], DosBackTrackingBuffer[5];
- PUSHORT BackTracking = BackTrackingBuffer, DosBackTracking = DosBackTrackingBuffer;
- SHORT BackTrackingSize = RTL_NUMBER_OF(BackTrackingBuffer);
- SHORT DosBackTrackingSize = RTL_NUMBER_OF(DosBackTrackingBuffer);
- USHORT Offset, Position, BackTrackingPosition, OldBackTrackingPosition;
- USHORT BackTrackingBuffer[16], OldBackTrackingBuffer[16] = {0};
- PUSHORT BackTrackingSwap, BackTracking = BackTrackingBuffer, OldBackTracking = OldBackTrackingBuffer; UNICODE_STRING IntExpression;
- USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot;
- USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars = 1;
- BOOLEAN EndOfName = FALSE;
- BOOLEAN Result = FALSE;
- BOOLEAN DontSkipDot; WCHAR CompareChar; PAGED_CODE();
@@ -37,7 +38,7 @@ if (!Name->Length || !Expression->Length) { /* Return TRUE if both strings are empty, otherwise FALSE */
if (Name->Length == 0 && Expression->Length == 0)
if (!Name->Length && !Expression->Length) return TRUE; else return FALSE;@@ -103,193 +104,144 @@ } }
- while ((NamePosition < Name->Length / sizeof(WCHAR)) &&
(ExpressionPosition < Expression->Length / sizeof(WCHAR)))- {
/* Basic check to test if chars are equal */CompareChar = IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :Name->Buffer[NamePosition];if (Expression->Buffer[ExpressionPosition] == CompareChar){NamePosition++;ExpressionPosition++;}/* Check cases that eat one char */else if (Expression->Buffer[ExpressionPosition] == L'?'){NamePosition++;ExpressionPosition++;}/* Test star */else if (Expression->Buffer[ExpressionPosition] == L'*'){/* Skip contigous stars */while ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) &&(Expression->Buffer[ExpressionPosition + 1] == L'*')){ExpressionPosition++;}/* Save star position */StarFound++;if (StarFound >= BackTrackingSize){ASSERT(BackTracking == BackTrackingBuffer);BackTrackingSize = Expression->Length / sizeof(WCHAR);BackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,BackTrackingSize * sizeof(USHORT),'nrSF');RtlCopyMemory(BackTracking, BackTrackingBuffer, sizeof(BackTrackingBuffer));}BackTracking[StarFound] = ExpressionPosition++;/* If star is at the end, then eat all rest and leave */if (ExpressionPosition == Expression->Length / sizeof(WCHAR)){NamePosition = Name->Length / sizeof(WCHAR);
- /* Name parsing loop */
- for (; !EndOfName; MatchingChars = BackTrackingPosition, NamePosition++)
- {
/* Reset positions */OldBackTrackingPosition = BackTrackingPosition = 0;if (NamePosition >= Name->Length / sizeof(WCHAR)){EndOfName = TRUE;if (OldBackTracking[MatchingChars - 1] == Expression->Length * 2) break;
}/* Allow null matching */if (Expression->Buffer[ExpressionPosition] != L'?' &&Expression->Buffer[ExpressionPosition] != Name->Buffer[NamePosition]){NamePosition++;}}/* Check DOS_STAR */else if (Expression->Buffer[ExpressionPosition] == DOS_STAR){/* 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 (MatchingChars != Name->Length || LastDot == (USHORT)-1){DosStarFound++;if (DosStarFound >= DosBackTrackingSize){ASSERT(DosBackTracking == DosBackTrackingBuffer);DosBackTrackingSize = Expression->Length / sizeof(WCHAR);DosBackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,DosBackTrackingSize * sizeof(USHORT),
}while (MatchingChars > OldBackTrackingPosition){ExpressionPosition = (OldBackTracking[OldBackTrackingPosition++] + 1) / 2;/* Expression parsing loop */for (Offset = 0; ExpressionPosition < Expression->Length; Offset = sizeof(WCHAR)){ExpressionPosition += Offset;if (ExpressionPosition == Expression->Length){BackTracking[BackTrackingPosition++] = Expression->Length * 2;break;}/* If buffer too small */if (BackTrackingPosition > RTL_NUMBER_OF(BackTrackingBuffer) - 1){/* Allocate memory for BackTracking */BackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,(Expression->Length + sizeof(WCHAR)) * sizeof(USHORT),'nrSF');/* Copy old buffer content */RtlCopyMemory(BackTracking,BackTrackingBuffer,RTL_NUMBER_OF(BackTrackingBuffer) * sizeof(USHORT));/* Allocate memory for OldBackTracking */OldBackTracking = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,(Expression->Length + sizeof(WCHAR)) * sizeof(USHORT), 'nrSF');
RtlCopyMemory(DosBackTracking, DosBackTrackingBuffer, sizeof(DosBackTrackingBuffer));}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++;}}/* Check DOS_DOT */else if (Expression->Buffer[ExpressionPosition] == DOS_DOT){/* We only match dots */if (Name->Buffer[NamePosition] == L'.'){NamePosition++;}/* 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){/* We match everything except dots */if (Name->Buffer[NamePosition] != L'.'){NamePosition++;}ExpressionPosition++;}/* If nothing match, try to backtrack */else if (StarFound >= 0){ExpressionPosition = BackTracking[StarFound--];}else if (DosStarFound >= 0){ExpressionPosition = DosBackTracking[DosStarFound--];}/* Otherwise, fail */else{break;}/* Under certain circumstances, expression is over, but name isn't* and we can backtrack, then, backtrack */if (ExpressionPosition == Expression->Length / sizeof(WCHAR) &&NamePosition != Name->Length / sizeof(WCHAR) &&StarFound >= 0){ExpressionPosition = BackTracking[StarFound--];}- }
- /* If we have nullable matching wc at the end of the string, eat them */
- if (ExpressionPosition != Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR))
- {
while (ExpressionPosition < Expression->Length / sizeof(WCHAR)){if (Expression->Buffer[ExpressionPosition] != DOS_DOT &&Expression->Buffer[ExpressionPosition] != L'*' &&Expression->Buffer[ExpressionPosition] != DOS_STAR){
/* Copy old buffer content */RtlCopyMemory(OldBackTracking,OldBackTrackingBuffer,RTL_NUMBER_OF(OldBackTrackingBuffer) * sizeof(USHORT));}/* Basic check to test if chars are equal */CompareChar = IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] :Name->Buffer[NamePosition];if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == CompareChar && !EndOfName){BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;}/* Check cases that eat one char */else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == L'?' && !EndOfName){BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;}/* Test star */else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == L'*'){BackTracking[BackTrackingPosition++] = ExpressionPosition * 2;BackTracking[BackTrackingPosition++] = (ExpressionPosition * 2) + 3;continue;}/* Check DOS_STAR */else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_STAR){/* Look for last dot */DontSkipDot = TRUE;if (!EndOfName && Name->Buffer[NamePosition] == '.'){for (Position = NamePosition - 1; Position < Name->Length; Position++){if (Name->Buffer[Position] == L'.'){DontSkipDot = FALSE;break;}}}if (EndOfName || Name->Buffer[NamePosition] != L'.' || !DontSkipDot)BackTracking[BackTrackingPosition++] = ExpressionPosition * 2;BackTracking[BackTrackingPosition++] = (ExpressionPosition * 2) + 3;continue;}/* Check DOS_DOT */else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_DOT){if (EndOfName) continue;if (Name->Buffer[NamePosition] == L'.')BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;}/* Check DOS_QM */else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_QM){if (EndOfName || Name->Buffer[NamePosition] == L'.') continue;BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2;}/* Leave from loop */ break; }
ExpressionPosition++;}- }
- if (BackTracking != BackTrackingBuffer)
- {
for (Position = 0; MatchingChars > OldBackTrackingPosition && Position < BackTrackingPosition; Position++){while (MatchingChars > OldBackTrackingPosition &&BackTracking[Position] > OldBackTracking[OldBackTrackingPosition]){++OldBackTrackingPosition;}}}/* Swap pointers */BackTrackingSwap = BackTracking;BackTracking = OldBackTracking;OldBackTracking = BackTrackingSwap;- }
- /* Store result value */
- Result = (OldBackTracking[MatchingChars - 1] == (Expression->Length * 2));
- /* Frees the memory if necessary */
- if (BackTracking != BackTrackingBuffer && BackTracking != OldBackTrackingBuffer) ExFreePoolWithTag(BackTracking, 'nrSF');
- }
- if (DosBackTracking != DosBackTrackingBuffer)
- {
ExFreePoolWithTag(DosBackTracking, 'nrSF');- }
- return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
- if (OldBackTracking != BackTrackingBuffer && OldBackTracking != OldBackTrackingBuffer)
ExFreePoolWithTag(OldBackTracking, 'nrSF');- return Result;
}
/* PUBLIC FUNCTIONS **********************************************************/