mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[NTOSKRNL]
Merging some stuff from pierre-fsd/arty-newcc branches: - Implemented FsRtlDissectDbcs(), FsRtlIsDbcsInExpression(), FsRtlIsFatDbcsLegal(), FsRtlIsHpfsDbcsLegal() - Implemented FsRtlIsNameInExpressionPrivate() - Rewritten FsRtlIsNameInExpression() - Updated comments About FsRtlIsNameInExpressionPrivate(), it comes with a fix there isn't in branch, which avoids reading string more than its own length, and this helps getting rid of a workaround later in code. svn path=/trunk/; revision=48002
This commit is contained in:
parent
604a7a51ed
commit
17458060a5
|
@ -4,6 +4,7 @@
|
|||
* FILE: ntoskrnl/fsrtl/name.c
|
||||
* PURPOSE: Provides DBCS parsing and other support routines for FSDs
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Pierre Schweitzer (pierre.schweitzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
@ -45,19 +46,67 @@ FsRtlDissectDbcs(IN ANSI_STRING Name,
|
|||
OUT PANSI_STRING FirstPart,
|
||||
OUT PANSI_STRING RemainingPart)
|
||||
{
|
||||
KeBugCheck(FILE_SYSTEM);
|
||||
ULONG FirstPosition, i;
|
||||
ULONG SkipFirstSlash = 0;
|
||||
|
||||
/* Zero the strings before continuing */
|
||||
RtlZeroMemory(FirstPart, sizeof(ANSI_STRING));
|
||||
RtlZeroMemory(RemainingPart, sizeof(ANSI_STRING));
|
||||
|
||||
/* Just quit if the string is empty */
|
||||
if (!Name.Length) return;
|
||||
|
||||
/* Find first backslash */
|
||||
FirstPosition = Name.Length;
|
||||
for (i = 0; i < Name.Length; i++)
|
||||
{
|
||||
/* First make sure the character it's not the Lead DBCS */
|
||||
if (FsRtlIsLeadDbcsCharacter(Name.Buffer[i]))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
/* If we found one... */
|
||||
else if (Name.Buffer[i] == '\\')
|
||||
{
|
||||
/* If it begins string, just notice it and continue */
|
||||
if (i == 0)
|
||||
{
|
||||
SkipFirstSlash = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Else, save its position and break out of the loop */
|
||||
FirstPosition = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the first result string */
|
||||
FirstPart->Buffer = Name.Buffer + SkipFirstSlash;
|
||||
FirstPart->Length = (FirstPosition - SkipFirstSlash);
|
||||
FirstPart->MaximumLength = FirstPart->Length;
|
||||
|
||||
/* And second one, if necessary */
|
||||
if (FirstPosition < (Name.Length))
|
||||
{
|
||||
RemainingPart->Buffer = Name.Buffer + FirstPosition + 1;
|
||||
RemainingPart->Length = Name.Length - (FirstPosition + 1);
|
||||
RemainingPart->MaximumLength = RemainingPart->Length;
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name FsRtlDoesDbcsContainWildCards
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Returns TRUE if the given DbcsName contains wildcards such as *, ?,
|
||||
* ANSI_DOS_STAR, ANSI_DOS_DOT, and ANSI_DOS_QM
|
||||
*
|
||||
* @param Name
|
||||
* FILLME
|
||||
* The Name to check
|
||||
*
|
||||
* @return None
|
||||
* @return TRUE if there are wildcards, FALSE otherwise
|
||||
*
|
||||
* @remarks None
|
||||
*
|
||||
|
@ -89,17 +138,17 @@ FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name)
|
|||
|
||||
/*++
|
||||
* @name FsRtlIsDbcsInExpression
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Check if the Name string is in the Expression string.
|
||||
*
|
||||
* @param Expression
|
||||
* FILLME
|
||||
* The string in which we've to find Name. It can contains wildcards
|
||||
*
|
||||
* @param Name
|
||||
* FILLME
|
||||
* The string to find. It cannot contain wildcards.
|
||||
*
|
||||
* @return None
|
||||
* @return TRUE if Name is found in Expression, FALSE otherwise
|
||||
*
|
||||
* @remarks None
|
||||
*
|
||||
|
@ -109,27 +158,74 @@ NTAPI
|
|||
FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
|
||||
IN PANSI_STRING Name)
|
||||
{
|
||||
KeBugCheck(FILE_SYSTEM);
|
||||
ULONG ExpressionPosition, NamePosition, MatchingChars = 0;
|
||||
|
||||
ASSERT(!FsRtlDoesDbcsContainWildCards(Name));
|
||||
|
||||
/* One can't be null, both can be */
|
||||
if (!Expression->Length || !Name->Length)
|
||||
{
|
||||
return !(Expression->Length ^ Name->Length);
|
||||
}
|
||||
|
||||
for (ExpressionPosition = 0; ExpressionPosition < Expression->Length; ExpressionPosition++)
|
||||
{
|
||||
if ((Expression->Buffer[ExpressionPosition] == Name->Buffer[MatchingChars]) ||
|
||||
(Expression->Buffer[ExpressionPosition] == '?') ||
|
||||
(Expression->Buffer[ExpressionPosition] == ANSI_DOS_QM) ||
|
||||
(Expression->Buffer[ExpressionPosition] == ANSI_DOS_DOT &&
|
||||
(Name->Buffer[MatchingChars] == '.' || Name->Buffer[MatchingChars] == '0')))
|
||||
{
|
||||
MatchingChars++;
|
||||
}
|
||||
else if (Expression->Buffer[ExpressionPosition] == '*')
|
||||
{
|
||||
MatchingChars = Name->Length;
|
||||
}
|
||||
else if (Expression->Buffer[ExpressionPosition] == ANSI_DOS_STAR)
|
||||
{
|
||||
for (NamePosition = MatchingChars; NamePosition < Name->Length; NamePosition++)
|
||||
{
|
||||
if (Name->Buffer[NamePosition] == '.')
|
||||
{
|
||||
MatchingChars = NamePosition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MatchingChars = 0;
|
||||
}
|
||||
if (MatchingChars == Name->Length)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name FsRtlIsFatDbcsLegal
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Returns TRUE if the given DbcsName is a valid FAT filename (in 8.3)
|
||||
*
|
||||
* @param DbcsName
|
||||
* FILLME
|
||||
* The filename to check. It can also contains pathname.
|
||||
*
|
||||
* @param WildCardsPermissible
|
||||
* FILLME
|
||||
* If this is set to FALSE and if filename contains wildcard, the function
|
||||
* will fail
|
||||
*
|
||||
* @param PathNamePermissible
|
||||
* FILLME
|
||||
* If this is set to FALSE and if the filename comes with a pathname, the
|
||||
* function will fail
|
||||
*
|
||||
* @param LeadingBackslashPermissible
|
||||
* FILLME
|
||||
* If this is set to FALSE and if the filename starts with a backslash, the
|
||||
* function will fail
|
||||
*
|
||||
* @return TRUE if the DbcsName is legal, FALSE otherwise
|
||||
*
|
||||
|
@ -143,27 +239,130 @@ FsRtlIsFatDbcsLegal(IN ANSI_STRING DbcsName,
|
|||
IN BOOLEAN PathNamePermissible,
|
||||
IN BOOLEAN LeadingBackslashPermissible)
|
||||
{
|
||||
KeBugCheck(FILE_SYSTEM);
|
||||
return FALSE;
|
||||
ANSI_STRING FirstPart, RemainingPart, Name;
|
||||
BOOLEAN LastDot;
|
||||
ULONG i;
|
||||
|
||||
/* Just quit if the string is empty */
|
||||
if (!DbcsName.Length)
|
||||
return FALSE;
|
||||
|
||||
/* DbcsName wasn't supposed to be started with \ */
|
||||
if (!LeadingBackslashPermissible && DbcsName.Buffer[0] == '\\')
|
||||
return FALSE;
|
||||
/* DbcsName was allowed to be started with \, but now, remove it */
|
||||
else if (LeadingBackslashPermissible && DbcsName.Buffer[0] == '\\')
|
||||
{
|
||||
DbcsName.Buffer = DbcsName.Buffer + 1;
|
||||
DbcsName.Length = DbcsName.Length - 1;
|
||||
DbcsName.MaximumLength = DbcsName.MaximumLength - 1;
|
||||
}
|
||||
|
||||
/* Extract first part of the DbcsName to work on */
|
||||
FsRtlDissectDbcs(DbcsName, &FirstPart, &RemainingPart);
|
||||
while (FirstPart.Length > 0)
|
||||
{
|
||||
/* Reset dots count */
|
||||
LastDot = FALSE;
|
||||
|
||||
/* Accept special filename if wildcards are allowed */
|
||||
if (WildCardsPermissible && (FirstPart.Length == 1 || FirstPart.Length == 2) && FirstPart.Buffer[0] == '.')
|
||||
{
|
||||
if (FirstPart.Length == 2)
|
||||
{
|
||||
if (FirstPart.Buffer[1] == '.')
|
||||
{
|
||||
goto EndLoop;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto EndLoop;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filename must be 8.3 filename */
|
||||
if (FirstPart.Length < 3 || FirstPart.Length > 12)
|
||||
return FALSE;
|
||||
|
||||
/* Now, we will parse the filename to find everything bad in */
|
||||
for (i = 0; i < FirstPart.Length; i++)
|
||||
{
|
||||
/* First make sure the character it's not the Lead DBCS */
|
||||
if (FsRtlIsLeadDbcsCharacter(FirstPart.Buffer[i]))
|
||||
{
|
||||
if (i == (FirstPart.Length) - 1)
|
||||
return FALSE;
|
||||
i++;
|
||||
}
|
||||
/* Then check for bad characters */
|
||||
else if (!FsRtlIsAnsiCharacterLegalFat(FirstPart.Buffer[i], WildCardsPermissible))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (FirstPart.Buffer[i] == '.')
|
||||
{
|
||||
/* Filename can only contain one dot */
|
||||
if (LastDot)
|
||||
return FALSE;
|
||||
|
||||
LastDot = TRUE;
|
||||
|
||||
/* We mustn't have spaces before dot or at the end of the filename
|
||||
* and no dot at the beginning of the filename */
|
||||
if ((i == (FirstPart.Length) - 1) || i == 0)
|
||||
return FALSE;
|
||||
|
||||
if (i > 0)
|
||||
if (FirstPart.Buffer[i - 1] == ' ')
|
||||
return FALSE;
|
||||
|
||||
/* Filename must be 8.3 filename and not 3.8 filename */
|
||||
if ((FirstPart.Length - 1) - i > 3)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filename mustn't finish with a space */
|
||||
if (FirstPart.Buffer[FirstPart.Length - 1] == ' ')
|
||||
return FALSE;
|
||||
|
||||
EndLoop:
|
||||
/* Preparing next loop */
|
||||
Name.Buffer = RemainingPart.Buffer;
|
||||
Name.Length = RemainingPart.Length;
|
||||
Name.MaximumLength = RemainingPart.MaximumLength;
|
||||
|
||||
/* Call once again our dissect function */
|
||||
FsRtlDissectDbcs(Name, &FirstPart, &RemainingPart);
|
||||
|
||||
/* We found a pathname, it wasn't allowed */
|
||||
if (FirstPart.Length > 0 && !PathNamePermissible)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name FsRtlIsHpfsDbcsLegal
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Returns TRUE if the given DbcsName is a valid HPFS filename
|
||||
*
|
||||
* @param DbcsName
|
||||
* FILLME
|
||||
* The filename to check. It can also contains pathname.
|
||||
*
|
||||
* @param WildCardsPermissible
|
||||
* FILLME
|
||||
* If this is set to FALSE and if filename contains wildcard, the function
|
||||
* will fail
|
||||
*
|
||||
* @param PathNamePermissible
|
||||
* FILLME
|
||||
* If this is set to FALSE and if the filename comes with a pathname, the
|
||||
* function will fail
|
||||
*
|
||||
* @param LeadingBackslashPermissible
|
||||
* FILLME
|
||||
* If this is set to FALSE and if the filename starts with a backslash, the
|
||||
* function will fail
|
||||
*
|
||||
* @return TRUE if the DbcsName is legal, FALSE otherwise
|
||||
*
|
||||
|
@ -177,6 +376,82 @@ FsRtlIsHpfsDbcsLegal(IN ANSI_STRING DbcsName,
|
|||
IN BOOLEAN PathNamePermissible,
|
||||
IN BOOLEAN LeadingBackslashPermissible)
|
||||
{
|
||||
KeBugCheck(FILE_SYSTEM);
|
||||
return FALSE;
|
||||
ANSI_STRING FirstPart, RemainingPart, Name;
|
||||
ULONG i;
|
||||
|
||||
/* Just quit if the string is empty */
|
||||
if (!DbcsName.Length)
|
||||
return FALSE;
|
||||
|
||||
/* DbcsName wasn't supposed to be started with \ */
|
||||
if (!LeadingBackslashPermissible && DbcsName.Buffer[0] == '\\')
|
||||
return FALSE;
|
||||
/* DbcsName was allowed to be started with \, but now, remove it */
|
||||
else if (LeadingBackslashPermissible && DbcsName.Buffer[0] == '\\')
|
||||
{
|
||||
DbcsName.Buffer = DbcsName.Buffer + 1;
|
||||
DbcsName.Length = DbcsName.Length - 1;
|
||||
DbcsName.MaximumLength = DbcsName.MaximumLength - 1;
|
||||
}
|
||||
|
||||
/* Extract first part of the DbcsName to work on */
|
||||
FsRtlDissectDbcs(DbcsName, &FirstPart, &RemainingPart);
|
||||
while (FirstPart.Length > 0)
|
||||
{
|
||||
/* Accept special filename if wildcards are allowed */
|
||||
if (WildCardsPermissible && (FirstPart.Length == 1 || FirstPart.Length == 2) && FirstPart.Buffer[0] == '.')
|
||||
{
|
||||
if (FirstPart.Length == 2)
|
||||
{
|
||||
if (FirstPart.Buffer[1] == '.')
|
||||
{
|
||||
goto EndLoop;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto EndLoop;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filename must be 255 bytes maximum */
|
||||
if (FirstPart.Length > 255)
|
||||
return FALSE;
|
||||
|
||||
/* Now, we will parse the filename to find everything bad in */
|
||||
for (i = 0; i < FirstPart.Length; i++)
|
||||
{
|
||||
/* First make sure the character it's not the Lead DBCS */
|
||||
if (FsRtlIsLeadDbcsCharacter(FirstPart.Buffer[i]))
|
||||
{
|
||||
if (i == (FirstPart.Length) - 1)
|
||||
return FALSE;
|
||||
i++;
|
||||
}
|
||||
/* Then check for bad characters */
|
||||
else if (!!FsRtlIsAnsiCharacterLegalHpfs(FirstPart.Buffer[i], WildCardsPermissible))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filename mustn't finish with a space or a dot */
|
||||
if ((FirstPart.Buffer[FirstPart.Length - 1] == ' ') ||
|
||||
(FirstPart.Buffer[FirstPart.Length - 1] == '.'))
|
||||
return FALSE;
|
||||
|
||||
EndLoop:
|
||||
/* Preparing next loop */
|
||||
Name.Buffer = RemainingPart.Buffer;
|
||||
Name.Length = RemainingPart.Length;
|
||||
Name.MaximumLength = RemainingPart.MaximumLength;
|
||||
|
||||
/* Call once again our dissect function */
|
||||
FsRtlDissectDbcs(Name, &FirstPart, &RemainingPart);
|
||||
|
||||
/* We found a pathname, it wasn't allowed */
|
||||
if (FirstPart.Length > 0 && !PathNamePermissible)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* PURPOSE: Provides name parsing and other support routines for FSDs
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Filip Navara (navaraf@reactos.org)
|
||||
* Pierre Schweitzer (pierre.schweitzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
@ -13,27 +14,96 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
|
||||
IN PUNICODE_STRING Name,
|
||||
IN BOOLEAN IgnoreCase,
|
||||
IN PWCHAR UpcaseTable OPTIONAL)
|
||||
{
|
||||
ULONG i = 0, j, k = 0;
|
||||
|
||||
ASSERT(!FsRtlDoesNameContainWildCards(Name));
|
||||
|
||||
while (i < Name->Length / sizeof(WCHAR) && k < Expression->Length / sizeof(WCHAR))
|
||||
{
|
||||
if ((Expression->Buffer[k] == (IgnoreCase ? UpcaseTable[Name->Buffer[i]] : Name->Buffer[i])) ||
|
||||
(Expression->Buffer[k] == L'?') || (Expression->Buffer[k] == DOS_QM) ||
|
||||
(Expression->Buffer[k] == DOS_DOT && (Name->Buffer[i] == L'.' || Name->Buffer[i] == L'0')))
|
||||
{
|
||||
i++;
|
||||
k++;
|
||||
}
|
||||
else if (Expression->Buffer[k] == L'*')
|
||||
{
|
||||
if (k < Expression->Length / sizeof(WCHAR))
|
||||
{
|
||||
if (Expression->Buffer[k+1] != L'*' && Expression->Buffer[k+1] != L'?' &&
|
||||
Expression->Buffer[k+1] != DOS_DOT && Expression->Buffer[k+1] != DOS_QM &&
|
||||
Expression->Buffer[k+1] != DOS_STAR)
|
||||
{
|
||||
while ((IgnoreCase ? UpcaseTable[Name->Buffer[i]] : Name->Buffer[i]) != Expression->Buffer[k+1] &&
|
||||
i <= Name->Length / sizeof(WCHAR)) i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(Expression->Buffer[k+1] != DOS_DOT && (Name->Buffer[i] == L'.' || Name->Buffer[i] == L'0')))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = Name->Length / sizeof(WCHAR);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
else if (Expression->Buffer[k] == DOS_STAR)
|
||||
{
|
||||
j = i;
|
||||
while (j <= Name->Length / sizeof(WCHAR))
|
||||
{
|
||||
if (Name->Buffer[j] == L'.')
|
||||
{
|
||||
i = j;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (k == Expression->Length / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
/*++
|
||||
* @name FsRtlAreNamesEqual
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Compare two strings to check if they match
|
||||
*
|
||||
* @param Name1
|
||||
* FILLME
|
||||
* First unicode string to compare
|
||||
*
|
||||
* @param Name2
|
||||
* FILLME
|
||||
* Second unicode string to compare
|
||||
*
|
||||
* @param IgnoreCase
|
||||
* FILLME
|
||||
* If TRUE, Case will be ignored when comparing strings
|
||||
*
|
||||
* @param UpcaseTable
|
||||
* FILLME
|
||||
* Table for upcase letters. If NULL is given, system one will be used
|
||||
*
|
||||
* @return None
|
||||
* @return TRUE if the strings are equal
|
||||
*
|
||||
* @remarks From Bo Branten's ntifs.h v25.
|
||||
*
|
||||
|
@ -188,7 +258,7 @@ FsRtlDissectName(IN UNICODE_STRING Name,
|
|||
* @name FsRtlDoesNameContainWildCards
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Checks if the given string contains WildCards
|
||||
*
|
||||
* @param Name
|
||||
* Pointer to a UNICODE_STRING containing Name to examine
|
||||
|
@ -224,13 +294,21 @@ FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
|
|||
* @name FsRtlIsNameInExpression
|
||||
* @implemented
|
||||
*
|
||||
* FILLME
|
||||
* Check if the Name string is in the Expression string.
|
||||
*
|
||||
* @param DeviceObject
|
||||
* FILLME
|
||||
* @param Expression
|
||||
* The string in which we've to find Name. It can contain wildcards.
|
||||
* If IgnoreCase is set to TRUE, this string MUST BE uppercase.
|
||||
*
|
||||
* @param Irp
|
||||
* FILLME
|
||||
* @param Name
|
||||
* The string to find. It cannot contain wildcards
|
||||
*
|
||||
* @param IgnoreCase
|
||||
* If set to TRUE, case will be ignore with upcasing both strings
|
||||
*
|
||||
* @param UpcaseTable
|
||||
* If not NULL, and if IgnoreCase is set to TRUE, it will be used to
|
||||
* upcase the both strings
|
||||
*
|
||||
* @return TRUE if Name is in Expression, FALSE otherwise
|
||||
*
|
||||
|
@ -246,80 +324,31 @@ FsRtlIsNameInExpression(IN PUNICODE_STRING Expression,
|
|||
IN BOOLEAN IgnoreCase,
|
||||
IN PWCHAR UpcaseTable OPTIONAL)
|
||||
{
|
||||
USHORT ExpressionPosition, NamePosition;
|
||||
UNICODE_STRING TempExpression, TempName;
|
||||
BOOLEAN Result;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING IntName;
|
||||
|
||||
ExpressionPosition = 0;
|
||||
NamePosition = 0;
|
||||
while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
|
||||
NamePosition < (Name->Length / sizeof(WCHAR)))
|
||||
if (IgnoreCase && !UpcaseTable)
|
||||
{
|
||||
if (Expression->Buffer[ExpressionPosition] == L'*')
|
||||
Status = RtlUpcaseUnicodeString(&IntName, Name, TRUE);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
ExpressionPosition++;
|
||||
if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
while (NamePosition < (Name->Length / sizeof(WCHAR)))
|
||||
{
|
||||
TempExpression.Length =
|
||||
TempExpression.MaximumLength =
|
||||
Expression->Length - (ExpressionPosition * sizeof(WCHAR));
|
||||
TempExpression.Buffer = Expression->Buffer + ExpressionPosition;
|
||||
TempName.Length =
|
||||
TempName.MaximumLength =
|
||||
Name->Length - (NamePosition * sizeof(WCHAR));
|
||||
TempName.Buffer = Name->Buffer + NamePosition;
|
||||
/* FIXME: Rewrite to get rid of recursion */
|
||||
if (FsRtlIsNameInExpression(&TempExpression, &TempName,
|
||||
IgnoreCase, UpcaseTable))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
NamePosition++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Take UpcaseTable into account! */
|
||||
if (Expression->Buffer[ExpressionPosition] == L'?' ||
|
||||
(IgnoreCase &&
|
||||
RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) ==
|
||||
RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) ||
|
||||
(!IgnoreCase &&
|
||||
Expression->Buffer[ExpressionPosition] ==
|
||||
Name->Buffer[NamePosition]))
|
||||
{
|
||||
NamePosition++;
|
||||
ExpressionPosition++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ExRaiseStatus(Status);
|
||||
}
|
||||
Name = &IntName;
|
||||
IgnoreCase = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
IntName.Buffer = NULL;
|
||||
}
|
||||
|
||||
/* Handle matching of "f0_*.*" expression to "f0_000" file name. */
|
||||
if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
|
||||
Expression->Buffer[ExpressionPosition] == L'.')
|
||||
Result = FsRtlIsNameInExpressionPrivate(Expression, Name, IgnoreCase, UpcaseTable);
|
||||
|
||||
if (IntName.Buffer != NULL)
|
||||
{
|
||||
while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
|
||||
(Expression->Buffer[ExpressionPosition] == L'.' ||
|
||||
Expression->Buffer[ExpressionPosition] == L'*' ||
|
||||
Expression->Buffer[ExpressionPosition] == L'?'))
|
||||
{
|
||||
ExpressionPosition++;
|
||||
}
|
||||
RtlFreeUnicodeString(&IntName);
|
||||
}
|
||||
|
||||
if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) &&
|
||||
NamePosition == (Name->Length / sizeof(WCHAR)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue