Author: tkreuzer
Date: Sat Feb  1 14:28:15 2014
New Revision: 61900
URL: 
http://svn.reactos.org/svn/reactos?rev=61900&view=rev
Log:
[NPFS]
- Implement NpInitializeAliases + NpTranslateAlias
- Add a number of debug traces, disabled by default
Modified:
    trunk/reactos/drivers/filesystems/npfs/create.c
    trunk/reactos/drivers/filesystems/npfs/main.c
    trunk/reactos/drivers/filesystems/npfs/npfs.h
    trunk/reactos/drivers/filesystems/npfs/strucsup.c
    trunk/reactos/drivers/filesystems/npfs/volinfo.c
Modified: trunk/reactos/drivers/filesystems/npfs/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/c…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/create.c     [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/create.c     [iso-8859-1] Sat Feb  1 14:28:15
2014
@@ -59,12 +59,14 @@
 {
     IO_STATUS_BLOCK Status;
     PAGED_CODE();
+    TRACE("Entered\n");
     NpSetFileObject(FileObject, NpVcb, NULL, FALSE);
     ++NpVcb->ReferenceCount;
     Status.Information = FILE_OPENED;
     Status.Status = STATUS_SUCCESS;
+    TRACE("Leaving, Status.Status = %lx\n", Status.Status);
     return Status;
 }
@@ -78,6 +80,7 @@
     IO_STATUS_BLOCK IoStatus;
     PNP_ROOT_DCB_FCB Ccb;
     PAGED_CODE();
+    TRACE("Entered\n");
     IoStatus.Status = NpCreateRootDcbCcb(&Ccb);
     if (NT_SUCCESS(IoStatus.Status))
@@ -93,6 +96,7 @@
         IoStatus.Information = 0;
     }
+    TRACE("Leaving, IoStatus = %lx\n", IoStatus);
     return IoStatus;
 }
@@ -116,6 +120,7 @@
     USHORT NamedPipeConfiguration;
     PLIST_ENTRY NextEntry, ListHead;
     PNP_CCB Ccb = NULL;
+    TRACE("Entered\n");
     IoStatus.Status = STATUS_SUCCESS;
     IoStatus.Information = 0;
