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));


Reply via email to