[NPFS/KERNEL32]
[reactos.git] / reactos / drivers / filesystems / npfs / create.c
index 3be21ad..abdfe5e 100644 (file)
@@ -1,7 +1,7 @@
 /*
 * COPYRIGHT:  See COPYING in the top level directory
 * PROJECT:    ReactOS kernel
-* FILE:       drivers/fs/np/create.c
+* FILE:       drivers/filesystems/npfs/create.c
 * PURPOSE:    Named pipe filesystem
 * PROGRAMMER: David Welch <welch@cwcom.net>
 */
 
 /* FUNCTIONS *****************************************************************/
 
-static
 VOID
-NpfsDeleteFcb(PNPFS_FCB Fcb)
+NpfsDereferenceFcb(PNPFS_FCB Fcb)
 {
     PNPFS_VCB Vcb = Fcb->Vcb;
 
     KeLockMutex(&Vcb->PipeListLock);
-    RemoveEntryList(&Fcb->PipeListEntry);
+    if (InterlockedDecrement(&Fcb->RefCount) == 0)
+    {
+        DPRINT("NpfsDereferenceFcb. Deleting %p\n", Fcb);
+        RemoveEntryList(&Fcb->PipeListEntry);
+        RtlFreeUnicodeString(&Fcb->PipeName);
+        ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
+    }
     KeUnlockMutex(&Vcb->PipeListLock);
-    RtlFreeUnicodeString(&Fcb->PipeName);
-    ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
 }
 
 static
@@ -46,6 +49,7 @@ NpfsAllocateCcb(CCB_TYPE Type, PNPFS_FCB Fcb)
 
     Ccb->RefCount = 1;
     Ccb->Type = Type;
+    // FIXME: why does this function not reference Fcb?
     Ccb->Fcb = Fcb;
     Ccb->OtherSide = NULL;
 
@@ -57,7 +61,7 @@ VOID
 NpfsReferenceCcb(PNPFS_CCB Ccb)
 {
     ASSERT(Ccb->RefCount > 0);
-    InterlockedIncrement((PLONG)&Ccb->RefCount);
+    InterlockedIncrement(&Ccb->RefCount);
 }
 
 static
@@ -66,7 +70,7 @@ NpfsDereferenceCcb(PNPFS_CCB Ccb)
 {
     /* Decrement reference count */
     ASSERT(Ccb->RefCount > 0);
-    if (InterlockedDecrement((PLONG)&Ccb->RefCount) == 0)
+    if (InterlockedDecrement(&Ccb->RefCount) == 0)
     {
         /* Its zero, delete CCB */
         ExFreePoolWithTag(Ccb, TAG_NPFS_CCB);
@@ -103,6 +107,7 @@ NpfsFindPipe(PNPFS_VCB Vcb,
             TRUE) == 0)
         {
             DPRINT("<%wZ> = <%wZ>\n", PipeName, &Fcb->PipeName);
+            (VOID)InterlockedIncrement(&Fcb->RefCount);
             return Fcb;
         }
 
@@ -245,9 +250,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
     PNPFS_CCB ClientCcb;
     PNPFS_CCB ServerCcb = NULL;
     PNPFS_VCB Vcb;
-    ACCESS_MASK DesiredAccess;
     NTSTATUS Status;
 #ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+    ACCESS_MASK DesiredAccess;
     BOOLEAN SpecialAccess;
 #endif
 
@@ -258,7 +263,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
     FileObject = IoStack->FileObject;
     RelatedFileObject = FileObject->RelatedFileObject;
     FileName = &FileObject->FileName;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
     DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+#endif
 
     DPRINT("FileObject %p\n", FileObject);
     DPRINT("FileName %wZ\n", &FileObject->FileName);
@@ -337,6 +344,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
     {
         DPRINT("No memory!\n");
         KeUnlockMutex(&Fcb->CcbListLock);
+        NpfsDereferenceFcb(Fcb);
         Irp->IoStatus.Status = STATUS_NO_MEMORY;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_NO_MEMORY;
@@ -365,6 +373,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
             DPRINT("No memory!\n");
             NpfsDereferenceCcb(ClientCcb);
             KeUnlockMutex(&Fcb->CcbListLock);
+            NpfsDereferenceFcb(Fcb);
             Irp->IoStatus.Status = STATUS_NO_MEMORY;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
             return STATUS_NO_MEMORY;
@@ -437,9 +446,10 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
 
                 NpfsDereferenceCcb(ClientCcb);
                 KeUnlockMutex(&Fcb->CcbListLock);
-                Irp->IoStatus.Status = STATUS_OBJECT_PATH_NOT_FOUND;
+                NpfsDereferenceFcb(Fcb);
+                Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                return STATUS_OBJECT_PATH_NOT_FOUND;
+                return STATUS_OBJECT_NAME_NOT_FOUND;
             }
         }
         else
@@ -460,8 +470,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
         }
 
         NpfsDereferenceCcb(ClientCcb);
-
         KeUnlockMutex(&Fcb->CcbListLock);
+        NpfsDereferenceFcb(Fcb);
         Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_UNSUCCESSFUL;
@@ -509,8 +519,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
     PNPFS_VCB Vcb;
     PNPFS_FCB Fcb;
     PNPFS_CCB Ccb;
-    PNAMED_PIPE_CREATE_PARAMETERS Buffer;
-    BOOLEAN NewPipe = FALSE;
+    ULONG Disposition;
+    ULONG ShareAccess;
+    PNAMED_PIPE_CREATE_PARAMETERS Parameters;
 
     DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
@@ -520,12 +531,16 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
     DPRINT("FileObject %p\n", FileObject);
     DPRINT("Pipe name %wZ\n", &FileObject->FileName);
 
