Author: tfaber
Date: Sun Oct 30 18:11:13 2016
New Revision: 73081

URL: http://svn.reactos.org/svn/reactos?rev=73081&view=rev
Log:
[0.4.3]
- Revert r72839 & r72835 to avoid the FsRtlIsNameInExpressionPrivate crash from 
CORE-12121

Modified:
    branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/dbcsname.c
    branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/name.c

Modified: branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/dbcsname.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/dbcsname.c?rev=73081&r1=73080&r2=73081&view=diff
==============================================================================
--- branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/dbcsname.c [iso-8859-1] 
(original)
+++ branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/dbcsname.c [iso-8859-1] 
Sun Oct 30 18:11:13 2016
@@ -160,14 +160,9 @@
 FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
                         IN PANSI_STRING Name)
 {
-    USHORT Offset, Position, BackTrackingPosition, OldBackTrackingPosition;
-    USHORT BackTrackingBuffer[16], OldBackTrackingBuffer[16] = {0};
-    PUSHORT BackTrackingSwap, BackTracking = BackTrackingBuffer, 
OldBackTracking = OldBackTrackingBuffer;
-    USHORT ExpressionPosition, NamePosition = 0, MatchingChars = 1;
-    USHORT NameChar = 0, ExpressionChar;
-    BOOLEAN EndOfName = FALSE;
-    BOOLEAN Result;
-    BOOLEAN DontSkipDot;
+    SHORT StarFound = -1, DosStarFound = -1;
+    PUSHORT BackTracking = NULL, DosBackTracking = NULL;
+    USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot;
     PAGED_CODE();
 
     ASSERT(Name->Length);
@@ -237,180 +232,170 @@
         }
     }
 