@@ -167,6 +172,7 @@
         ((GrantedAccess & FILE_WRITE_DATA) && (NamedPipeConfiguration ==
FILE_PIPE_OUTBOUND)))
     {
         IoStatus.Status = STATUS_ACCESS_DENIED;
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
@@ -185,6 +191,7 @@
     if (NextEntry == ListHead)
     {
         IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE;
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
@@ -195,6 +202,7 @@
     if (!NT_SUCCESS(IoStatus.Status))
     {
         NpUninitializeSecurity(Ccb);
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
@@ -203,7 +211,149 @@
     IoStatus.Information = FILE_OPENED;
     IoStatus.Status = STATUS_SUCCESS;
+    TRACE("Leaving, IoStatus = %lx\n", IoStatus);
     return IoStatus;
+}
+
+NTSTATUS
+NTAPI
+NpTranslateAlias(
+    PUNICODE_STRING PipeName)
+{
+    WCHAR UpcaseBuffer[MAX_INDEXED_LENGTH + 1];
+    UNICODE_STRING UpcaseString;
+    ULONG Length;
+    PNPFS_ALIAS CurrentAlias;
+    NTSTATUS Status;
+    BOOLEAN BufferAllocated, BackSlash;
+    LONG Result;
+    PAGED_CODE();
+
+    /* Get the pipe name length and check for empty string */
+    Length = PipeName->Length;
+    if (Length == 0)
+    {
+        return STATUS_SUCCESS;
+    }
+
+    /* Check if the name starts with a path separator */
+    BackSlash = (PipeName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
+    if (BackSlash)
+    {
+        /* We are only interested in the part after the backslash */
+        Length -= sizeof(WCHAR);
+    }
+
+    /* Check if the length is within our indexed list bounds */
+    if ((Length >= MIN_INDEXED_LENGTH * sizeof(WCHAR)) &&
+        (Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR)))
+    {
+        /* Length is within bounds, use the list by length */
+        CurrentAlias = NpAliasListByLength[(Length / sizeof(WCHAR)) -
MIN_INDEXED_LENGTH];
+    }
+    else
+    {
+        /* We use the generic list, search for an entry of the right size */
+        CurrentAlias = NpAliasList;
+        while ((CurrentAlias != NULL) && (CurrentAlias->Name.Length !=
Length))
+        {
+            /* Check if we went past the desired length */
+            if (CurrentAlias->Name.Length > Length)
+            {
+                /* In this case there is no matching alias, return success */
+                return STATUS_SUCCESS;
+            }
+
+            /* Go to the next alias in the list */
+            CurrentAlias = CurrentAlias->Next;
+        }
+    }
+
+    /* Did we find any alias? */
+    if (CurrentAlias == NULL)
+    {
+        /* Nothing found, no matching alias */
+        return STATUS_SUCCESS;
+    }
+
+    /* Check whether we can use our stack buffer */
+    if (Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR))
+    {
+        /* Initialize the upcased string */
+        UpcaseString.Buffer = UpcaseBuffer;
+        UpcaseString.MaximumLength = sizeof(UpcaseBuffer);
+
+        /* Upcase the pipe name */
+        Status = RtlUpcaseUnicodeString(&UpcaseString, PipeName, FALSE);
+        NT_ASSERT(NT_SUCCESS(Status));
+        BufferAllocated = FALSE;
+    }
+    else
+    {
+        /* Upcase the pipe name, allocate the string buffer */
+        Status = RtlUpcaseUnicodeString(&UpcaseString, PipeName, TRUE);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+
+        BufferAllocated = TRUE;
+    }
+
+    /* Did the original name start with a backslash? */
+    if (BackSlash)
+    {
+        /* Skip it for the comparison */
+        UpcaseString.Buffer++;
+        UpcaseString.Length -= sizeof(WCHAR);
+    }
+
+    /* Make sure the length matches the "raw" length */
+    NT_ASSERT(UpcaseString.Length == Length);
+    NT_ASSERT(CurrentAlias->Name.Length == Length);
+
+    /* Loop while we have aliases */
+    do
+    {
+        /* Compare the names and check if they match */
+        Result = NpCompareAliasNames(&UpcaseString, &CurrentAlias->Name);
+        if (Result == 0)
+        {
+            /* The names match, use the target name */
+            *PipeName = *CurrentAlias->TargetName;
+
+            /* Did the original name start with a backslash? */
+            if (!BackSlash)
+            {
+                /* It didn't, so skip it in the target name as well */
+                PipeName->Buffer++;
+                PipeName->Length -= sizeof(WCHAR);
+            }
+            break;
+        }
+
+        /* Check if we went past all string candidates */
+        if (Result < 0)
+        {
+            /* Nothing found, we're done */
+            break;
+        }
+
+        /* Go to the next alias */
+        CurrentAlias = CurrentAlias->Next;
+
+        /* Keep looping while we have aliases of the right length */
+    } while ((CurrentAlias != NULL) && (CurrentAlias->Name.Length == Length));
+
+    /* Did we allocate a buffer? */
+    if (BufferAllocated)
+    {
+        /* Free the allocated buffer */
+        ASSERT(UpcaseString.Buffer != UpcaseBuffer);
+        RtlFreeUnicodeString(&UpcaseString);
+    }
+
+    return STATUS_SUCCESS;
 }
 NTSTATUS
@@ -223,6 +373,8 @@
     ACCESS_MASK DesiredAccess;
     LIST_ENTRY DeferredList;
     UNICODE_STRING Prefix;
+    NTSTATUS Status;
+    TRACE("Entered\n");
     InitializeListHead(&DeferredList);
     IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
@@ -276,8 +428,9 @@
         goto Quickie;
     }
-    // Status = NpTranslateAlias(&FileName);; // ignore this for now
-    // if (!NT_SUCCESS(Status)) goto Quickie;
+    Status = NpTranslateAlias(&FileName);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
     if (RelatedFileObject)
     {
         if (Type == NPFS_NTC_ROOT_DCB)
@@ -355,6 +508,7 @@
     Irp->IoStatus = IoStatus;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status);
     return IoStatus.Status;
 }
@@ -380,6 +534,7 @@
     USHORT NamedPipeConfiguration, CheckShareAccess;
     BOOLEAN AccessGranted;
     PAGED_CODE();
+    TRACE("Entered\n");
     Privileges = NULL;
