From c3d141b6750ce86d3d3776f8ab1438aca3bbccd0 Mon Sep 17 00:00:00 2001 From: "Carl J. Bialorucki" Date: Tue, 21 Jul 2026 14:54:10 -0500 Subject: [PATCH] [NTOS][NTOS:FSRTL] Use RtlIsNameInExpression for FsRtlIsNameInExpression Also link rtl_vista to ntoskrnl --- ntoskrnl/CMakeLists.txt | 2 +- ntoskrnl/fsrtl/name.c | 314 ------------------------------- ntoskrnl/ntkrnlmp/CMakeLists.txt | 2 +- ntoskrnl/ntoskrnl.spec | 2 +- 4 files changed, 3 insertions(+), 317 deletions(-) diff --git a/ntoskrnl/CMakeLists.txt b/ntoskrnl/CMakeLists.txt index 34999010434..8e24d9789b7 100644 --- a/ntoskrnl/CMakeLists.txt +++ b/ntoskrnl/CMakeLists.txt @@ -46,7 +46,7 @@ set_module_type(ntoskrnl kernel) source_group(TREE ${REACTOS_SOURCE_DIR}/ntoskrnl PREFIX "Source Files" FILES ${NTOSKRNL_SOURCE}) -target_link_libraries(ntoskrnl ntoskrnl_vista cportlib csq ${PSEH_LIB} arbiter cmlib ntlsalib rtl ${ROSSYM_LIB} libcntpr setjmp wdmguid poguid ioevent) +target_link_libraries(ntoskrnl ntoskrnl_vista cportlib csq ${PSEH_LIB} arbiter cmlib ntlsalib rtl rtl_vista ${ROSSYM_LIB} libcntpr setjmp wdmguid poguid ioevent) if(STACK_PROTECTOR) target_link_libraries(ntoskrnl gcc_ssp_nt) diff --git a/ntoskrnl/fsrtl/name.c b/ntoskrnl/fsrtl/name.c index 3d2b33ea831..5a2f8efc08b 100644 --- a/ntoskrnl/fsrtl/name.c +++ b/ntoskrnl/fsrtl/name.c @@ -15,257 +15,6 @@ #define NDEBUG #include -/* PRIVATE FUNCTIONS *********************************************************/ -BOOLEAN -NTAPI -FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression, - IN PUNICODE_STRING Name, - IN BOOLEAN IgnoreCase, - IN PWCHAR UpcaseTable OPTIONAL) -{ - USHORT Offset, Position, BackTrackingPosition, OldBackTrackingPosition; - USHORT BackTrackingBuffer[16], OldBackTrackingBuffer[16] = {0}; - PUSHORT BackTrackingSwap, BackTracking = BackTrackingBuffer, OldBackTracking = OldBackTrackingBuffer; - ULONG BackTrackingBufferSize = RTL_NUMBER_OF(BackTrackingBuffer); - PVOID AllocatedBuffer = NULL; - UNICODE_STRING IntExpression; - USHORT ExpressionPosition, NamePosition = 0, MatchingChars = 1; - BOOLEAN EndOfName = FALSE; - BOOLEAN Result; - BOOLEAN DontSkipDot; - WCHAR CompareChar; - 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 && !Expression->Length) - return TRUE; - else - return FALSE; - } - - /* Check for a shortcut: just one wildcard */ - if (Expression->Length == sizeof(WCHAR)) - { - 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]] != - IntExpression.Buffer[ExpressionPosition]) - { - return FALSE; - } - } - - /* It matches */ - return TRUE; - } - } - } - - /* Name parsing loop */ - for (; !EndOfName; MatchingChars = BackTrackingPosition, NamePosition++) - { - /* Reset positions */ - OldBackTrackingPosition = BackTrackingPosition = 0; - - if (NamePosition >= Name->Length / sizeof(WCHAR)) - { - EndOfName = TRUE; - if (MatchingChars && (OldBackTracking[MatchingChars - 1] == Expression->Length * 2)) - break; - } - - while (MatchingChars > OldBackTrackingPosition) - { - ExpressionPosition = (OldBackTracking[OldBackTrackingPosition++] + 1) / 2; - - /* Expression parsing loop */ - for (Offset = 0; ExpressionPosition < Expression->Length; Offset = sizeof(WCHAR)) - { - ExpressionPosition += Offset; - - if (ExpressionPosition == Expression->Length) - { - BackTracking[BackTrackingPosition++] = Expression->Length * 2; - break; - } - - /* If buffer too small */ - if (BackTrackingPosition > BackTrackingBufferSize - 3) - { - /* We should only ever get here once! */ - ASSERT(AllocatedBuffer == NULL); - ASSERT((BackTracking == BackTrackingBuffer) || (BackTracking == OldBackTrackingBuffer)); - ASSERT((OldBackTracking == BackTrackingBuffer) || (OldBackTracking == OldBackTrackingBuffer)); - - /* Calculate buffer size */ - BackTrackingBufferSize = Expression->Length / sizeof(WCHAR) * 2 + 1; - - /* Allocate memory for both back-tracking buffers */ - AllocatedBuffer = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, - 2 * BackTrackingBufferSize * sizeof(USHORT), - 'nrSF'); - if (AllocatedBuffer == NULL) - { - DPRINT1("Failed to allocate BackTracking buffer. BackTrackingBufferSize = =x%lx\n", - BackTrackingBufferSize); - Result = FALSE; - goto Exit; - } - - /* Copy BackTracking content. Note that it can point to either BackTrackingBuffer or OldBackTrackingBuffer */ - RtlCopyMemory(AllocatedBuffer, - BackTracking, - RTL_NUMBER_OF(BackTrackingBuffer) * sizeof(USHORT)); - - /* Place current Backtracking is at the start of the new buffer */ - BackTracking = AllocatedBuffer; - - /* Copy OldBackTracking content */ - RtlCopyMemory(&BackTracking[BackTrackingBufferSize], - OldBackTracking, - RTL_NUMBER_OF(OldBackTrackingBuffer) * sizeof(USHORT)); - - /* Place current OldBackTracking after current BackTracking in the buffer */ - OldBackTracking = &BackTracking[BackTrackingBufferSize]; - } - - /* Basic check to test if chars are equal */ - CompareChar = (NamePosition >= Name->Length / sizeof(WCHAR)) ? UNICODE_NULL : (IgnoreCase ? UpcaseTable[Name->Buffer[NamePosition]] : - Name->Buffer[NamePosition]); - if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == CompareChar && !EndOfName) - { - BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2; - } - /* Check cases that eat one char */ - else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == L'?' && !EndOfName) - { - BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2; - } - /* Test star */ - else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == L'*') - { - BackTracking[BackTrackingPosition++] = ExpressionPosition * 2; - BackTracking[BackTrackingPosition++] = (ExpressionPosition * 2) + 3; - continue; - } - /* Check DOS_STAR */ - else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_STAR) - { - /* Look for last dot */ - DontSkipDot = TRUE; - if (!EndOfName && Name->Buffer[NamePosition] == '.') - { - for (Position = NamePosition + 1; Position < Name->Length / sizeof(WCHAR); Position++) - { - if (Name->Buffer[Position] == L'.') - { - DontSkipDot = FALSE; - break; - } - } - } - - if (EndOfName || Name->Buffer[NamePosition] != L'.' || !DontSkipDot) - BackTracking[BackTrackingPosition++] = ExpressionPosition * 2; - - BackTracking[BackTrackingPosition++] = (ExpressionPosition * 2) + 3; - continue; - } - /* Check DOS_DOT */ - else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_DOT) - { - if (EndOfName) continue; - - if (Name->Buffer[NamePosition] == L'.') - BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2; - } - /* Check DOS_QM */ - else if (Expression->Buffer[ExpressionPosition / sizeof(WCHAR)] == DOS_QM) - { - if (EndOfName || Name->Buffer[NamePosition] == L'.') continue; - - BackTracking[BackTrackingPosition++] = (ExpressionPosition + sizeof(WCHAR)) * 2; - } - - /* Leave from loop */ - break; - } - - for (Position = 0; MatchingChars > OldBackTrackingPosition && Position < BackTrackingPosition; Position++) - { - while (MatchingChars > OldBackTrackingPosition && - BackTracking[Position] > OldBackTracking[OldBackTrackingPosition]) - { - ++OldBackTrackingPosition; - } - } - } - - /* Swap pointers */ - BackTrackingSwap = BackTracking; - BackTracking = OldBackTracking; - OldBackTracking = BackTrackingSwap; - } - - /* Store result value */ - Result = MatchingChars > 0 && (OldBackTracking[MatchingChars - 1] == (Expression->Length * 2)); - -Exit: - - /* Frees the memory if necessary */ - if (AllocatedBuffer != NULL) - { - ExFreePoolWithTag(AllocatedBuffer, 'nrSF'); - } - - return Result; -} - /* PUBLIC FUNCTIONS **********************************************************/ /*++ @@ -481,66 +230,3 @@ FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name) /* Nothing Found */ return FALSE; } - -/*++ - * @name FsRtlIsNameInExpression - * @implemented - * - * 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 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 - * - * @remarks From Bo Branten's ntifs.h v12. This function should be - * rewritten to avoid recursion and better wildcard handling - * should be implemented (see FsRtlDoesNameContainWildCards). - * - *--*/ -BOOLEAN -NTAPI -FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, - IN PUNICODE_STRING Name, - IN BOOLEAN IgnoreCase, - IN PWCHAR UpcaseTable OPTIONAL) -{ - BOOLEAN Result; - NTSTATUS Status; - UNICODE_STRING IntName; - - if (IgnoreCase && !UpcaseTable) - { - Status = RtlUpcaseUnicodeString(&IntName, Name, TRUE); - if (!NT_SUCCESS(Status)) - { - ExRaiseStatus(Status); - } - Name = &IntName; - IgnoreCase = FALSE; - } - else - { - IntName.Buffer = NULL; - } - - Result = FsRtlIsNameInExpressionPrivate(Expression, Name, IgnoreCase, UpcaseTable); - - if (IntName.Buffer != NULL) - { - RtlFreeUnicodeString(&IntName); - } - - return Result; -} diff --git a/ntoskrnl/ntkrnlmp/CMakeLists.txt b/ntoskrnl/ntkrnlmp/CMakeLists.txt index 6e351027c68..44e286578bf 100644 --- a/ntoskrnl/ntkrnlmp/CMakeLists.txt +++ b/ntoskrnl/ntkrnlmp/CMakeLists.txt @@ -37,7 +37,7 @@ if(STACK_PROTECTOR) target_link_libraries(ntkrnlmp gcc_ssp_nt) endif() -target_link_libraries(ntkrnlmp ntoskrnl_vista cportlib csq ${PSEH_LIB} arbiter cmlib ntlsalib rtl ${ROSSYM_LIB} libcntpr setjmp wdmguid poguid ioevent) +target_link_libraries(ntkrnlmp ntoskrnl_vista cportlib csq ${PSEH_LIB} arbiter cmlib ntlsalib rtl rtl_vista ${ROSSYM_LIB} libcntpr setjmp wdmguid poguid ioevent) add_importlibs(ntkrnlmp hal kdcom bootvid) add_pch(ntkrnlmp ${REACTOS_SOURCE_DIR}/ntoskrnl/include/ntoskrnl.h "${NTKRNLMP_PCH_SKIP_SOURCE}") add_dependencies(ntkrnlmp psdk asm) diff --git a/ntoskrnl/ntoskrnl.spec b/ntoskrnl/ntoskrnl.spec index 6a7fb0759be..c3448d402b4 100644 --- a/ntoskrnl/ntoskrnl.spec +++ b/ntoskrnl/ntoskrnl.spec @@ -237,7 +237,7 @@ @ stdcall FsRtlIsDbcsInExpression(ptr ptr) @ stdcall FsRtlIsFatDbcsLegal(long ptr long long long) @ stdcall FsRtlIsHpfsDbcsLegal(long ptr long long long) -@ stdcall FsRtlIsNameInExpression(ptr ptr long wstr) +@ stdcall FsRtlIsNameInExpression(ptr ptr long wstr) RtlIsNameInExpression @ stdcall FsRtlIsNtstatusExpected(long) @ stdcall FsRtlIsPagingFile(ptr) @ stdcall FsRtlIsTotalDeviceFailure(ptr)