-    /* Name parsing loop */
-    for (; !EndOfName; MatchingChars = BackTrackingPosition)
-    {
-        /* Reset positions */
-        OldBackTrackingPosition = BackTrackingPosition = 0;
-
-        if (NamePosition >= Name->Length)
-        {
-            EndOfName = TRUE;
-            if (OldBackTracking[MatchingChars - 1] == Expression->Length * 2)
+    while (NamePosition < Name->Length && ExpressionPosition < 
Expression->Length)
+    {
+        /* Basic check to test if chars are equal */
+        if ((Expression->Buffer[ExpressionPosition] == 
Name->Buffer[NamePosition]))
+        {
+            NamePosition++;
+            ExpressionPosition++;
+        }
+        /* Check cases that eat one char */
+        else if (Expression->Buffer[ExpressionPosition] == '?')
+        {
+            NamePosition++;
+            ExpressionPosition++;
+        }
+        /* Test star */
+        else if (Expression->Buffer[ExpressionPosition] == '*')
+        {
+            /* Skip contigous stars */
+            while (ExpressionPosition + 1 < Expression->Length && 
Expression->Buffer[ExpressionPosition + 1] == '*')
+            {
+                ExpressionPosition++;
+            }
+
+            /* Save star position */
+            if (!BackTracking)
+            {
+                BackTracking = ExAllocatePoolWithTag(PagedPool | 
POOL_RAISE_IF_ALLOCATION_FAILURE,
+                                                     Expression->Length * 
sizeof(USHORT), 'nrSF');
+            }
+            BackTracking[++StarFound] = ExpressionPosition++;
+
+            /* If star is at the end, then eat all rest and leave */
+            if (ExpressionPosition == Expression->Length)
+            {
+                NamePosition = Name->Length;
                 break;
-        }
+            }
+            /* Allow null matching */
+            else if (Expression->Buffer[ExpressionPosition] != '?' &&
+                     Expression->Buffer[ExpressionPosition] != 
Name->Buffer[NamePosition])
+            {
+                NamePosition++;
+            }
+        }
+        /* Check DOS_STAR */
+        else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
+        {
+            /* 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] == '.')
+                {
+                    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)
+            {
+                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++;
+            }
+        }
+        /* Check DOS_DOT */
+        else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT)
+        {
+            /* We only match dots */
+            if (Name->Buffer[NamePosition] == '.')
+            {
+                NamePosition++;
+            }
+            /* 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)
+        {
+            /* We match everything except dots */
+            if (Name->Buffer[NamePosition] != '.')
+            {
+                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
         {
-            /* If lead byte present */
-            if (FsRtlIsLeadDbcsCharacter(Name->Buffer[NamePosition]))
-            {
-                NameChar = Name->Buffer[NamePosition] +
-                           (0x100 * Name->Buffer[NamePosition + 1]);
-                NamePosition += sizeof(USHORT);
-            }
-            else
-            {
-                NameChar = Name->Buffer[NamePosition];
-                NamePosition += sizeof(UCHAR);
-            }
-        }
-
-        while (MatchingChars > OldBackTrackingPosition)
-        {
-            ExpressionPosition = (OldBackTracking[OldBackTrackingPosition++] + 
1) / 2;
-
-            /* Expression parsing loop */
-            for (Offset = 0; ExpressionPosition < Expression->Length; )
-            {
-                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 + 
1) * sizeof(USHORT) * 2,
-                                                         '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 + 1) * sizeof(USHORT) * 2,
-                                                            'nrSF');
-                    /* Copy old buffer content */
-                    RtlCopyMemory(OldBackTracking,
-                                  OldBackTrackingBuffer,
-                                  RTL_NUMBER_OF(OldBackTrackingBuffer) * 
sizeof(USHORT));
-                }
-
-                /* If lead byte present */
-                if 
(FsRtlIsLeadDbcsCharacter(Expression->Buffer[ExpressionPosition]))
-                {
-                    ExpressionChar = Expression->Buffer[ExpressionPosition] +
-                                     (0x100 * 
Expression->Buffer[ExpressionPosition + 1]);
-                    Offset = sizeof(USHORT);
-                }
-                else
-                {
-                    ExpressionChar = Expression->Buffer[ExpressionPosition];
-                    Offset = sizeof(UCHAR);
-                }
-
-                /* Basic check to test if chars are equal */
-                if (ExpressionChar == NameChar && !EndOfName)
-                {
-                    BackTracking[BackTrackingPosition++] = (ExpressionPosition 
+ Offset) * 2;
-                }
-                /* Check cases that eat one char */
-                else if (ExpressionChar == '?' && !EndOfName)
-                {
-                    BackTracking[BackTrackingPosition++] = (ExpressionPosition 
+ Offset) * 2;
-                }
-                /* Test star */
-                else if (ExpressionChar == '*')
-                {
-                    BackTracking[BackTrackingPosition++] = ExpressionPosition 
* 2;
-                    BackTracking[BackTrackingPosition++] = (ExpressionPosition 
* 2) + 1;
-                    continue;
-                }
-                /* Check DOS_STAR */
-                else if (ExpressionChar == ANSI_DOS_STAR)
-                {
-                    /* Look for last dot */
-                    DontSkipDot = TRUE;
-                    if (!EndOfName && NameChar == '.')
-                    {
-                        for (Position = NamePosition; Position < Name->Length; 
)
-                        {
-                            /* If lead byte not present */
-                            if 
(!FsRtlIsLeadDbcsCharacter(Name->Buffer[Position]))
-                            {
-                                if (Name->Buffer[Position] == '.')
-                                {
-                                    DontSkipDot = FALSE;
-                                    break;
-                                }
-
-                                Position += sizeof(UCHAR);
-                            }
-                            else
-                            {
-                                Position += sizeof(USHORT);
-                            }
-                        }
-                    }
-
-                    if (EndOfName || NameChar != '.' || !DontSkipDot)
-                        BackTracking[BackTrackingPosition++] = 
ExpressionPosition * 2;
-
-                    BackTracking[BackTrackingPosition++] = (ExpressionPosition 
* 2) + 1;
-                    continue;
-                }
-                /* Check DOS_DOT */
-                else if (ExpressionChar == DOS_DOT)
-                {
-                    if (EndOfName) continue;
-
-                    if (NameChar == '.')
-                        BackTracking[BackTrackingPosition++] = 
(ExpressionPosition + Offset) * 2;
-                }
-                /* Check DOS_QM */
-                else if (ExpressionChar == ANSI_DOS_QM)
-                {
-                    if (EndOfName || NameChar == '.') continue;
-
-                    BackTracking[BackTrackingPosition++] = (ExpressionPosition 
+ Offset) * 2;
-                }
-
-                /* Leave from loop */
+            break;
+        }
+
+        /* Under certain circumstances, expression is over, but name isn't
+         * and we can backtrack, then, backtrack */
+        if (ExpressionPosition == Expression->Length &&
+            NamePosition != Name->Length && StarFound >= 0)
+        {
+            ExpressionPosition = BackTracking[StarFound--];
+        }
+    }
+    /* If we have nullable matching wc at the end of the string, eat them */
+    if (ExpressionPosition != Expression->Length && NamePosition == 
Name->Length)
+    {
+        while (ExpressionPosition < Expression->Length)
+        {
+            if (Expression->Buffer[ExpressionPosition] != ANSI_DOS_DOT &&
+                Expression->Buffer[ExpressionPosition] != '*' &&
+                Expression->Buffer[ExpressionPosition] != ANSI_DOS_STAR)
+            {
                 break;
             }
-
-            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)
+            ExpressionPosition++;
+        }
+    }
+
+    if (BackTracking)
+    {
         ExFreePoolWithTag(BackTracking, 'nrSF');
-    if (OldBackTracking != BackTrackingBuffer && OldBackTracking != 
OldBackTrackingBuffer)
-        ExFreePoolWithTag(OldBackTracking, 'nrSF');
-
-    return Result;
+    }
+    if (DosBackTracking)
+    {
+        ExFreePoolWithTag(DosBackTracking, 'nrSF');
+    }
+
+    return (ExpressionPosition == Expression->Length && NamePosition == 
Name->Length);
 }
 
 /*++

Modified: branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/name.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/name.c?rev=73081&r1=73080&r2=73081&view=diff
==============================================================================
--- branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/name.c     [iso-8859-1] 
(original)
+++ branches/ros-branch-0_4_3/reactos/ntoskrnl/fsrtl/name.c     [iso-8859-1] 
Sun Oct 30 18:11:13 2016
@@ -23,14 +23,13 @@
                                IN BOOLEAN IgnoreCase,
                                IN PWCHAR UpcaseTable OPTIONAL)
 {
-    USHORT Offset, Position, BackTrackingPosition, OldBackTrackingPosition;
-    USHORT BackTrackingBuffer[16], OldBackTrackingBuffer[16] = {0};
-    PUSHORT BackTrackingSwap, BackTracking = BackTrackingBuffer, 
OldBackTracking = OldBackTrackingBuffer;
+    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);
     UNICODE_STRING IntExpression;
-    USHORT ExpressionPosition, NamePosition = 0, MatchingChars = 1;
-    BOOLEAN EndOfName = FALSE;
-    BOOLEAN Result;
-    BOOLEAN DontSkipDot;
+    USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot;
     WCHAR CompareChar;
     PAGED_CODE();
 
@@ -38,7 +37,7 @@
     if (!Name->Length || !Expression->Length)
     {
         /* Return TRUE if both strings are empty, otherwise FALSE */