@@ -424,17 +579,23 @@
                            &AccessState->GenerateOnClose);
     SeUnlockSubjectContext(SubjectSecurityContext);
-    if (!AccessGranted) return IoStatus;
+    if (!AccessGranted)
+    {
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
+        return IoStatus;
+    }
     if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
     {
         IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
     if (Disposition == FILE_CREATE)
     {
         IoStatus.Status = STATUS_ACCESS_DENIED;
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
@@ -455,6 +616,7 @@
     if (CheckShareAccess != ShareAccess)
     {
         IoStatus.Status = STATUS_ACCESS_DENIED;
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
@@ -476,6 +638,7 @@
     {
         --Ccb->Fcb->CurrentInstances;
         NpDeleteCcb(Ccb, List);
+        TRACE("Leaving, IoStatus = %lx\n", IoStatus);
         return IoStatus;
     }
@@ -485,6 +648,7 @@
     IoStatus.Status = STATUS_SUCCESS;
     IoStatus.Information = 1;
+    TRACE("Leaving, IoStatus = %lx\n", IoStatus);
     return IoStatus;
 }
@@ -509,6 +673,7 @@
     PNP_CCB Ccb;
     PNP_FCB Fcb;
     PAGED_CODE();
+    TRACE("Entered\n");
     if (!(Parameters->TimeoutSpecified) ||
         !(Parameters->MaximumInstances) ||
@@ -611,9 +776,11 @@
     IoStatus->Status = STATUS_SUCCESS;
     IoStatus->Information = FILE_CREATED;
+    TRACE("Leaving, STATUS_SUCCESS\n");
     return STATUS_SUCCESS;
 Quickie:
+    TRACE("Leaving, Status = %lx\n", Status);
     IoStatus->Information = 0;
     IoStatus->Status = Status;
     return Status;
@@ -635,6 +802,7 @@
     UNICODE_STRING Prefix;
     PNAMED_PIPE_CREATE_PARAMETERS Parameters;
     IO_STATUS_BLOCK IoStatus;
+    TRACE("Entered\n");
     InitializeListHead(&DeferredList);
     Process = IoGetRequestorProcess(Irp);
@@ -741,6 +909,7 @@
     NpCompleteDeferredIrps(&DeferredList);
     FsRtlExitFileSystem();
+    TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status);
     Irp->IoStatus = IoStatus;
     IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
     return IoStatus.Status;
Modified: trunk/reactos/drivers/filesystems/npfs/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/m…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/main.c       [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/main.c       [iso-8859-1] Sat Feb  1 14:28:15
2014
@@ -16,14 +16,292 @@
 /* GLOBALS ********************************************************************/
 PDEVICE_OBJECT NpfsDeviceObject;
+PVOID NpAliases;
+PNPFS_ALIAS NpAliasList;
+PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH];
 /* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+NpReadAlias(
+    PWSTR ValueName,
+    ULONG ValueType,
+    PVOID ValueData,
+    ULONG ValueLength,
+    PVOID Context,
+    PVOID EntryContext)
+{
+    PNPFS_QUERY_VALUE_CONTEXT QueryContext = Context;
+    PWSTR CurrentString;
+    USHORT Length;
+    PNPFS_ALIAS CurrentAlias;
+    UNICODE_STRING TempString;
+    PUNICODE_STRING CurrentTargetName;
+
+    /* Check if we have the expected type */
+    if (ValueType != REG_MULTI_SZ)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Check if only the size is requested */
+    if (QueryContext->SizeOnly)
+    {
+        /* Count this entry */
+        QueryContext->NumberOfEntries++;
+
+        /* Get the length of the value name (i.e. the target name). */
+        Length = wcslen(ValueName) * sizeof(WCHAR);
+
+        /* Add the size of the name plus a '\' and a UNICODE_STRING structure */
+        QueryContext->FullSize += Length + sizeof(UNICODE_NULL) +
+                                  sizeof(OBJ_NAME_PATH_SEPARATOR) +
+                                  sizeof(UNICODE_STRING);
+
+        /* Loop while we have alias names */
+        CurrentString = ValueData;
+        while (*CurrentString != UNICODE_NULL)
+        {
+            /* Count this alias */
+            QueryContext->NumberOfAliases++;
+
+            /* Get the length of the current string (i.e. the alias name) */
+            Length = wcslen(CurrentString) * sizeof(WCHAR);
+
+            /* Count the length plus the size of an NPFS_ALIAS structure */
+            QueryContext->FullSize += Length + sizeof(UNICODE_NULL) +
sizeof(NPFS_ALIAS);
+
+            /* Go to the next string */
+            CurrentString += (Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
+        }
+    }
+    else
+    {
+        /* Get the next name string pointer */
+        CurrentTargetName = QueryContext->CurrentTargetName++;
+
+        /* Get the length of the value name (i.e. the target name). */
+        Length = wcslen(ValueName) * sizeof(WCHAR);
+
+        /* Initialize the current name string (one char more than the name) */
+        CurrentTargetName->Buffer = QueryContext->CurrentStringPointer;
+        CurrentTargetName->Length = Length + sizeof(OBJ_NAME_PATH_SEPARATOR);
+        CurrentTargetName->MaximumLength = CurrentTargetName->Length +
sizeof(UNICODE_NULL);
+
+        /* Update the current string pointer */
+        QueryContext->CurrentStringPointer +=
+            CurrentTargetName->MaximumLength / sizeof(WCHAR);
+
+        /* Prepend a '\' before the name */
+        CurrentTargetName->Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
+
+        /* Append the value name (including the NULL termination) */
+        RtlCopyMemory(&CurrentTargetName->Buffer[1],
+                      ValueName,
+                      Length + sizeof(UNICODE_NULL));
+
+        /* Upcase the target name */
+        RtlUpcaseUnicodeString(CurrentTargetName, CurrentTargetName, 0);
+
+        /* Loop while we have alias names */
+        CurrentString = ValueData;
+        while (*CurrentString != UNICODE_NULL)
+        {
+            /* Get the next alias pointer */
+            CurrentAlias = QueryContext->CurrentAlias++;
+
+            /* Get the length of the current string (i.e. the alias name) */
+            Length = wcslen(CurrentString) * sizeof(WCHAR);
+
+            /* Setup the alias structure */
+            CurrentAlias->TargetName = CurrentTargetName;
+            CurrentAlias->Name.Buffer = QueryContext->CurrentStringPointer;
+            CurrentAlias->Name.Length = Length;
+            CurrentAlias->Name.MaximumLength = Length + sizeof(UNICODE_NULL);
+
+            /* Upcase the alias name */
+            TempString.Buffer = CurrentString;
+            TempString.Length = Length;
+            RtlUpcaseUnicodeString(&CurrentAlias->Name,
+                                   &TempString,
+                                   FALSE);
+
+            /* Update the current string pointer */
+            QueryContext->CurrentStringPointer +=
+                CurrentAlias->Name.MaximumLength / sizeof(WCHAR);
+
+            /* Go to the next string */
+            CurrentString += (Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
+        }
+    }
+
+    return STATUS_SUCCESS;
+}
+
+LONG
+NTAPI
+NpCompareAliasNames(
+    _In_ PCUNICODE_STRING String1,
+    _In_ PCUNICODE_STRING String2)
+{
+    ULONG Count;
+    PWCHAR P1, P2;
+
+    /* First check if the string sizes match */
+    if (String1->Length != String2->Length)
+    {
+        /* They don't, return positive if the first is longer, negative otherwise */
+        return String1->Length - String2->Length;
+    }
+
+    /* Now loop all characters */
+    Count = String1->Length / sizeof(WCHAR);
+    P1 = String1->Buffer;
+    P2 = String2->Buffer;
+    while (Count)
+    {
+        /* Check if they don't match */
+        if (*P1 != *P2)
+        {
+            /* Return positive if the first char is greater, negative otherwise */
+            return *P1 - *P2;
+        }
+
+        /* Go to the next buffer position */
+        P1++;
+        P2++;
+        Count--;
+    }
+
+    /* All characters matched, return 0 */
+    return 0;
+}
+
+NTSTATUS
+NTAPI
+NpInitializeAliases(VOID)
+{
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    NPFS_QUERY_VALUE_CONTEXT Context;
+    NTSTATUS Status;
+    USHORT Length;
+    ULONG i;
+    PNPFS_ALIAS CurrentAlias, *AliasPointer;
+
+    /* Initialize the query table */
+    QueryTable[0].QueryRoutine = NpReadAlias;
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_NOEXPAND;
+    QueryTable[0].Name = NULL;
+    QueryTable[0].EntryContext = NULL;
+    QueryTable[0].DefaultType = REG_NONE;
+    QueryTable[0].DefaultData = NULL;
+    QueryTable[0].DefaultLength = 0;
+    QueryTable[1].QueryRoutine = NULL;
+    QueryTable[1].Flags = 0;
+    QueryTable[1].Name = NULL;
+
+    /* Setup the query context */
+    Context.SizeOnly = 1;
+    Context.FullSize = 0;
+    Context.NumberOfAliases = 0;
+    Context.NumberOfEntries = 0;
+
+    /* Query the registry values (calculate length only) */
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES | RTL_REGISTRY_OPTIONAL,
+                                    L"Npfs\\Aliases",
+                                    QueryTable,
+                                    &Context,
+                                    NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+            return STATUS_SUCCESS;
+
+        return Status;
+    }
+
+    /* Check if there is anything */
+    if (Context.FullSize == 0)
+    {
+        /* Nothing to do, return success */
+        return STATUS_SUCCESS;
+    }
+
+    /* Allocate a structure large enough to hold all the data */
+    NpAliases = ExAllocatePoolWithTag(NonPagedPool, Context.FullSize, 'sfpN');
+    if (NpAliases == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Now setup the actual pointers in the context */
+    Context.CurrentTargetName = NpAliases;
+    CurrentAlias = (PNPFS_ALIAS)&Context.CurrentTargetName[Context.NumberOfEntries];
+    Context.CurrentAlias = CurrentAlias;
+    Context.CurrentStringPointer = (PWCHAR)&CurrentAlias[Context.NumberOfAliases];
+
+    /* This time query the real data */
+    Context.SizeOnly = FALSE;
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES | RTL_REGISTRY_OPTIONAL,
+                                    L"Npfs\\Aliases",
+                                    QueryTable,
+                                    &Context,
+                                    NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        ExFreePoolWithTag(NpAliases, 0);
+        NpAliases = NULL;
+        return Status;
+    }
+
+    /* Make sure we didn't go past the end of the allocation! */
+    NT_ASSERT((PUCHAR)Context.CurrentStringPointer <=
+              ((PUCHAR)NpAliases + Context.FullSize));
+
+    /* Loop all aliases we got */
+    for (i = 0; i < Context.NumberOfAliases; i++)
+    {
+        /* Get the length and check what list to use */
+        Length = CurrentAlias->Name.Length;
+        if ((Length >= MIN_INDEXED_LENGTH * sizeof(WCHAR)) &&
+            (Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR)))
+        {
+            /* For this length range, we use an indexed list */
+            AliasPointer = &NpAliasListByLength[(Length / sizeof(WCHAR)) - 5];
+        }
+        else
+        {
+            /* Length is outside of the range, use the default list */
+            AliasPointer = &NpAliasList;
+        }
+
+        /* Loop through all aliases already in the list until we find one that
+           is greater than our current alias */
+        while ((*AliasPointer != NULL) &&
+               (NpCompareAliasNames(&CurrentAlias->Name,
+                                    &(*AliasPointer)->Name) > 0))
+        {
+            /* Go to the next alias */
+            AliasPointer = &(*AliasPointer)->Next;
+        }
+
+        /* Insert the alias in the list */
+        CurrentAlias->Next = *AliasPointer;
+        *AliasPointer = CurrentAlias;
+
+        /* Go to the next alias in the array */
+        CurrentAlias++;
+    }
+
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
                      IN PIRP Irp)
 {
+    TRACE("Entered\n");
     UNIMPLEMENTED;
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
@@ -44,6 +322,13 @@
     UNREFERENCED_PARAMETER(RegistryPath);
     DPRINT1("Next-Generation NPFS-Lite\n");
+
+    Status = NpInitializeAliases();
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to initialize aliases!\n");
+        return Status;
+    }
     DriverObject->MajorFunction[IRP_MJ_CREATE] = NpFsdCreate;
     DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe;
Modified: trunk/reactos/drivers/filesystems/npfs/npfs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/npfs.h       [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/npfs.h       [iso-8859-1] Sat Feb  1 14:28:15
2014
@@ -14,8 +14,12 @@
 #include <ntifs.h>
 #include <ntndk.h>
 #include <pseh/pseh2.h>
-#define UNIMPLEMENTED
-#define DPRINT1 DbgPrint
+//#define UNIMPLEMENTED
+//#define DPRINT1 DbgPrint
+
+#define NDEBUG
+#include <debug.h>
+#define TRACE(...) /* DPRINT1("%s: ", __FUNCTION__); DbgPrint(__VA_ARGS__) */
 //
 // Allow Microsoft Extensions
@@ -25,6 +29,9 @@
 #pragma warning(disable:4214)
 #pragma warning(disable:4100)
 #endif
+
+#define MIN_INDEXED_LENGTH 5
+#define MAX_INDEXED_LENGTH 9
 /* TYPEDEFS & DEFINES *********************************************************/
@@ -326,6 +333,32 @@
 extern PNP_VCB NpVcb;
+//
+// Defines an alias
+//
+typedef struct _NPFS_ALIAS
+{
+    struct _NPFS_ALIAS *Next;
+    PUNICODE_STRING TargetName;
+    UNICODE_STRING Name;
+} NPFS_ALIAS, *PNPFS_ALIAS;
+
+//
+// Private structure used to enumerate the alias values
+//
+typedef struct _NPFS_QUERY_VALUE_CONTEXT
+{
+    BOOLEAN SizeOnly;
+    SIZE_T FullSize;
+    ULONG NumberOfAliases;
+    ULONG NumberOfEntries;
+    PNPFS_ALIAS CurrentAlias;
+    PUNICODE_STRING CurrentTargetName;
+    PWCHAR CurrentStringPointer;
+} NPFS_QUERY_VALUE_CONTEXT, *PNPFS_QUERY_VALUE_CONTEXT;
+
+extern PNPFS_ALIAS NpAliasList;
+extern PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH];
 /* FUNCTIONS ******************************************************************/
@@ -385,6 +418,12 @@
     }
 }
