Author: pschweitzer Date: Mon Aug 25 04:27:35 2008 New Revision: 35625
URL: http://svn.reactos.org/svn/reactos?rev=35625&view=rev Log: - Reimplemented FsRtlIsNameInExpression to get rid of recursion, and to handle all wild cards. - Updated its comments.
Modified: branches/pierre-fsd/ntoskrnl/fsrtl/name.c
Modified: branches/pierre-fsd/ntoskrnl/fsrtl/name.c URL: http://svn.reactos.org/svn/reactos/branches/pierre-fsd/ntoskrnl/fsrtl/name.c... ============================================================================== --- branches/pierre-fsd/ntoskrnl/fsrtl/name.c [iso-8859-1] (original) +++ branches/pierre-fsd/ntoskrnl/fsrtl/name.c [iso-8859-1] Mon Aug 25 04:27:35 2008 @@ -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 (heis_spiter@hotmail.com) */
/* INCLUDES ******************************************************************/ @@ -224,13 +225,20 @@ * @name FsRtlIsNameInExpression * @implemented * - * FILLME - * - * @param DeviceObject - * FILLME - * - * @param Irp - * FILLME + * Check if the Name string is in the Expression string. + * + * @param Expression + * The string in which we've to find Name. It can contains wildcards + * + * @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,85 +254,80 @@ IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL) { - USHORT ExpressionPosition, NamePosition; - UNICODE_STRING TempExpression, TempName; - - ExpressionPosition = 0; - NamePosition = 0; - while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && - NamePosition < (Name->Length / sizeof(WCHAR))) - { - 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)) + ULONG i, j, k = 0; + UNICODE_STRING IntExpression, IntName; + WCHAR IntExprBuffer[Expression->Length / sizeof(WCHAR)], IntNameBuffer[Name->Length / sizeof(WCHAR)]; + + ASSERT(!FsRtlDoesNameContainWildCards(Name)); + + /* We'll first upcase the both strings, if necessary. + In all cases, we'll create internal strings to work on. */ + if (IgnoreCase) + { + IntExpression.Buffer = IntExprBuffer; + IntName.Buffer = IntNameBuffer; + if (!UpcaseTable) + { + RtlUpcaseUnicodeString(&IntExpression, Expression, FALSE); + RtlUpcaseUnicodeString(&IntName, Name, FALSE); + + } + else + { + for (i = 0 ; i < Expression->Length / sizeof (WCHAR) + 1 ; i++) + { + IntExpression.Buffer[i] = UpcaseTable[Expression->Buffer[i]]; + } + IntExpression.Length = Expression->Length; + IntExpression.MaximumLength = Expression->MaximumLength; + for (i = 0 ; i < Name->Length / sizeof (WCHAR) + 1 ; i++) + { + IntName.Buffer[i] = UpcaseTable[Name->Buffer[i]]; + } + IntName.Length = Name->Length; + IntName.MaximumLength = Name->MaximumLength; + } + } + else + { + IntExpression.Length = Expression->Length; + IntExpression.MaximumLength = Expression->MaximumLength; + IntExpression.Buffer = Expression->Buffer; + IntName.Length = Name->Length; + IntName.MaximumLength = Name->MaximumLength; + IntName.Buffer = Name->Buffer; + } + + for (i = 0 ; i < IntExpression.Length / sizeof(WCHAR) ; i++) + { + if ((IntExpression.Buffer[i] == IntName.Buffer[k]) || (IntExpression.Buffer[i] == '?') || + (IntExpression.Buffer[i] == ANSI_DOS_QM) || + (IntExpression.Buffer[i] == ANSI_DOS_DOT && (IntName.Buffer[k] == '.' || IntName.Buffer[k] == '0'))) + { + k++; + } + else if (IntExpression.Buffer[i] == '*') + { + k = IntName.Length / sizeof(WCHAR); + } + else if (IntExpression.Buffer[i] == ANSI_DOS_STAR) + { + for (j = k ; j < IntName.Length / sizeof(WCHAR) ; j++) + { + if (IntName.Buffer[j] == '.') { - return TRUE; + k = j; } - NamePosition++; } } else { - if (Expression->Buffer[ExpressionPosition] == L'?' || ( - IgnoreCase && !UpcaseTable && - RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) == - RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) || - (!IgnoreCase && Expression->Buffer[ExpressionPosition] == - Name->Buffer[NamePosition])) - { - NamePosition++; - ExpressionPosition++; - } - else if (IgnoreCase && UpcaseTable) - { - if (UpcaseTable[Expression->Buffer[ExpressionPosition]] == - UpcaseTable[Name->Buffer[NamePosition]]) - { - NamePosition++; - ExpressionPosition++; - } - } - else - { - return FALSE; - } - } - } - - /* Handle matching of "f0_*.*" expression to "f0_000" file name. */ - if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && - Expression->Buffer[ExpressionPosition] == L'.') - { - while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && - (Expression->Buffer[ExpressionPosition] == L'.' || - Expression->Buffer[ExpressionPosition] == L'*' || - Expression->Buffer[ExpressionPosition] == L'?')) - { - ExpressionPosition++; - } - } - - if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) && - NamePosition == (Name->Length / sizeof(WCHAR))) - { - return TRUE; + k = 0; + } + if (k == IntName.Length / sizeof(WCHAR)) + { + return TRUE; + } }
return FALSE;