-        if (!Name->Length && !Expression->Length)
+        if (Name->Length == 0 && Expression->Length == 0)
             return TRUE;
         else
             return FALSE;
@@ -104,144 +103,193 @@
         }
     }
 
-    /* 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)
+    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);
                 break;
-        }
-
-        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)
+            }
+
+            /* 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'.')
                 {
-                    BackTracking[BackTrackingPosition++] = Expression->Length 
* 2;
-                    break;
+                    LastDot = MatchingChars;
+                    if (LastDot > NamePosition)
+                        break;
                 }
 
-                /* If buffer too small */
-                if (BackTrackingPosition > RTL_NUMBER_OF(BackTrackingBuffer) - 
1)
+                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)
                 {
-                    /* 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),
+                    ASSERT(DosBackTracking == DosBackTrackingBuffer);
+
+                    DosBackTrackingSize = Expression->Length / sizeof(WCHAR);
+                    DosBackTracking = ExAllocatePoolWithTag(PagedPool | 
POOL_RAISE_IF_ALLOCATION_FAILURE,
+                                                            
DosBackTrackingSize * sizeof(USHORT),
                                                             'nrSF');
-                    /* Copy old buffer content */
-                    RtlCopyMemory(OldBackTracking,
-                                  OldBackTrackingBuffer,
-                                  RTL_NUMBER_OF(OldBackTrackingBuffer) * 
sizeof(USHORT));
+                    RtlCopyMemory(DosBackTracking, DosBackTrackingBuffer, 
sizeof(DosBackTrackingBuffer));
                 }
-
-                /* 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 */
+                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)
+            {
                 break;
             }
-
-            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)
+            ExpressionPosition++;
+        }
+    }
+
+    if (BackTracking != BackTrackingBuffer)
+    {
         ExFreePoolWithTag(BackTracking, 'nrSF');
-    if (OldBackTracking != BackTrackingBuffer && OldBackTracking != 
OldBackTrackingBuffer)
-        ExFreePoolWithTag(OldBackTracking, 'nrSF');
-
-    return Result;
+    }
+    if (DosBackTracking != DosBackTrackingBuffer)
+    {
+        ExFreePoolWithTag(DosBackTracking, 'nrSF');
+    }
+
+    return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && 
NamePosition == Name->Length / sizeof(WCHAR));
 }
 
 /* PUBLIC FUNCTIONS **********************************************************/


Reply via email to