[NPFS]
authorEric Kohl <eric.kohl@reactos.org>
Fri, 19 Nov 2010 22:42:53 +0000 (22:42 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Fri, 19 Nov 2010 22:42:53 +0000 (22:42 +0000)
- Rename DEVICE_EXTENSION to NPFS_VCB.
- Add a type variable to distinguish FCBs and CCBs for device, directory or pipe.
- Attach an FCB to the VCB that represents the root directory of the file system and implement an open routine for the root directory.
- Make NpfsWaitPipe work when it is called for the root directory.

[KERNEL32]
- Remove the old version of WaitNamedPipeW.

This patch fixes the broken wait pipe code. It was written and tested on r49458 because later revisions do not work for me.

svn path=/trunk/; revision=49646

reactos/dll/win32/kernel32/file/npipe.c
reactos/drivers/filesystems/npfs/create.c
reactos/drivers/filesystems/npfs/finfo.c
reactos/drivers/filesystems/npfs/fsctrl.c
reactos/drivers/filesystems/npfs/npfs.c
reactos/drivers/filesystems/npfs/npfs.h
reactos/drivers/filesystems/npfs/rw.c

index 629b69b..7112ffb 100644 (file)
@@ -14,7 +14,7 @@
 #include <debug.h>
 DEBUG_CHANNEL(kernel32file);
 
-//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+#define USING_PROPER_NPFS_WAIT_SEMANTICS
 
 /* FUNCTIONS ****************************************************************/
 
@@ -264,16 +264,6 @@ WaitNamedPipeA(LPCSTR lpNamedPipeName,
 }
 
 
-/*
- * When NPFS will work properly, use this code instead. It is compatible with
- * Microsoft's NPFS.SYS. The main difference is that:
- *      - This code actually respects the timeout instead of ignoring it!
- *      - This code validates and creates the proper names for both UNC and local pipes
- *      - On NT, you open the *root* pipe directory (either \DosDevices\Pipe or
- *        \DosDevices\Unc\Server\Pipe) and then send the pipe to wait on in the
- *        FILE_PIPE_WAIT_FOR_BUFFER structure.
- */
-#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
 /*
  * @implemented
  */
@@ -458,95 +448,6 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     /* Success */
     return TRUE;
 }
