Don't forget to apply the changes (not reviewed, sorry, no time) to
FsRtlIsDbcsInExpression.
Le 28/09/2016 à 01:00, dchapyshev(a)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=…
 ==============================================================================
 --- 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 **********************************************************/
  
--
Pierre Schweitzer <pierre at reactos.org>
System & Network Administrator
Senior Kernel Developer
ReactOS Deutschland e.V.