+LONG
+NTAPI
+NpCompareAliasNames(
+    _In_ PCUNICODE_STRING String1,
+    _In_ PCUNICODE_STRING String2);
+
 BOOLEAN
 NTAPI
 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
@@ -415,7 +454,7 @@
 NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
                     IN PNP_CCB Ccb,
                     IN PNP_DATA_QUEUE DataQueue,
-                    IN ULONG Who,
+                    IN ULONG Who,
                     IN ULONG Type,
                     IN ULONG DataSize,
                     IN PIRP Irp,
@@ -510,20 +549,20 @@
 NTSTATUS
 NTAPI
 NpSetListeningPipeState(IN PNP_CCB Ccb,
-                        IN PIRP Irp,
+                        IN PIRP Irp,
                         IN PLIST_ENTRY List);
 NTSTATUS
 NTAPI
-NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
+NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
                            IN PLIST_ENTRY List);
 NTSTATUS
 NTAPI
 NpSetClosingPipeState(IN PNP_CCB Ccb,
-                      IN PIRP Irp,
-                      IN ULONG NamedPipeEnd,
+                      IN PIRP Irp,
+                      IN ULONG NamedPipeEnd,
                       IN PLIST_ENTRY List);
 VOID
@@ -594,7 +633,7 @@
 NTAPI
 NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
             IN LARGE_INTEGER WaitTime,