-#else
-/*
- * @implemented
- */
-BOOL
-WINAPI
-WaitNamedPipeW(LPCWSTR lpNamedPipeName,
-               DWORD nTimeOut)
-{
-    UNICODE_STRING NamedPipeName;
-    NTSTATUS Status;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    FILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
-    HANDLE FileHandle;
-    IO_STATUS_BLOCK Iosb;
-
-    if (RtlDosPathNameToNtPathName_U(lpNamedPipeName,
-                                     &NamedPipeName,
-                                     NULL,
-                                     NULL) == FALSE)
-    {
-        return FALSE;
-    }
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &NamedPipeName,
-                               OBJ_CASE_INSENSITIVE,
-                               NULL,
-                               NULL);
-    Status = NtOpenFile(&FileHandle,
-                        FILE_READ_ATTRIBUTES | SYNCHRONIZE,
-                        &ObjectAttributes,
-                        &Iosb,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE,
-                        FILE_SYNCHRONOUS_IO_NONALERT);
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastErrorByStatus(Status);
-        RtlFreeUnicodeString(&NamedPipeName);
-        return FALSE;
-    }
-
-    /* Check what timeout we got */
-    if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT)
-    {
-        /* Don't use a timeout */
-        WaitPipe.TimeoutSpecified = FALSE;
-    }
-    else
-    {
-        /* Check if we should wait forever */
-        if (nTimeOut == NMPWAIT_WAIT_FOREVER)
-        {
-            /* Set the max */
-            WaitPipe.Timeout.LowPart = 0;
-            WaitPipe.Timeout.HighPart = 0x80000000;
-        }
-        else
-        {
-            /* Convert to NT format */
-            WaitPipe.Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
-        }
-
-        /* In both cases, we do have a timeout */
-        WaitPipe.TimeoutSpecified = TRUE;
-    }
-
-    Status = NtFsControlFile(FileHandle,
-                             NULL,
-                             NULL,
-                             NULL,
-                             &Iosb,
-                             FSCTL_PIPE_WAIT,
-                             &WaitPipe,
-                             sizeof(WaitPipe),
-                             NULL,
-                             0);
-    NtClose(FileHandle);
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastErrorByStatus(Status);
-        RtlFreeUnicodeString(&NamedPipeName);
-        return FALSE;
-    }
-
-    RtlFreeUnicodeString(&NamedPipeName);
-    return TRUE;
-}
-#endif
 
 
 /*
index bef462f..0462003 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
-static PNPFS_FCB
-NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt,
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
              PUNICODE_STRING PipeName)
 {
     PLIST_ENTRY CurrentEntry;
     PNPFS_FCB Fcb;
 
-    CurrentEntry = DeviceExt->PipeListHead.Flink;
-    while (CurrentEntry != &DeviceExt->PipeListHead)
+    CurrentEntry = Vcb->PipeListHead.Flink;
+    while (CurrentEntry != &Vcb->PipeListHead)
     {
         Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, PipeListEntry);
         if (RtlCompareUnicodeString(PipeName,
@@ -103,53 +103,95 @@ NpfsSignalAndRemoveListeningServerInstance(PNPFS_FCB Fcb,
 }
 
 
+static VOID
+NpfsOpenRootDirectory(PNPFS_FCB Fcb,
+                      PFILE_OBJECT FileObject,
+                      PIO_STATUS_BLOCK IoStatus)
+{
+    PNPFS_CCB Ccb;
+
+    DPRINT("NpfsOpenRootDirectory()\n");
+
+    Ccb = ExAllocatePool(NonPagedPool, sizeof(NPFS_CCB));
+    if (Ccb == NULL)
+    {
+        IoStatus->Status = STATUS_NO_MEMORY;
+        return;
+    }
+
+    Ccb->Type = CCB_DIRECTORY;
+    Ccb->Fcb = Fcb;
+
+    FileObject->FsContext = Fcb;
+    FileObject->FsContext2 = Ccb;
+
+    IoStatus->Information = FILE_OPENED;
+    IoStatus->Status = STATUS_SUCCESS;
+
+    return;
+}
+
+
 NTSTATUS NTAPI
 NpfsCreate(PDEVICE_OBJECT DeviceObject,
            PIRP Irp)
 {
     PEXTENDED_IO_STACK_LOCATION IoStack;
+    PUNICODE_STRING FileName;
     PFILE_OBJECT FileObject;
+    PFILE_OBJECT RelatedFileObject;
     PNPFS_FCB Fcb;
     PNPFS_CCB ClientCcb;
     PNPFS_CCB ServerCcb = NULL;
-    PNPFS_DEVICE_EXTENSION DeviceExt;
-    BOOLEAN SpecialAccess;
+    PNPFS_VCB Vcb;
     ACCESS_MASK DesiredAccess;
+    NTSTATUS Status;
 
     DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
-    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
     FileObject = IoStack->FileObject;
+    RelatedFileObject = FileObject->RelatedFileObject;
+    FileName = &FileObject->FileName;
     DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+
     DPRINT("FileObject %p\n", FileObject);
     DPRINT("FileName %wZ\n", &FileObject->FileName);
 
     Irp->IoStatus.Information = 0;
 
-    SpecialAccess = ((DesiredAccess & SPECIFIC_RIGHTS_ALL) == FILE_READ_ATTRIBUTES);
-    if (SpecialAccess)
+    if (FileName->Length == 2 && FileName->Buffer[0] == L'\\' && RelatedFileObject == NULL)
     {
-        DPRINT("NpfsCreate() open client end for special use!\n");
+        DPRINT("Open the root directory\n");
+
+        NpfsOpenRootDirectory(Vcb->RootFcb,
+                              FileObject,
+                              &Irp->IoStatus);
+
+        Status = Irp->IoStatus.Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
     }
 
+
     /*
     * Step 1. Find the pipe we're trying to open.
     */
