- 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;