-            IN PIRP Irp,
+            IN PIRP Irp,
             IN PUNICODE_STRING AliasName);
 NTSTATUS
@@ -607,27 +646,27 @@
 IO_STATUS_BLOCK
 NTAPI
-NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
+NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
                 IN BOOLEAN Peek,
                 IN BOOLEAN ReadOverflowOperation,
                 IN PVOID Buffer,
-                IN ULONG BufferSize,
-                IN ULONG Mode,
+                IN ULONG BufferSize,
+                IN ULONG Mode,
                 IN PNP_CCB Ccb,
                 IN PLIST_ENTRY List);
-NTSTATUS
+NTSTATUS
 NTAPI
 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
-                 IN ULONG Mode,
-                 IN PVOID OutBuffer,
-                 IN ULONG OutBufferSize,
-                 IN ULONG PipeType,
-                 OUT PULONG BytesWritten,
-                 IN PNP_CCB Ccb,
-                 IN ULONG NamedPipeEnd,
-                 IN PETHREAD Thread,
+                 IN ULONG Mode,
+                 IN PVOID OutBuffer,
+                 IN ULONG OutBufferSize,
+                 IN ULONG PipeType,
+                 OUT PULONG BytesWritten,
+                 IN PNP_CCB Ccb,
+                 IN ULONG NamedPipeEnd,
+                 IN PETHREAD Thread,
                  IN PLIST_ENTRY List);
 NTSTATUS