-    KeLockMutex(&DeviceExt->PipeListLock);
-    Fcb = NpfsFindPipe(DeviceExt,
+    KeLockMutex(&Vcb->PipeListLock);
+    Fcb = NpfsFindPipe(Vcb,
         &FileObject->FileName);
     if (Fcb == NULL)
     {
         /* Not found, bail out with error. */
         DPRINT("No pipe found!\n");
-        KeUnlockMutex(&DeviceExt->PipeListLock);
+        KeUnlockMutex(&Vcb->PipeListLock);
         Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_OBJECT_NAME_NOT_FOUND;
     }
 
-    KeUnlockMutex(&DeviceExt->PipeListLock);
+    KeUnlockMutex(&Vcb->PipeListLock);
 
     /*
     * Acquire the lock for CCB lists. From now on no modifications to the
@@ -170,11 +212,13 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
         return STATUS_NO_MEMORY;
     }
 
+    ClientCcb->Type = CCB_PIPE;
     ClientCcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
     ClientCcb->Fcb = Fcb;
     ClientCcb->PipeEnd = FILE_PIPE_CLIENT_END;
     ClientCcb->OtherSide = NULL;
-    ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+//    ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+    ClientCcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
     InitializeListHead(&ClientCcb->ReadRequestListHead);
 
     DPRINT("CCB: %p\n", ClientCcb);
@@ -212,9 +256,10 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
     /*
     * Step 3. Search for listening server CCB.
     */
-
+/*
     if (!SpecialAccess)
     {
+*/
         /*
         * WARNING: Point of no return! Once we get the server CCB it's
         * possible that we completed a wait request and so we have to
@@ -270,6 +315,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
             /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
             NpfsSignalAndRemoveListeningServerInstance(Fcb, ServerCcb);
         }
+/*
     }
     else if (IsListEmpty(&Fcb->ServerCcbListHead))
     {
@@ -287,6 +333,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_UNSUCCESSFUL;
     }
+*/
 
     /*
     * Step 4. Add the client CCB to a list and connect it if possible.
@@ -326,7 +373,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 {
     PEXTENDED_IO_STACK_LOCATION IoStack;
     PFILE_OBJECT FileObject;
-    PNPFS_DEVICE_EXTENSION DeviceExt;
+    PNPFS_VCB Vcb;
     PNPFS_FCB Fcb;
     PNPFS_CCB Ccb;
     PNAMED_PIPE_CREATE_PARAMETERS Buffer;
@@ -334,7 +381,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 
     DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
-    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
     FileObject = IoStack->FileObject;
     DPRINT("FileObject %p\n", FileObject);
@@ -360,13 +407,14 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         return STATUS_NO_MEMORY;
     }
 
+    Ccb->Type = CCB_PIPE;
     Ccb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
-    KeLockMutex(&DeviceExt->PipeListLock);
+    KeLockMutex(&Vcb->PipeListLock);
 
     /*
     * First search for existing Pipe with the same name.
     */
-    Fcb = NpfsFindPipe(DeviceExt,
+    Fcb = NpfsFindPipe(Vcb,
         &FileObject->FileName);
     if (Fcb != NULL)
     {
@@ -374,7 +422,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         * Found Pipe with the same name. Check if we are
         * allowed to use it.
         */
-        KeUnlockMutex(&DeviceExt->PipeListLock);
+        KeUnlockMutex(&Vcb->PipeListLock);
 
         if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
         {
@@ -402,7 +450,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
         if (Fcb == NULL)
         {
-            KeUnlockMutex(&DeviceExt->PipeListLock);
+            KeUnlockMutex(&Vcb->PipeListLock);
             ExFreePool(Ccb);
             Irp->IoStatus.Status = STATUS_NO_MEMORY;
             Irp->IoStatus.Information = 0;
@@ -410,12 +458,14 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
             return STATUS_NO_MEMORY;
         }
 
+        Fcb->Type = FCB_PIPE;
+        Fcb->Vcb = Vcb;
         Fcb->PipeName.Length = FileObject->FileName.Length;
         Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
         Fcb->PipeName.Buffer = ExAllocatePool(NonPagedPool, Fcb->PipeName.MaximumLength);
         if (Fcb->PipeName.Buffer == NULL)
         {
-            KeUnlockMutex(&DeviceExt->PipeListLock);
+            KeUnlockMutex(&Vcb->PipeListLock);
             ExFreePool(Fcb);
             ExFreePool(Ccb);
             Irp->IoStatus.Status = STATUS_NO_MEMORY;
@@ -457,18 +507,18 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         {
             if (Buffer->InboundQuota == 0)
             {
-                Fcb->InboundQuota = DeviceExt->DefaultQuota;
+                Fcb->InboundQuota = Vcb->DefaultQuota;
             }
             else
             {
                 Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
-                if (Fcb->InboundQuota < DeviceExt->MinQuota)
+                if (Fcb->InboundQuota < Vcb->MinQuota)
                 {
-                    Fcb->InboundQuota = DeviceExt->MinQuota;
+                    Fcb->InboundQuota = Vcb->MinQuota;
                 }
-                else if (Fcb->InboundQuota > DeviceExt->MaxQuota)
+                else if (Fcb->InboundQuota > Vcb->MaxQuota)
                 {
-                    Fcb->InboundQuota = DeviceExt->MaxQuota;
+                    Fcb->InboundQuota = Vcb->MaxQuota;
                 }
             }
         }
@@ -481,18 +531,18 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         {
             if (Buffer->OutboundQuota == 0)
             {
-                Fcb->OutboundQuota = DeviceExt->DefaultQuota;
+                Fcb->OutboundQuota = Vcb->DefaultQuota;
             }
             else
             {
                 Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
-                if (Fcb->OutboundQuota < DeviceExt->MinQuota)
+                if (Fcb->OutboundQuota < Vcb->MinQuota)
                 {
-                    Fcb->OutboundQuota = DeviceExt->MinQuota;
+                    Fcb->OutboundQuota = Vcb->MinQuota;
                 }
-                else if (Fcb->OutboundQuota > DeviceExt->MaxQuota)
+                else if (Fcb->OutboundQuota > Vcb->MaxQuota)
                 {
-                    Fcb->OutboundQuota = DeviceExt->MaxQuota;
+                    Fcb->OutboundQuota = Vcb->MaxQuota;
                 }
             }
         }
@@ -501,8 +551,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
             Fcb->OutboundQuota = 0;
         }
 
-        InsertTailList(&DeviceExt->PipeListHead, &Fcb->PipeListEntry);
-        KeUnlockMutex(&DeviceExt->PipeListLock);
+        InsertTailList(&Vcb->PipeListHead, &Fcb->PipeListEntry);
+        KeUnlockMutex(&Vcb->PipeListLock);
     }
 
     if (Fcb->InboundQuota)
@@ -514,9 +564,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 
             if (NewPipe)
             {
-                KeLockMutex(&DeviceExt->PipeListLock);
+                KeLockMutex(&Vcb->PipeListLock);
                 RemoveEntryList(&Fcb->PipeListEntry);
-                KeUnlockMutex(&DeviceExt->PipeListLock);
+                KeUnlockMutex(&Vcb->PipeListLock);
                 RtlFreeUnicodeString(&Fcb->PipeName);
                 ExFreePool(Fcb);
             }
@@ -573,7 +623,7 @@ NTSTATUS NTAPI
 NpfsCleanup(PDEVICE_OBJECT DeviceObject,
             PIRP Irp)
 {
-    PNPFS_DEVICE_EXTENSION DeviceExt;
+    PNPFS_VCB Vcb;
     PIO_STACK_LOCATION IoStack;
     PFILE_OBJECT FileObject;
     PNPFS_CCB Ccb, OtherSide;
@@ -583,7 +633,7 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject,
     DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
-    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     FileObject = IoStack->FileObject;
     Ccb = FileObject->FsContext2;
 
@@ -596,6 +646,15 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject,
         return STATUS_SUCCESS;
     }
 
+    if (Ccb->Type == CCB_DIRECTORY)
+    {
+        DPRINT("Cleanup the root directory!\n");
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = 0;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
     DPRINT("CCB %p\n", Ccb);
     Fcb = Ccb->Fcb;
 
@@ -708,9 +767,9 @@ NTSTATUS NTAPI
 NpfsClose(PDEVICE_OBJECT DeviceObject,
           PIRP Irp)
 {
-    PNPFS_DEVICE_EXTENSION DeviceExt;
     PIO_STACK_LOCATION IoStack;
     PFILE_OBJECT FileObject;
+    PNPFS_VCB Vcb;
     PNPFS_FCB Fcb;
     PNPFS_CCB Ccb;
     BOOLEAN Server;
@@ -718,7 +777,7 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
     DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
-    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     FileObject = IoStack->FileObject;
     Ccb = FileObject->FsContext2;
 
@@ -731,6 +790,20 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
         return STATUS_SUCCESS;
     }
 
+    if (Ccb->Type == CCB_DIRECTORY)
+    {
+        DPRINT("Closing the root directory!\n");
+
+        ExFreePool(Ccb);
+        FileObject->FsContext = NULL;
+        FileObject->FsContext2 = NULL;
+
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = 0;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
     DPRINT("CCB %p\n", Ccb);
     Fcb = Ccb->Fcb;
 
@@ -771,9 +844,9 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
         IsListEmpty(&Fcb->ClientCcbListHead))
     {
         RtlFreeUnicodeString(&Fcb->PipeName);
-        KeLockMutex(&DeviceExt->PipeListLock);
+        KeLockMutex(&Vcb->PipeListLock);
         RemoveEntryList(&Fcb->PipeListEntry);
-        KeUnlockMutex(&DeviceExt->PipeListLock);
+        KeUnlockMutex(&Vcb->PipeListLock);
         ExFreePool(Fcb);
         FileObject->FsContext = NULL;
     }
index fbb1d60..46c47c0 100644 (file)
@@ -214,7 +214,7 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
     PIO_STACK_LOCATION IoStack;
     FILE_INFORMATION_CLASS FileInformationClass;
     PFILE_OBJECT FileObject;
-    PNPFS_DEVICE_EXTENSION DeviceExtension;
+    PNPFS_VCB Vcb;
     PNPFS_FCB Fcb;
     PNPFS_CCB Ccb;
     PVOID SystemBuffer;
@@ -225,7 +225,7 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
 
     IoStack = IoGetCurrentIrpStackLocation (Irp);
     FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
-    DeviceExtension = DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     FileObject = IoStack->FileObject;
     Ccb = (PNPFS_CCB)FileObject->FsContext2;
     Fcb = Ccb->Fcb;
index 242102d..c177969 100644 (file)
@@ -293,23 +293,66 @@ NpfsWaitPipe(PIRP Irp,
              PNPFS_CCB Ccb)
 {
     PLIST_ENTRY current_entry;
+    PNPFS_VCB Vcb;
     PNPFS_FCB Fcb;
     PNPFS_CCB ServerCcb;
     PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
-    NTSTATUS Status;
     LARGE_INTEGER TimeOut;
+    UNICODE_STRING PipeName;
+    NTSTATUS Status;
 
     DPRINT("NpfsWaitPipe\n");
 
     WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
-    Fcb = Ccb->Fcb;
 
-    if (Ccb->PipeState != 0)
+    /* Fail, if the CCB does not represent the root directory */
+    if (Ccb->Type != CCB_DIRECTORY)
+        return STATUS_ILLEGAL_FUNCTION;
+
+    /* Calculate the pipe name length and allocate the buffer */
+    PipeName.Length = WaitPipe->NameLength + sizeof(WCHAR);
+    PipeName.MaximumLength = PipeName.Length + sizeof(WCHAR);
+    PipeName.Buffer = ExAllocatePool(NonPagedPool, PipeName.MaximumLength);
+    if (PipeName.Buffer == NULL)
     {
-        DPRINT("Pipe is not in passive (waiting) state!\n");
-        return STATUS_UNSUCCESSFUL;
+        DPRINT1("Could not allocate memory for the pipe name!\n");
+        return STATUS_NO_MEMORY;
     }
 
+    /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
+    PipeName.Buffer[0] = L'\\';
+    RtlCopyMemory(&PipeName.Buffer[1],
+                  &WaitPipe->Name[0],
+                  WaitPipe->NameLength);
+    PipeName.Buffer[PipeName.Length / sizeof(WCHAR)] = 0;
+
+    DPRINT("Waiting for Pipe %wZ\n", &PipeName);
+
+    /* Get the VCB */
+    Vcb = Ccb->Fcb->Vcb;
+
+    /* Lock the pipe list */
+    KeLockMutex(&Vcb->PipeListLock);
+
+    /* File a pipe with the given name */
+    Fcb = NpfsFindPipe(Vcb,
+                       &PipeName);
+
+    /* Unlock the pipe list */
+    KeUnlockMutex(&Vcb->PipeListLock);
+
+    /* Release the pipe name buffer */
+    ExFreePool(PipeName.Buffer);
+
+    /* Fail if not pipe was found */
+    if (Fcb == NULL)
+    {
+        DPRINT("No pipe found!\n", Fcb);
+        return STATUS_OBJECT_NAME_NOT_FOUND;
+    }
+
+    DPRINT("Fcb %p\n", Fcb);
+
     /* search for listening server */
     current_entry = Fcb->ServerCcbListHead.Flink;
     while (current_entry != &Fcb->ServerCcbListHead)
@@ -484,13 +527,13 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
     PIO_STACK_LOCATION IoStack;
     PFILE_OBJECT FileObject;
     NTSTATUS Status;
-    PNPFS_DEVICE_EXTENSION DeviceExt;
+    PNPFS_VCB Vcb;
     PNPFS_FCB Fcb;
     PNPFS_CCB Ccb;
 
     DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
-    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     DPRINT("IoStack: %p\n", IoStack);
     FileObject = IoStack->FileObject;
index 147f410..825abe3 100644 (file)
@@ -19,9 +19,10 @@ NTSTATUS NTAPI
 DriverEntry(PDRIVER_OBJECT DriverObject,
             PUNICODE_STRING RegistryPath)
 {
-    PNPFS_DEVICE_EXTENSION DeviceExtension;
     PDEVICE_OBJECT DeviceObject;
     UNICODE_STRING DeviceName;
+    PNPFS_VCB Vcb;
+    PNPFS_FCB Fcb;
     NTSTATUS Status;
 
     DPRINT("Named Pipe FSD 0.0.2\n");
@@ -56,7 +57,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
 
     RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
     Status = IoCreateDevice(DriverObject,
-        sizeof(NPFS_DEVICE_EXTENSION),
+        sizeof(NPFS_VCB),
         &DeviceName,
         FILE_DEVICE_NAMED_PIPE,
         0,
@@ -68,21 +69,29 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
         return Status;
     }
 
-    /* initialize the device object */
+    /* Initialize the device object */
     DeviceObject->Flags |= DO_DIRECT_IO;
     DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 
-    /* initialize the device extension */
-    DeviceExtension = DeviceObject->DeviceExtension;
-    InitializeListHead(&DeviceExtension->PipeListHead);
-    InitializeListHead(&DeviceExtension->ThreadListHead);
-    KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
-    DeviceExtension->EmptyWaiterCount = 0;
+    /* Initialize the Volume Control Block (VCB) */
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
+    InitializeListHead(&Vcb->PipeListHead);
+    InitializeListHead(&Vcb->ThreadListHead);
+    KeInitializeMutex(&Vcb->PipeListLock, 0);
+    Vcb->EmptyWaiterCount = 0;
 
     /* set the size quotas */
-    DeviceExtension->MinQuota = PAGE_SIZE;
-    DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
-    DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
+    Vcb->MinQuota = PAGE_SIZE;
+    Vcb->DefaultQuota = 8 * PAGE_SIZE;
+    Vcb->MaxQuota = 64 * PAGE_SIZE;
+
+    Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
+    Fcb->Type = FCB_DIRECTORY;
+    Fcb->Vcb = Vcb;
+
+
+
+    Vcb->RootFcb = Fcb;
 
     return STATUS_SUCCESS;
 }
index 373980c..cb37cb0 100644 (file)
@@ -4,7 +4,22 @@
 #include <ntifs.h>
 #include <ndk/iotypes.h>
 
-typedef struct _NPFS_DEVICE_EXTENSION
+typedef enum _FCB_TYPE
+{
+    FCB_DEVICE,
+    FCB_DIRECTORY,
+    FCB_PIPE
+} FCB_TYPE;
+
+typedef enum _CCB_TYPE
+{
+    CCB_DEVICE,
+    CCB_DIRECTORY,
+    CCB_PIPE
+} CCB_TYPE;
+
+/* Volume Control Block (VCB) aka Device Extension */
+typedef struct _NPFS_VCB
 {
     LIST_ENTRY PipeListHead;
     LIST_ENTRY ThreadListHead;
@@ -13,11 +28,13 @@ typedef struct _NPFS_DEVICE_EXTENSION
     ULONG MinQuota;
     ULONG DefaultQuota;
     ULONG MaxQuota;
-} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
+    struct _NPFS_FCB *RootFcb;
+} NPFS_VCB, *PNPFS_VCB;
 
 typedef struct _NPFS_FCB
 {
-    FSRTL_COMMON_FCB_HEADER RFCB;
+    FCB_TYPE Type;
+    PNPFS_VCB Vcb;
     UNICODE_STRING PipeName;
     LIST_ENTRY PipeListEntry;
     KMUTEX CcbListLock;
@@ -40,9 +57,11 @@ typedef struct _NPFS_FCB
 typedef struct _NPFS_CCB
 {
     LIST_ENTRY CcbListEntry;
+    CCB_TYPE Type;
+    PNPFS_FCB Fcb;
+
     struct _NPFS_CCB* OtherSide;
     struct ETHREAD *Thread;
-    PNPFS_FCB Fcb;
     KEVENT ConnectEvent;
     KEVENT ReadEvent;
     KEVENT WriteEvent;
@@ -71,7 +90,7 @@ typedef struct _NPFS_THREAD_CONTEXT
 {
     ULONG Count;
     KEVENT Event;
-    PNPFS_DEVICE_EXTENSION DeviceExt;
+    PNPFS_VCB Vcb;
     LIST_ENTRY ListEntry;
     PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
     KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
@@ -135,4 +154,9 @@ NTSTATUS NTAPI
 DriverEntry(PDRIVER_OBJECT DriverObject,
             PUNICODE_STRING RegistryPath);
 
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
+             PUNICODE_STRING PipeName);
+
+
 #endif /* __DRIVERS_FS_NP_NPFS_H */
index e5ef963..3c54bd7 100644 (file)
@@ -48,8 +48,8 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
                            IN PIRP Irp)
 {
     PNPFS_CONTEXT Context;
-    PNPFS_DEVICE_EXTENSION DeviceExt;
     PIO_STACK_LOCATION IoStack;
+    PNPFS_VCB Vcb;
     PNPFS_CCB Ccb;
     PLIST_ENTRY ListEntry;
     PNPFS_THREAD_CONTEXT ThreadContext;
@@ -60,17 +60,17 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
     IoReleaseCancelSpinLock(Irp->CancelIrql);
 
     Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
-    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     Ccb = IoStack->FileObject->FsContext2;
 
-    KeLockMutex(&DeviceExt->PipeListLock);
+    KeLockMutex(&Vcb->PipeListLock);
     ExAcquireFastMutex(&Ccb->DataListLock);
     switch(IoStack->MajorFunction)
     {
     case IRP_MJ_READ:
-        ListEntry = DeviceExt->ThreadListHead.Flink;
-        while (ListEntry != &DeviceExt->ThreadListHead)
+        ListEntry = Vcb->ThreadListHead.Flink;
+        while (ListEntry != &Vcb->ThreadListHead)
         {
             ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
             /* Real events start at index 1 */
@@ -92,7 +92,7 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
                     KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
 
                     ExReleaseFastMutex(&Ccb->DataListLock);
-                    KeUnlockMutex(&DeviceExt->PipeListLock);
+                    KeUnlockMutex(&Vcb->PipeListLock);
 
                     return;
                 }
@@ -103,7 +103,7 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
         RemoveEntryList(&Context->ListEntry);
 
         ExReleaseFastMutex(&Ccb->DataListLock);
-        KeUnlockMutex(&DeviceExt->PipeListLock);
+        KeUnlockMutex(&Vcb->PipeListLock);
 
         Irp->IoStatus.Status = STATUS_CANCELLED;
         Irp->IoStatus.Information = 0;
@@ -126,12 +126,12 @@ NpfsWaiterThread(PVOID InitContext)
     PIO_STACK_LOCATION IoStack = NULL;
     KIRQL OldIrql;
 
-    KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+    KeLockMutex(&ThreadContext->Vcb->PipeListLock);
 
     while (1)
     {
         CurrentCount = ThreadContext->Count;
-        KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+        KeUnlockMutex(&ThreadContext->Vcb->PipeListLock);
         IoAcquireCancelSpinLock(&OldIrql);
         if (Irp && IoSetCancelRoutine(Irp, NULL) != NULL)
         {
@@ -162,14 +162,14 @@ NpfsWaiterThread(PVOID InitContext)
         {
             ASSERT(FALSE);
         }
-        KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+        KeLockMutex(&ThreadContext->Vcb->PipeListLock);
         Count = Status - STATUS_WAIT_0;
         ASSERT (Count < CurrentCount);
         if (Count > 0)
         {
             Irp = ThreadContext->WaitIrpArray[Count];
             ThreadContext->Count--;
-            ThreadContext->DeviceExt->EmptyWaiterCount++;
+            ThreadContext->Vcb->EmptyWaiterCount++;
             ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count];
             ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count];
         }
@@ -184,18 +184,18 @@ NpfsWaiterThread(PVOID InitContext)
                 if (ThreadContext->WaitIrpArray[i] == NULL)
                 {
                    ThreadContext->Count--;
-                   ThreadContext->DeviceExt->EmptyWaiterCount++;
+                   ThreadContext->Vcb->EmptyWaiterCount++;
                    ThreadContext->WaitObjectArray[i] = ThreadContext->WaitObjectArray[ThreadContext->Count];
                    ThreadContext->WaitIrpArray[i] = ThreadContext->WaitIrpArray[ThreadContext->Count];
                 }
             }
         }
-        if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
+        if (ThreadContext->Count == 1 && ThreadContext->Vcb->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
         {
             /* it exist an other thread with empty wait slots, we can remove our thread from the list */
             RemoveEntryList(&ThreadContext->ListEntry);
-            ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
-            KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+            ThreadContext->Vcb->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
+            KeUnlockMutex(&ThreadContext->Vcb->PipeListLock);
             break;
         }
     }
@@ -208,19 +208,21 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
 {
     PLIST_ENTRY ListEntry;
     PNPFS_THREAD_CONTEXT ThreadContext = NULL;
-    NTSTATUS Status;
+    PNPFS_CONTEXT Context;
     HANDLE hThread;
+    PNPFS_VCB Vcb;
     KIRQL oldIrql;
+    NTSTATUS Status;
 
-    PNPFS_CONTEXT Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
-    PNPFS_DEVICE_EXTENSION DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
 
     DPRINT("NpfsAddWaitingReadWriteRequest(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
 
-    KeLockMutex(&DeviceExt->PipeListLock);
+    KeLockMutex(&Vcb->PipeListLock);
 
-    ListEntry = DeviceExt->ThreadListHead.Flink;
-    while (ListEntry != &DeviceExt->ThreadListHead)
+    ListEntry = Vcb->ThreadListHead.Flink;
+    while (ListEntry != &Vcb->ThreadListHead)
     {
         ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
         if (ThreadContext->Count < MAXIMUM_WAIT_OBJECTS)
@@ -229,20 +231,21 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
         }
         ListEntry = ListEntry->Flink;
     }
-    if (ListEntry == &DeviceExt->ThreadListHead)
+
+    if (ListEntry == &Vcb->ThreadListHead)
     {
         ThreadContext = ExAllocatePool(NonPagedPool, sizeof(NPFS_THREAD_CONTEXT));
         if (ThreadContext == NULL)
         {
-            KeUnlockMutex(&DeviceExt->PipeListLock);
+            KeUnlockMutex(&Vcb->PipeListLock);
             return STATUS_NO_MEMORY;
         }
-        ThreadContext->DeviceExt = DeviceExt;
+
+        ThreadContext->Vcb = Vcb;
         KeInitializeEvent(&ThreadContext->Event, SynchronizationEvent, FALSE);
         ThreadContext->Count = 1;
         ThreadContext->WaitObjectArray[0] = &ThreadContext->Event;
 
-
         DPRINT("Creating a new system thread for waiting read/write requests\n");
 
         Status = PsCreateSystemThread(&hThread,
@@ -255,11 +258,12 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
         if (!NT_SUCCESS(Status))
         {
             ExFreePool(ThreadContext);
-            KeUnlockMutex(&DeviceExt->PipeListLock);
+            KeUnlockMutex(&Vcb->PipeListLock);
             return Status;
         }
-        InsertHeadList(&DeviceExt->ThreadListHead, &ThreadContext->ListEntry);
-        DeviceExt->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
+
+        InsertHeadList(&Vcb->ThreadListHead, &ThreadContext->ListEntry);
+        Vcb->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
     }
     IoMarkIrpPending(Irp);
 
@@ -276,11 +280,11 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
         ThreadContext->WaitObjectArray[ThreadContext->Count] = Context->WaitEvent;
         ThreadContext->WaitIrpArray[ThreadContext->Count] = Irp;
         ThreadContext->Count++;
-        DeviceExt->EmptyWaiterCount--;
+        Vcb->EmptyWaiterCount--;
         KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
         Status = STATUS_SUCCESS;
     }
-    KeUnlockMutex(&DeviceExt->PipeListLock);
+    KeUnlockMutex(&Vcb->PipeListLock);
     return Status;
 }