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.…
==============================================================================
--- 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(a)reactos.org)
* Filip Navara (navaraf(a)reactos.org)
+ * Pierre Schweitzer (heis_spiter(a)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;