Modified: trunk/reactos/drivers/filesystems/npfs/strucsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/s…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/strucsup.c   [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/strucsup.c   [iso-8859-1] Sat Feb  1 14:28:15
2014
@@ -14,8 +14,6 @@
 #define NPFS_BUGCHECK_FILE_ID   (NPFS_BUGCHECK_STRUCSUP)
 /* GLOBALS ********************************************************************/
-
-#define UNIMPLEMENTED
 PWCHAR NpRootDCBName = L"\\";
 PNP_VCB NpVcb;
Modified: trunk/reactos/drivers/filesystems/npfs/volinfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/v…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/volinfo.c    [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/volinfo.c    [iso-8859-1] Sat Feb  1 14:28:15
2014
@@ -23,6 +23,7 @@
     PFILE_FS_VOLUME_INFORMATION InfoBuffer = Buffer;
     NTSTATUS Status;
     USHORT NameLength;
+    TRACE("Entered\n");
     *Length -= sizeof(*InfoBuffer);
@@ -47,6 +48,7 @@
     RtlCopyMemory(InfoBuffer->VolumeLabel, L"Named Pipe", NameLength);
     *Length -= NameLength;
+    TRACE("Leaving, Status = %lx\n", Status);
     return Status;
 }
@@ -56,6 +58,7 @@
                   IN OUT PULONG Length)
 {
     PFILE_FS_SIZE_INFORMATION InfoBuffer = Buffer;
+    TRACE("Entered\n");
     *Length -= sizeof(*InfoBuffer);
@@ -64,6 +67,7 @@
     InfoBuffer->SectorsPerAllocationUnit = 1;
     InfoBuffer->BytesPerSector = 1;
+    TRACE("Leaving, Status = STATUS_SUCCESS\n");
     return STATUS_SUCCESS;
 }