-    Buffer = IoStack->Parameters.CreatePipe.Parameters;
+    Disposition = (IoStack->Parameters.CreatePipe.Options >> 24) & 0xFF;
+    ShareAccess = IoStack->Parameters.CreatePipe.ShareAccess;
+    Parameters = IoStack->Parameters.CreatePipe.Parameters;
 
     Irp->IoStatus.Information = 0;
 
-    if (!(IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) ||
-        (IoStack->Parameters.CreatePipe.ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE)))
+    if ((Disposition == FILE_OVERWRITE) ||
+        (Disposition == FILE_OVERWRITE_IF) ||
+        !(ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) ||
+        (ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE)))
     {
         Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -549,16 +564,19 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
         {
             DPRINT("Out of instances.\n");
+            NpfsDereferenceFcb(Fcb);
             Irp->IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
             return STATUS_INSTANCE_NOT_AVAILABLE;
         }
 
-        if (Fcb->MaximumInstances != Buffer->MaximumInstances ||
-            Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart ||
-            Fcb->PipeType != Buffer->NamedPipeType)
+        if (Disposition == FILE_CREATE ||
+            Fcb->MaximumInstances != Parameters->MaximumInstances ||
+            Fcb->TimeOut.QuadPart != Parameters->DefaultTimeout.QuadPart ||
+            Fcb->PipeType != Parameters->NamedPipeType)
         {
             DPRINT("Asked for invalid pipe mode.\n");
+            NpfsDereferenceFcb(Fcb);
             Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
             return STATUS_ACCESS_DENIED;
@@ -566,7 +584,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
     }
     else
     {
-        NewPipe = TRUE;
         Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NPFS_FCB), TAG_NPFS_FCB);
         if (Fcb == NULL)
         {
@@ -579,6 +596,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 
         Fcb->Type = FCB_PIPE;
         Fcb->Vcb = Vcb;
+        Fcb->RefCount = 1;
         Fcb->PipeName.Length = FileObject->FileName.Length;
         Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
         Fcb->PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
@@ -601,13 +619,13 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         InitializeListHead(&Fcb->WaiterListHead);
         KeInitializeMutex(&Fcb->CcbListLock, 0);
 
-        Fcb->PipeType = Buffer->NamedPipeType;
-        Fcb->ServerReadMode = Buffer->ReadMode;
+        Fcb->PipeType = Parameters->NamedPipeType;
+        Fcb->ServerReadMode = Parameters->ReadMode;
         /* MSDN documentation reads that clients always start off in byte mode */
         Fcb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE;
 
-        Fcb->CompletionMode = Buffer->CompletionMode;
-        switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
+        Fcb->CompletionMode = Parameters->CompletionMode;
+        switch (ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
         {
         case FILE_SHARE_READ:
             Fcb->PipeConfiguration = FILE_PIPE_OUTBOUND;
@@ -619,19 +637,19 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
             Fcb->PipeConfiguration = FILE_PIPE_FULL_DUPLEX;
             break;
         }
-        Fcb->MaximumInstances = Buffer->MaximumInstances;
+        Fcb->MaximumInstances = Parameters->MaximumInstances;
         Fcb->CurrentInstances = 0;
-        Fcb->TimeOut = Buffer->DefaultTimeout;
+        Fcb->TimeOut = Parameters->DefaultTimeout;
         if (!(Fcb->PipeConfiguration & FILE_PIPE_OUTBOUND) ||
             Fcb->PipeConfiguration & FILE_PIPE_FULL_DUPLEX)
         {
-            if (Buffer->InboundQuota == 0)
+            if (Parameters->InboundQuota == 0)
             {
                 Fcb->InboundQuota = Vcb->DefaultQuota;
             }
             else
             {
-                Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
+                Fcb->InboundQuota = PAGE_ROUND_UP(Parameters->InboundQuota);
                 if (Fcb->InboundQuota < Vcb->MinQuota)
                 {
                     Fcb->InboundQuota = Vcb->MinQuota;
@@ -649,13 +667,13 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 
         if (Fcb->PipeConfiguration & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND))
         {
-            if (Buffer->OutboundQuota == 0)
+            if (Parameters->OutboundQuota == 0)
             {
                 Fcb->OutboundQuota = Vcb->DefaultQuota;
             }
             else
             {
-                Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
+                Fcb->OutboundQuota = PAGE_ROUND_UP(Parameters->OutboundQuota);
                 if (Fcb->OutboundQuota < Vcb->MinQuota)
                 {
                     Fcb->OutboundQuota = Vcb->MinQuota;
@@ -678,11 +696,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
     Ccb = NpfsAllocateCcb(CCB_PIPE, Fcb);
     if (Ccb == NULL)
     {
-        if (NewPipe)
-        {
-            NpfsDeleteFcb(Fcb);
-        }
-
+        NpfsDereferenceFcb(Fcb);
         Irp->IoStatus.Status = STATUS_NO_MEMORY;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_NO_MEMORY;
@@ -698,11 +712,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
         if (Ccb->Data == NULL)
         {
             NpfsDereferenceCcb(Ccb);
-
-            if (NewPipe)
-            {
-                NpfsDeleteFcb(Fcb);
-            }
+            NpfsDereferenceFcb(Fcb);
 
             Irp->IoStatus.Status = STATUS_NO_MEMORY;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -1004,12 +1014,8 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
 
     KeUnlockMutex(&Fcb->CcbListLock);
 
-    if (IsListEmpty(&Fcb->ServerCcbListHead) &&
-        IsListEmpty(&Fcb->ClientCcbListHead))
-    {
-        NpfsDeleteFcb(Fcb);
-        FileObject->FsContext = NULL;
-    }
+    NpfsDereferenceFcb(Fcb);
+    FileObject->FsContext = NULL;
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = 0;