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?…
==============================================================================
--- 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=…
==============================================================================
--- 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));