* 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 ******************************************************************/
#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)
+{
+ USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, StarFound = MAXUSHORT;
+ PAGED_CODE();
+
+ ASSERT(!IgnoreCase || UpcaseTable);
+
+ while (NamePosition < Name->Length / sizeof(WCHAR) && ExpressionPosition < Expression->Length / sizeof(WCHAR))
+ {
+ if ((Expression->Buffer[ExpressionPosition] == (IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition])))
+ {
+ NamePosition++;
+ ExpressionPosition++;
+ }
+ else if (Expression->Buffer[ExpressionPosition] == L'?' || (Expression->Buffer[ExpressionPosition] == DOS_QM) ||
+ (Expression->Buffer[ExpressionPosition] == DOS_DOT && Name->Buffer[NamePosition] == L'.'))
+ {
+ NamePosition++;
+ ExpressionPosition++;
+ StarFound = MAXUSHORT;
+ }
+ else if (Expression->Buffer[ExpressionPosition] == L'*')
+ {
+ StarFound = ExpressionPosition++;
+ if (StarFound < (Expression->Length / sizeof(WCHAR) - 1))
+ {
+ while ((IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition]) != Expression->Buffer[ExpressionPosition] &&
+ NamePosition < Name->Length / sizeof(WCHAR))
+ {
+ NamePosition++;
+ }
+ }
+ else
+ {
+ NamePosition = Name->Length / sizeof(WCHAR);
+ }
+ }
+ else if (Expression->Buffer[ExpressionPosition] == DOS_STAR)
+ {
+ StarFound = MAXUSHORT;
+ MatchingChars = NamePosition;
+ while (MatchingChars < Name->Length / sizeof(WCHAR))
+ {
+ if (Name->Buffer[MatchingChars] == L'.')
+ {
+ NamePosition = MatchingChars;
+ }
+ MatchingChars++;
+ }
+ ExpressionPosition++;
+ }
+ else if (StarFound != MAXUSHORT)
+ {
+ ExpressionPosition = StarFound + 1;
+ while ((IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition]) != Expression->Buffer[ExpressionPosition] &&
+ NamePosition < Name->Length / sizeof(WCHAR))
+ {
+ NamePosition++;
+ }
+ }
+ else
+ {
+ NamePosition = Name->Length / sizeof(WCHAR);
+ }
+ }
+ if (ExpressionPosition + 1 == Expression->Length / sizeof(WCHAR) && NamePosition == Name->Length / sizeof(WCHAR) &&
+ Expression->Buffer[ExpressionPosition] == DOS_DOT)
+ {
+ ExpressionPosition++;
+ }
+
+ return (ExpressionPosition == Expression->Length / sizeof(WCHAR) && NamePosition == Name->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.
*
BOOLEAN StringsAreEqual, MemoryAllocated = FALSE;
ULONG i;
NTSTATUS Status;
+ PAGED_CODE();
/* Well, first check their size */
if (Name1->Length != Name2->Length) return FALSE;
{
ULONG FirstPosition, i;
ULONG SkipFirstSlash = 0;
+ PAGED_CODE();
/* Zero the strings before continuing */
RtlZeroMemory(FirstPart, sizeof(UNICODE_STRING));
* @name FsRtlDoesNameContainWildCards
* @implemented
*
- * FILLME
+ * Checks if the given string contains WildCards
*
* @param Name
* Pointer to a UNICODE_STRING containing Name to examine
FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
{
PWCHAR Ptr;
+ PAGED_CODE();
/* Loop through every character */
if (Name->Length)
* @name FsRtlIsNameInExpression
* @implemented
*
- * FILLME
+ * Check if the Name string is in the Expression string.
+ *
+ * @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 DeviceObject
- * FILLME
+ * @param Name
+ * The string to find. It cannot contain wildcards
*
- * @param Irp
- * FILLME
+ * @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
*
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'*')
- {
- 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
+ Status = RtlUpcaseUnicodeString(&IntName, Name, TRUE);
+ if (Status != STATUS_SUCCESS)
{
- /* 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;
}
-
- /* Handle matching of "f0_*.*" expression to "f0_000" file name. */
- if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
- Expression->Buffer[ExpressionPosition] == L'.')
+ else
{
- while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) &&
- (Expression->Buffer[ExpressionPosition] == L'.' ||
- Expression->Buffer[ExpressionPosition] == L'*' ||
- Expression->Buffer[ExpressionPosition] == L'?'))
- {
- ExpressionPosition++;
- }
+ IntName.Buffer = NULL;
}
- if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) &&
- NamePosition == (Name->Length / sizeof(WCHAR)))
+ Result = FsRtlIsNameInExpressionPrivate(Expression, Name, IgnoreCase, UpcaseTable);
+
+ if (IntName.Buffer != NULL)
{
- return TRUE;
+ RtlFreeUnicodeString(&IntName);
}
- return FALSE;
+ return Result;
}
-