- Fix function signature of CompareUnicodeStrings
- Add special case where we get a prefix itself and a name starting with
a prefix character.
- Implement RtlInitializeGenericTable
This fixes the windows npfs.sys hang.
Modified: trunk/reactos/lib/rtl/generictable.c
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/generictable.c
--- trunk/reactos/lib/rtl/generictable.c 2005-11-08 16:24:58 UTC
(rev 19054)
+++ trunk/reactos/lib/rtl/generictable.c 2005-11-08 16:41:58 UTC
(rev 19055)
@@ -146,19 +146,26 @@
}
/*
-* @unimplemented
+* @implemented
*/
VOID
NTAPI
-RtlInitializeGenericTable (
- PRTL_GENERIC_TABLE Table,
- PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
- PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
- PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
- PVOID TableContext
- )
+RtlInitializeGenericTable(PRTL_GENERIC_TABLE Table,
+ PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
+ PRTL_GENERIC_ALLOCATE_ROUTINE
AllocateRoutine,
+ PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
+ PVOID TableContext)
{
- UNIMPLEMENTED;
+ /* Initialize the table to default and passed values */
+ InitializeListHead(&Table->InsertOrderList);
+ Table->TableRoot = NULL;
+ Table->NumberGenericTableElements = 0;
+ Table->WhichOrderedElement = 0;
+ Table->OrderedPointer = &Table->InsertOrderList;
+ Table->CompareRoutine = CompareRoutine;
+ Table->AllocateRoutine = AllocateRoutine;
+ Table->FreeRoutine = FreeRoutine;
+ Table->TableContext = TableContext;
}
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-08 16:24:58 UTC
(rev 19054)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-08 16:41:58 UTC
(rev 19055)
@@ -48,8 +48,8 @@
STATIC
RTL_GENERIC_COMPARE_RESULTS
NTAPI
-CompareUnicodeStrings(IN PUNICODE_STRING String,
- IN PUNICODE_STRING Prefix,
+CompareUnicodeStrings(IN PUNICODE_STRING Prefix,
+ IN PUNICODE_STRING String,
IN ULONG CaseCheckChar)
{
ULONG StringLength = String->Length / sizeof(WCHAR);
@@ -58,7 +58,18 @@
ULONG i;
WCHAR FoundPrefix, FoundString;
PWCHAR p, p1;
+ DPRINT("CompareUnicodeStrings: %wZ %wZ\n", String, Prefix);
+ /* Handle case noticed in npfs when Prefix = '\' and name starts
with '\' */
+ if ((PrefixLength == 1) &&
+ (Prefix->Buffer[0] == '\\') &&
+ (StringLength > 1) &&
+ (String->Buffer[0] == '\\'))
+ {
+ /* The string is actually a prefix */
+ return -1;
+ }
+
/* Validate the Case Check Character Position */
if (CaseCheckChar > ScanLength) CaseCheckChar = ScanLength;
@@ -147,6 +158,7 @@
PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry, Entry,
NextEntry;
PRTL_SPLAY_LINKS SplayLinks;
RTL_GENERIC_COMPARE_RESULTS Result;
+ DPRINT("RtlFindUnicodePrefix\n");
/* Find out how many names there are */
NameCount = ComputeUnicodeNameLength(FullName);
@@ -164,16 +176,20 @@
/* Loop every entry which has valid entries */
while (CurrentEntry->NameLength)
{
+ DPRINT("CurrentEntry->NameLength %lx\n",
CurrentEntry->NameLength);
+
/* Get the splay links and loop */
while ((SplayLinks = &CurrentEntry->Links))
{
/* Get the entry */
+ DPRINT("SplayLinks %p\n", SplayLinks);
Entry = CONTAINING_RECORD(SplayLinks,
UNICODE_PREFIX_TABLE_ENTRY,
Links);
/* Do the comparison */
Result = CompareUnicodeStrings(Entry->Prefix, FullName, 0);
+ DPRINT("Result %lx\n", Result);
if (Result == GenericGreaterThan)
{
/* Prefix is greater, so restart on the left child */
@@ -192,6 +208,7 @@
* NOTE: An index of 0 means case-insensitive(ie, we'll be
case
* insensitive since index 0, ie, all the time)
*/
+ DPRINT("CaseInsensitiveIndex %lx\n", CaseInsensitiveIndex);
if (!CaseInsensitiveIndex)
{
/*
@@ -225,6 +242,7 @@
}
/* Return the entry */
+ DPRINT("RtlFindUnicodePrefix: %p\n", Entry);
return Entry;
}
@@ -240,11 +258,13 @@
(Result != GenericGreaterThan))
{
/* This is a positive match, return it */
+ DPRINT("RtlFindUnicodePrefix: %p\n", NextEntry);
return NextEntry;
}
/* No match yet, continue looping the circular list */
NextEntry = NextEntry->CaseMatch;
+ DPRINT("NextEntry %p\n", NextEntry);
} while (NextEntry != Entry);
/*
@@ -258,9 +278,11 @@
/* Splay links exausted, move to next entry */
PreviousEntry = CurrentEntry;
CurrentEntry = CurrentEntry->NextPrefixTree;
+ DPRINT("CurrentEntry %p\n", CurrentEntry);
}
/* If we got here, nothing was found */
+ DPRINT("RtlFindUnicodePrefix: %p\n", NULL);
return NULL;
}
@@ -291,6 +313,7 @@
ULONG NameCount;
RTL_GENERIC_COMPARE_RESULTS Result;
PRTL_SPLAY_LINKS SplayLinks;
+ DPRINT("RtlInsertUnicodePrefix\n");
/* Find out how many names there are */
NameCount = ComputeUnicodeNameLength(Prefix);
@@ -322,6 +345,7 @@
PrefixTableEntry->CaseMatch = PrefixTableEntry;
/* Quick return */
+ DPRINT("RtlInsertUnicodePrefix TRUE\n");
return TRUE;
}
@@ -344,6 +368,7 @@
(GenericEqual))
{
/* We must fail the insert: it already exists */
+ DPRINT("RtlInsertUnicodePrefix FALSE\n");
return FALSE;
}
@@ -436,6 +461,7 @@
Entry->NextPrefixTree = NextEntry;
/* Return success */
+ DPRINT("RtlInsertUnicodePrefix TRUE\n");
return TRUE;
}
@@ -449,6 +475,7 @@
{
PRTL_SPLAY_LINKS SplayLinks;
PUNICODE_PREFIX_TABLE_ENTRY Entry, CaseMatchEntry;
+ DPRINT("RtlNextUnicodePrefix\n");
/* We might need this entry 2/3rd of the time, so cache it now */
CaseMatchEntry = PrefixTable->LastNextEntry->CaseMatch;
@@ -507,6 +534,7 @@
/* Save this entry as the last one returned, and return it */
PrefixTable->LastNextEntry = Entry;
+ DPRINT("RtlNextUnicodePrefix: %p\n", Entry);
return Entry;
}
@@ -520,6 +548,7 @@
{
PUNICODE_PREFIX_TABLE_ENTRY Entry, RefEntry, NewEntry;
PRTL_SPLAY_LINKS SplayLinks;
+ DPRINT("RtlRemoveUnicodePrefix\n");
/* Erase the last entry */
PrefixTable->LastNextEntry = NULL;