From: Aleksey Bragin Date: Sun, 6 Mar 2011 11:00:17 +0000 (+0000) Subject: [NTOS/FSRTL] X-Git-Tag: ReactOS-0.3.13~62 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=e996625659e32880cda3b16a6e7e37b2fa9b75e4;hp=91bdfab1bd31a84f1f942296f79dd145894af159 [NTOS/FSRTL] - Implement parameters checking in FsRtlIsNameInExpressionPrivate. - Add two shortcuts for common wildcard invocations to make the function faster. - Second (main part of the function) is still under review. svn path=/trunk/; revision=50981 --- diff --git a/reactos/ntoskrnl/fsrtl/name.c b/reactos/ntoskrnl/fsrtl/name.c index 8ed32a34b4b..84fba9b4437 100644 --- a/reactos/ntoskrnl/fsrtl/name.c +++ b/reactos/ntoskrnl/fsrtl/name.c @@ -5,7 +5,8 @@ * 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) + * Pierre Schweitzer (pierre.schweitzer@reactos.org) + * Aleksey Bragin (aleksey@reactos.org) */ /* INCLUDES ******************************************************************/ @@ -23,10 +24,79 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression, IN PWCHAR UpcaseTable OPTIONAL) { USHORT ExpressionPosition = 0, NamePosition = 0, MatchingChars, StarFound = MAXUSHORT; + UNICODE_STRING IntExpression; PAGED_CODE(); + /* Check if we were given strings at all */ + if (!Name->Length || !Expression->Length) + { + /* Return TRUE if both strings are empty, otherwise FALSE */ + if (Name->Length == 0 && Expression->Length == 0) + return TRUE; + else + return FALSE; + } + + /* Check for a shortcut: just one wildcard */ + if (Expression->Length == 2) + { + if (Expression->Buffer[0] == L'*') + return TRUE; + } + ASSERT(!IgnoreCase || UpcaseTable); + /* Another shortcut, wildcard followed by some string */ + if (Expression->Buffer[0] == L'*') + { + /* Copy Expression to our local variable */ + IntExpression = *Expression; + + /* Skip the first char */ + IntExpression.Buffer++; + IntExpression.Length -= sizeof(WCHAR); + + /* Continue only if the rest of the expression does NOT contain + any more wildcards */ + if (!FsRtlDoesNameContainWildCards(&IntExpression)) + { + /* Check for a degenerate case */ + if (Name->Length < (Expression->Length - sizeof(WCHAR))) + return FALSE; + + /* Calculate position */ + NamePosition = (Name->Length - IntExpression.Length) / sizeof(WCHAR); + + /* Compare */ + if (!IgnoreCase) + { + /* We can just do a byte compare */ + return RtlEqualMemory(IntExpression.Buffer, + Name->Buffer + NamePosition, + IntExpression.Length); + } + else + { + /* Not so easy, need to upcase and check char by char */ + for (ExpressionPosition = 0; ExpressionPosition < (IntExpression.Length / sizeof(WCHAR)); ExpressionPosition++) + { + /* Assert that expression is already upcased! */ + ASSERT(IntExpression.Buffer[ExpressionPosition] == UpcaseTable[IntExpression.Buffer[ExpressionPosition]]); + + /* Now compare upcased name char with expression */ + if (UpcaseTable[Name->Buffer[NamePosition + ExpressionPosition]] != + UpcaseTable[IntExpression.Buffer[ExpressionPosition]]) + { + return FALSE; + } + } + + /* It matches */ + return TRUE; + } + } + } + while (NamePosition < Name->Length / sizeof(WCHAR) && ExpressionPosition < Expression->Length / sizeof(WCHAR)) { if ((Expression->Buffer[ExpressionPosition] == (IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : Name->Buffer[NamePosition]))) @@ -385,7 +455,7 @@ FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, if (IgnoreCase && !UpcaseTable) { Status = RtlUpcaseUnicodeString(&IntName, Name, TRUE); - if (Status != STATUS_SUCCESS) + if (!NT_SUCCESS(Status)) { ExRaiseStatus(Status); }