@@ -74,6 +78,7 @@
 {
     PFILE_FS_DEVICE_INFORMATION InfoBuffer = Buffer;
     NTSTATUS Status;
+    TRACE("Entered\n");
     if (*Length >= sizeof(*InfoBuffer))
     {
@@ -87,6 +92,7 @@
     {
         Status = STATUS_BUFFER_OVERFLOW;
     }
+    TRACE("Leaving, Status = %lx\n", Status);
     return Status;
 }
@@ -98,6 +104,7 @@
     PFILE_FS_ATTRIBUTE_INFORMATION InfoBuffer = Buffer;
     NTSTATUS Status;
     USHORT NameLength;
+    TRACE("Entered\n");
     NameLength = (USHORT)(*Length - 12);
     if (NameLength < 8)
@@ -117,6 +124,7 @@
     InfoBuffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
     RtlCopyMemory(InfoBuffer->FileSystemName, L"NPFS", NameLength);
+    TRACE("Leaving, Status = %lx\n", Status);
     return Status;
 }
@@ -126,11 +134,13 @@
                       IN OUT PULONG Length)
 {
     PFILE_FS_FULL_SIZE_INFORMATION InfoBuffer = Buffer;
+    TRACE("Entered\n");
     *Length -= sizeof(*InfoBuffer);
     RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
+    TRACE("Leaving, Status = STATUS_SUCCESS\n");
     return STATUS_SUCCESS;
 }
@@ -145,6 +155,7 @@
     PVOID Buffer;
     NTSTATUS Status;
     PAGED_CODE();
+    TRACE("Entered\n");
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     Buffer = Irp->AssociatedIrp.SystemBuffer;
@@ -174,6 +185,7 @@
     }
     Irp->IoStatus.Information = IoStack->Parameters.QueryVolume.Length - Length;
+    TRACE("Leaving, Status = %lx\n", Status);
     return Status;
 }
@@ -184,6 +196,7 @@
 {
     NTSTATUS Status;
     PAGED_CODE();
+    TRACE("Entered\n");
     FsRtlEnterFileSystem();
     ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
@@ -199,6 +212,7 @@
         IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
     }
+    TRACE("Leaving, Status = %lx\n", Status);
     return Status;
 }