mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 13:38:19 +00:00
[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. svn path=/trunk/; revision=58847
This commit is contained in:
parent
a08eef8b31
commit
2840256492
2 changed files with 112 additions and 196 deletions
|
@ -160,10 +160,9 @@ NTAPI
|
|||
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,130 +221,84 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
|||
/* 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] == '.')
|
||||
/* Skip contigous stars */
|
||||
while (ExpressionPosition + 1 < Expression->Length && Expression->Buffer[ExpressionPosition + 1] == ANSI_DOS_STAR)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
ExpressionPosition++;
|
||||
}
|
||||
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;
|
||||
/* 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 (Name->Buffer[NamePosition] == '.')
|
||||
{
|
||||
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++;
|
||||
}
|
||||
ExpressionPosition++;
|
||||
continue;
|
||||
}
|
||||
/* If not, we only match a dot */
|
||||
else if (Name->Buffer[NamePosition] == '.')
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
continue;
|
||||
}
|
||||
/* Otherwise, fail */
|
||||
else
|
||||
{
|
||||
break;
|
||||
/* 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)
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
|
@ -379,6 +332,10 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
|||
{
|
||||
ExFreePoolWithTag(BackTracking, 'nrSF');
|
||||
}
|
||||
if (DosBackTracking)
|
||||
{
|
||||
ExFreePoolWithTag(DosBackTracking, 'nrSF');
|
||||
}
|
||||
|
||||
return (ExpressionPosition == Expression->Length && NamePosition == Name->Length);
|
||||
}
|
||||
|
|
|
@ -23,12 +23,11 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
|||
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,130 +152,86 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
|||
/* 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
|
||||
*/
|
||||
if (Name->Buffer[NamePosition] == L'.')
|
||||
/* Skip contigous stars */
|
||||
while ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) &&
|
||||
(Expression->Buffer[ExpressionPosition + 1] == DOS_STAR))
|
||||
{
|
||||
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))
|
||||
{
|
||||
NamePosition++;
|
||||
}
|
||||
ExpressionPosition++;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
/* 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;
|
||||
/* Look for last dot */
|
||||
MatchingChars = 0;
|
||||
LastDot = (USHORT)-1;
|
||||
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
||||
{
|
||||
if (Name->Buffer[MatchingChars] == L'.')
|
||||
{
|
||||
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 (Name->Buffer[NamePosition] == L'.')
|
||||
{
|
||||
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++;
|
||||
}
|
||||
ExpressionPosition++;
|
||||
continue;
|
||||
}
|
||||
/* If not, we only match a dot */
|
||||
else if (Name->Buffer[NamePosition] == L'.')
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
continue;
|
||||
}
|
||||
/* Otherwise, fail */
|
||||
else
|
||||
{
|
||||
break;
|
||||
/* 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)
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
|
@ -311,6 +266,10 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
|||
{
|
||||
ExFreePoolWithTag(BackTracking, 'nrSF');
|
||||
}
|
||||
if (DosBackTracking)
|
||||
{
|
||||
ExFreePoolWithTag(DosBackTracking, 'nrSF');
|
||||
}
|
||||
|
||||
return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue