mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:42:58 +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,
|
FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||||
IN PANSI_STRING Name)
|
IN PANSI_STRING Name)
|
||||||
{
|
{
|
||||||
SHORT StarFound = -1;
|
SHORT StarFound = -1, DosStarFound = -1;
|
||||||
PUSHORT BackTracking = NULL;
|
PUSHORT BackTracking = NULL, DosBackTracking = NULL;
|
||||||
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars;
|
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot;
|
||||||
BOOLEAN BeyondName;
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT(Name->Length);
|
ASSERT(Name->Length);
|
||||||
|
@ -222,130 +221,84 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||||
/* Check DOS_STAR */
|
/* Check DOS_STAR */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
|
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
|
||||||
{
|
{
|
||||||
/* We can only consume dot if that's not the last one
|
/* Skip contigous stars */
|
||||||
* Otherwise, we null match
|
while (ExpressionPosition + 1 < Expression->Length && Expression->Buffer[ExpressionPosition + 1] == ANSI_DOS_STAR)
|
||||||
*/
|
|
||||||
if (Name->Buffer[NamePosition] == '.')
|
|
||||||
{
|
{
|
||||||
MatchingChars = NamePosition + 1;
|
ExpressionPosition++;
|
||||||
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 . */
|
/* Look for last dot */
|
||||||
MatchingChars = NamePosition;
|
MatchingChars = 0;
|
||||||
while (MatchingChars < Name->Length)
|
LastDot = (USHORT)-1;
|
||||||
{
|
|
||||||
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;
|
|
||||||
while (MatchingChars < Name->Length)
|
while (MatchingChars < Name->Length)
|
||||||
{
|
{
|
||||||
if (Name->Buffer[MatchingChars] == '.')
|
if (Name->Buffer[MatchingChars] == '.')
|
||||||
{
|
{
|
||||||
BeyondName = FALSE;
|
LastDot = MatchingChars;
|
||||||
break;
|
if (LastDot > NamePosition)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchingChars++;
|
MatchingChars++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are beyond name, we null match */
|
/* If we don't have dots or we didn't find last yet
|
||||||
if (BeyondName)
|
* 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++;
|
NamePosition++;
|
||||||
}
|
|
||||||
ExpressionPosition++;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
/* If not, we only match a dot */
|
|
||||||
else if (Name->Buffer[NamePosition] == '.')
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
ExpressionPosition++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Otherwise, fail */
|
|
||||||
else
|
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 */
|
/* Check DOS_QM */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM)
|
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM)
|
||||||
{
|
{
|
||||||
/* Check whether we are upon a dot */
|
/* We match everything except dots */
|
||||||
MatchingChars = 0;
|
if (Name->Buffer[NamePosition] != '.')
|
||||||
while (MatchingChars < NamePosition)
|
|
||||||
{
|
|
||||||
if (Name->Buffer[MatchingChars] == '.')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MatchingChars++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not, we match a single char */
|
|
||||||
if (MatchingChars == NamePosition && Name->Buffer[NamePosition] != '.')
|
|
||||||
{
|
{
|
||||||
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 */
|
/* If nothing match, try to backtrack */
|
||||||
else if (StarFound >= 0)
|
else if (StarFound >= 0)
|
||||||
{
|
{
|
||||||
ExpressionPosition = BackTracking[StarFound--];
|
ExpressionPosition = BackTracking[StarFound--];
|
||||||
}
|
}
|
||||||
|
else if (DosStarFound >= 0)
|
||||||
|
{
|
||||||
|
ExpressionPosition = DosBackTracking[DosStarFound--];
|
||||||
|
}
|
||||||
/* Otherwise, fail */
|
/* Otherwise, fail */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -379,6 +332,10 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(BackTracking, 'nrSF');
|
ExFreePoolWithTag(BackTracking, 'nrSF');
|
||||||
}
|
}
|
||||||
|
if (DosBackTracking)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(DosBackTracking, 'nrSF');
|
||||||
|
}
|
||||||
|
|
||||||
return (ExpressionPosition == Expression->Length && NamePosition == Name->Length);
|
return (ExpressionPosition == Expression->Length && NamePosition == Name->Length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,11 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
IN BOOLEAN IgnoreCase,
|
IN BOOLEAN IgnoreCase,
|
||||||
IN PWCHAR UpcaseTable OPTIONAL)
|
IN PWCHAR UpcaseTable OPTIONAL)
|
||||||
{
|
{
|
||||||
SHORT StarFound = -1;
|
SHORT StarFound = -1, DosStarFound = -1;
|
||||||
PUSHORT BackTracking = NULL;
|
PUSHORT BackTracking = NULL, DosBackTracking = NULL;
|
||||||
UNICODE_STRING IntExpression;
|
UNICODE_STRING IntExpression;
|
||||||
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars;
|
USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, LastDot;
|
||||||
WCHAR CompareChar;
|
WCHAR CompareChar;
|
||||||
BOOLEAN BeyondName;
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check if we were given strings at all */
|
/* Check if we were given strings at all */
|
||||||
|
@ -153,130 +152,86 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
/* Check DOS_STAR */
|
/* Check DOS_STAR */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
|
else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
|
||||||
{
|
{
|
||||||
/* We can only consume dot if that's not the last one
|
/* Skip contigous stars */
|
||||||
* Otherwise, we null match
|
while ((ExpressionPosition + 1 < (USHORT)(Expression->Length / sizeof(WCHAR))) &&
|
||||||
*/
|
(Expression->Buffer[ExpressionPosition + 1] == DOS_STAR))
|
||||||
if (Name->Buffer[NamePosition] == L'.')
|
|
||||||
{
|
{
|
||||||
MatchingChars = NamePosition + 1;
|
ExpressionPosition++;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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 . */
|
/* Look for last dot */
|
||||||
MatchingChars = NamePosition;
|
MatchingChars = 0;
|
||||||
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
LastDot = (USHORT)-1;
|
||||||
{
|
|
||||||
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;
|
|
||||||
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
while (MatchingChars < Name->Length / sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
if (Name->Buffer[MatchingChars] == L'.')
|
if (Name->Buffer[MatchingChars] == L'.')
|
||||||
{
|
{
|
||||||
BeyondName = FALSE;
|
LastDot = MatchingChars;
|
||||||
break;
|
if (LastDot > NamePosition)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchingChars++;
|
MatchingChars++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are beyond name, we null match */
|
/* If we don't have dots or we didn't find last yet
|
||||||
if (BeyondName)
|
* 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++;
|
NamePosition++;
|
||||||
}
|
|
||||||
ExpressionPosition++;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
/* If not, we only match a dot */
|
|
||||||
else if (Name->Buffer[NamePosition] == L'.')
|
|
||||||
{
|
|
||||||
NamePosition++;
|
|
||||||
ExpressionPosition++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Otherwise, fail */
|
|
||||||
else
|
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 */
|
/* Check DOS_QM */
|
||||||
else if (Expression->Buffer[ExpressionPosition] == DOS_QM)
|
else if (Expression->Buffer[ExpressionPosition] == DOS_QM)
|
||||||
{
|
{
|
||||||
/* Check whether we are upon a dot */
|
/* We match everything except dots */
|
||||||
MatchingChars = 0;
|
if (Name->Buffer[NamePosition] != L'.')
|
||||||
while (MatchingChars < NamePosition)
|
|
||||||
{
|
|
||||||
if (Name->Buffer[MatchingChars] == L'.')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MatchingChars++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not, we match a single char */
|
|
||||||
if (MatchingChars == NamePosition && Name->Buffer[NamePosition] != L'.')
|
|
||||||
{
|
{
|
||||||
NamePosition++;
|
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 */
|
/* If nothing match, try to backtrack */
|
||||||
else if (StarFound >= 0)
|
else if (StarFound >= 0)
|
||||||
{
|
{
|
||||||
ExpressionPosition = BackTracking[StarFound--];
|
ExpressionPosition = BackTracking[StarFound--];
|
||||||
}
|
}
|
||||||
|
else if (DosStarFound >= 0)
|
||||||
|
{
|
||||||
|
ExpressionPosition = DosBackTracking[DosStarFound--];
|
||||||
|
}
|
||||||
/* Otherwise, fail */
|
/* Otherwise, fail */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -311,6 +266,10 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(BackTracking, 'nrSF');
|
ExFreePoolWithTag(BackTracking, 'nrSF');
|
||||||
}
|
}
|
||||||
|
if (DosBackTracking)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(DosBackTracking, 'nrSF');
|
||||||
|
}
|
||||||
|
|
||||||
return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
|
return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue