-/* $Id: fsctrl.c,v 1.13 2003/11/13 15:26:07 ekohl Exp $
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: services/fs/np/fsctrl.c
+ * FILE: drivers/fs/np/fsctrl.c
* PURPOSE: Named pipe filesystem
* PROGRAMMER: David Welch <welch@cwcom.net>
- * Eric Kohl <ekohl@rz-online.de>
+ * Eric Kohl
*/
/* INCLUDES ******************************************************************/
-#include <ddk/ntddk.h>
-#include "npfs.h"
-
#define NDEBUG
#include <debug.h>
+#include "npfs.h"
/* FUNCTIONS *****************************************************************/
-static NTSTATUS
-NpfsConnectPipe(PNPFS_FCB Fcb)
+static VOID STDCALL
+NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PNPFS_PIPE Pipe;
- PLIST_ENTRY current_entry;
- PNPFS_FCB ClientFcb;
- NTSTATUS Status;
-
- DPRINT("NpfsConnectPipe()\n");
-
- if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
- return STATUS_PIPE_CONNECTED;
-
- if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
- return STATUS_PIPE_CLOSING;
-
- /*
- * Acceptable states are: FILE_PIPE_DISCONNECTED_STATE and
- * FILE_PIPE_LISTENING_STATE
- */
+ PNPFS_WAITER_ENTRY Waiter;
- DPRINT("Waiting for connection...\n");
+ Waiter = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
- Pipe = Fcb->Pipe;
-
- Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
-
- /* search for a listening client fcb */
-
- current_entry = Pipe->ClientFcbListHead.Flink;
- while (current_entry != &Pipe->ClientFcbListHead)
- {
- ClientFcb = CONTAINING_RECORD(current_entry,
- NPFS_FCB,
- FcbListEntry);
-
- if ((ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
- || (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
- {
- break;
- }
-
- current_entry = current_entry->Flink;
- }
-
- if ((current_entry != &Pipe->ClientFcbListHead)
- && (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE))
- {
- /* found a listening client fcb */
- DPRINT("Listening client fcb found -- connecting\n");
-
- /* connect client and server fcb's */
- Fcb->OtherSide = ClientFcb;
- ClientFcb->OtherSide = Fcb;
-
- /* set connected state */
- Fcb->PipeState = FILE_PIPE_CONNECTED_STATE;
- ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
-
- /* FIXME: create and initialize data queues */
-
- /* signal client's connect event */
- KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
-
- }
- else if ((current_entry != &Pipe->ClientFcbListHead)
- && (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
- {
- /* found a disconnected client fcb */
- DPRINT("Disconnected client fcb found - notifying client\n");
-
- /* signal client's connect event */
- KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
- }
- else
- {
- /* no listening client fcb found */
- DPRINT("No listening client fcb found -- waiting for client\n");
- Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
- UserRequest,
- KernelMode,
- FALSE,
- NULL);
+ DPRINT1("NpfsListeningCancelRoutine() called for <%wZ>\n",
+ &Waiter->Fcb->Pipe->PipeName);
- DPRINT("Finished waiting! Status: %x\n", Status);
- }
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
- DPRINT("Client Fcb: %p\n", Fcb->OtherSide);
+ KeLockMutex(&Waiter->Fcb->Pipe->FcbListLock);
+ RemoveEntryList(&Waiter->Entry);
+ KeUnlockMutex(&Waiter->Fcb->Pipe->FcbListLock);
- return STATUS_PIPE_CONNECTED;
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
static NTSTATUS
-NpfsDisconnectPipe(PNPFS_FCB Fcb)
+NpfsAddListeningServerInstance(PIRP Irp,
+ PNPFS_FCB Fcb)
{
- DPRINT("NpfsDisconnectPipe()\n");
+ PNPFS_WAITER_ENTRY Entry;
+ KIRQL oldIrql;
- if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
- return(STATUS_SUCCESS);
+ Entry = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
- if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
- {
- Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
- Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+ Entry->Fcb = Fcb;
- /* FIXME: remove data queue(s) */
+ KeLockMutex(&Fcb->Pipe->FcbListLock);
- Fcb->OtherSide->OtherSide = NULL;
- Fcb->OtherSide = NULL;
+ IoMarkIrpPending(Irp);
+ InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
- DPRINT("Pipe disconnected\n");
- return(STATUS_SUCCESS);
- }
-
- if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
+ IoAcquireCancelSpinLock(&oldIrql);
+ if (!Irp->Cancel)
{
- Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+ IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
+ IoReleaseCancelSpinLock(oldIrql);
+ KeUnlockMutex(&Fcb->Pipe->FcbListLock);
+ return STATUS_PENDING;
+ }
+ IoReleaseCancelSpinLock(oldIrql);
- /* FIXME: remove data queue(s) */
+ RemoveEntryList(&Entry->Entry);
- DPRINT("Pipe disconnected\n");
- return(STATUS_SUCCESS);
- }
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ KeUnlockMutex(&Fcb->Pipe->FcbListLock);
- return(STATUS_UNSUCCESSFUL);
+ return STATUS_CANCELLED;
}
static NTSTATUS
-NpfsWaitPipe(PIRP Irp,
- PNPFS_FCB Fcb)
+NpfsConnectPipe(PIRP Irp,
+ PNPFS_FCB Fcb)
{
PNPFS_PIPE Pipe;
PLIST_ENTRY current_entry;
- PNPFS_FCB ServerFcb;
- PNPFS_WAIT_PIPE WaitPipe;
+ PNPFS_FCB ClientFcb;
NTSTATUS Status;
- DPRINT("NpfsWaitPipe\n");
+ DPRINT("NpfsConnectPipe()\n");
+
+ if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+ {
+ KeResetEvent(&Fcb->ConnectEvent);
+ return STATUS_PIPE_CONNECTED;
+ }
+
+ if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
+ return STATUS_PIPE_CLOSING;
+
+ DPRINT("Waiting for connection...\n");
- WaitPipe = (PNPFS_WAIT_PIPE)Irp->AssociatedIrp.SystemBuffer;
Pipe = Fcb->Pipe;
- /* search for listening server */
- current_entry = Pipe->ServerFcbListHead.Flink;
- while (current_entry != &Pipe->ServerFcbListHead)
+ /* search for a listening client fcb */
+ KeLockMutex(&Pipe->FcbListLock);
+
+ current_entry = Pipe->ClientFcbListHead.Flink;
+ while (current_entry != &Pipe->ClientFcbListHead)
{
- ServerFcb = CONTAINING_RECORD(current_entry,
+ ClientFcb = CONTAINING_RECORD(current_entry,
NPFS_FCB,
FcbListEntry);
- if (ServerFcb->PipeState == FILE_PIPE_LISTENING_STATE)
- break;
+ if (ClientFcb->PipeState == 0)
+ {
+ /* found a passive (waiting) client fcb */
+ DPRINT("Passive (waiting) client fcb found -- wake the client\n");
+ KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
+ break;
+ }
- current_entry = current_entry->Flink;
- }
+#if 0
+ if (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
+ {
+ /* found a listening client fcb */
+ DPRINT("Listening client fcb found -- connecting\n");
- if (current_entry != &Pipe->ServerFcbListHead)
- {
- /* found a listening server fcb */
- DPRINT("Listening server fcb found -- connecting\n");
+ /* connect client and server fcb's */
+ Fcb->OtherSide = ClientFcb;
+ ClientFcb->OtherSide = Fcb;
- Status = STATUS_SUCCESS;
- }
- else
- {
- /* no listening server fcb found -- wait for one */
- Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
-
- Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
- UserRequest,
- KernelMode,
- FALSE,
- &WaitPipe->Timeout);
- }
-
- return(Status);
-}
+ /* set connected state */
+ Fcb->PipeState = FILE_PIPE_CONNECTED_STATE;
+ ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
+ KeUnlockMutex(&Pipe->FcbListLock);
-static NTSTATUS
-NpfsGetState(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Return current state of a pipe
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- ULONG OutputBufferLength;
- PNPFS_GET_STATE Reply;
- NTSTATUS Status;
- PNPFS_PIPE Pipe;
- PNPFS_FCB Fcb;
+ /* FIXME: create and initialize data queues */
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+ /* signal client's connect event */
+ DPRINT("Setting the ConnectEvent for %x\n", ClientFcb);
+ KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
- /* Validate parameters */
- if (OutputBufferLength >= sizeof(NPFS_GET_STATE))
- {
- Fcb = IrpSp->FileObject->FsContext;
- Reply = (PNPFS_GET_STATE)Irp->AssociatedIrp.SystemBuffer;
- Pipe = Fcb->Pipe;
+ return STATUS_PIPE_CONNECTED;
+ }
+#endif
- if (Pipe->PipeWriteMode == FILE_PIPE_MESSAGE_MODE)
- {
- Reply->WriteModeMessage = TRUE;
- }
- else
- {
- Reply->WriteModeMessage = FALSE;
+ current_entry = current_entry->Flink;
}
- if (Pipe->PipeReadMode == FILE_PIPE_MESSAGE_MODE)
- {
- Reply->ReadModeMessage = TRUE;
- }
- else
- {
- Reply->ReadModeMessage = FALSE;
- }
+ /* no listening client fcb found */
+ DPRINT("No listening client fcb found -- waiting for client\n");
- if (Pipe->PipeBlockMode == FILE_PIPE_QUEUE_OPERATION)
- {
- Reply->NonBlocking = TRUE;
- }
- else
- {
- Reply->NonBlocking = FALSE;
- }
+ Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
+
+ Status = NpfsAddListeningServerInstance(Irp, Fcb);
+
+ KeUnlockMutex(&Pipe->FcbListLock);
- Reply->InBufferSize = Pipe->InboundQuota;
+ DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
- Reply->OutBufferSize = Pipe->OutboundQuota;
+ return Status;
+}
- Reply->Timeout = Pipe->TimeOut;
- Status = STATUS_SUCCESS;
- }
- else
- {
- Status = STATUS_INVALID_PARAMETER;
- }
+static NTSTATUS
+NpfsDisconnectPipe(PNPFS_FCB Fcb)
+{
+ NTSTATUS Status;
+ PNPFS_FCB OtherSide;
+ PNPFS_PIPE Pipe;
+ BOOLEAN Server;
- DPRINT("Status (0x%X).\n", Status);
+ DPRINT("NpfsDisconnectPipe()\n");
- return Status;
+ Pipe = Fcb->Pipe;
+ KeLockMutex(&Pipe->FcbListLock);
+
+ if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
+ {
+ DPRINT("Pipe is already disconnected\n");
+ Status = STATUS_SUCCESS;
+ }
+ else if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+ {
+ Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
+ OtherSide = Fcb->OtherSide;
+ Fcb->OtherSide = NULL;
+ Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+ /* Lock the server first */
+ if (Server)
+ {
+ ExAcquireFastMutex(&Fcb->DataListLock);
+ ExAcquireFastMutex(&OtherSide->DataListLock);
+ }
+ else
+ {
+ ExAcquireFastMutex(&OtherSide->DataListLock);
+ ExAcquireFastMutex(&Fcb->DataListLock);
+ }
+ OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+ OtherSide->OtherSide = NULL;
+ /*
+ * Signaling the write event. If is possible that an other
+ * thread waits for an empty buffer.
+ */
+ KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
+ KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+ if (Server)
+ {
+ ExReleaseFastMutex(&Fcb->DataListLock);
+ ExReleaseFastMutex(&OtherSide->DataListLock);
+ }
+ else
+ {
+ ExReleaseFastMutex(&OtherSide->DataListLock);
+ ExReleaseFastMutex(&OtherSide->DataListLock);
+ }
+ Status = STATUS_SUCCESS;
+ }
+ else if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
+ {
+ PLIST_ENTRY Entry;
+ PNPFS_WAITER_ENTRY WaitEntry = NULL;
+ BOOLEAN Complete = FALSE;
+ PIRP Irp = NULL;
+
+ Entry = Fcb->Pipe->WaiterListHead.Flink;
+ while (Entry != &Fcb->Pipe->WaiterListHead)
+ {
+ WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
+ if (WaitEntry->Fcb == Fcb)
+ {
+ RemoveEntryList(Entry);
+ Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
+ Complete = (NULL == IoSetCancelRoutine(Irp, NULL));
+ break;
+ }
+ Entry = Entry->Flink;
+ }
+
+ if (Irp)
+ {
+ if (Complete)
+ {
+ Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+ }
+ Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+ Status = STATUS_SUCCESS;
+ }
+ else if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
+ {
+ Status = STATUS_PIPE_CLOSING;
+ }
+ else
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ KeUnlockMutex(&Pipe->FcbListLock);
+ return Status;
}
static NTSTATUS
-NpfsSetState(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Set state of a pipe
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
+NpfsWaitPipe(PIRP Irp,
+ PNPFS_FCB Fcb)
{
- ULONG InputBufferLength;
- PNPFS_SET_STATE Request;
PNPFS_PIPE Pipe;
+ PLIST_ENTRY current_entry;
+ PNPFS_FCB ServerFcb;
+ PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
NTSTATUS Status;
- PNPFS_FCB Fcb;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- /* Validate parameters */
- if (InputBufferLength >= sizeof(NPFS_SET_STATE))
- {
- Fcb = IrpSp->FileObject->FsContext;
- Request = (PNPFS_SET_STATE)Irp->AssociatedIrp.SystemBuffer;
- Pipe = Fcb->Pipe;
+ DPRINT("NpfsWaitPipe\n");
- if (Request->WriteModeMessage)
- {
- Pipe->PipeWriteMode = FILE_PIPE_MESSAGE_MODE;
- }
- else
- {
- Pipe->PipeWriteMode = FILE_PIPE_BYTE_STREAM_MODE;
- }
+ WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+ Pipe = Fcb->Pipe;
- if (Request->ReadModeMessage)
- {
- Pipe->PipeReadMode = FILE_PIPE_MESSAGE_MODE;
- }
- else
+ if (Fcb->PipeState != 0)
{
- Pipe->PipeReadMode = FILE_PIPE_BYTE_STREAM_MODE;
+ DPRINT("Pipe is not in passive (waiting) state!\n");
+ return STATUS_UNSUCCESSFUL;
}
- if (Request->NonBlocking)
- {
- Pipe->PipeBlockMode = FILE_PIPE_QUEUE_OPERATION;
- }
- else
+ /* search for listening server */
+ current_entry = Pipe->ServerFcbListHead.Flink;
+ while (current_entry != &Pipe->ServerFcbListHead)
{
- Pipe->PipeBlockMode = FILE_PIPE_COMPLETE_OPERATION;
- }
+ ServerFcb = CONTAINING_RECORD(current_entry,
+ NPFS_FCB,
+ FcbListEntry);
- Pipe->InboundQuota = Request->InBufferSize;
+ if (ServerFcb->PipeState == FILE_PIPE_LISTENING_STATE)
+ {
+ /* found a listening server fcb */
+ DPRINT("Listening server fcb found -- connecting\n");
- Pipe->OutboundQuota = Request->OutBufferSize;
+ return STATUS_SUCCESS;
+ }
- Pipe->TimeOut = Request->Timeout;
+ current_entry = current_entry->Flink;
+ }
- Status = STATUS_SUCCESS;
- }
- else
- {
- Status = STATUS_INVALID_PARAMETER;
- }
+ /* no listening server fcb found -- wait for one */
+ Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
+ UserRequest,
+ KernelMode,
+ FALSE,
+ &WaitPipe->Timeout);
- DPRINT("Status (0x%X).\n", Status);
+ DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
return Status;
}
-static NTSTATUS
-NpfsPeekPipe(PIRP Irp,
- PIO_STACK_LOCATION IoStack)
+/*
+ * FUNCTION: Return current state of a pipe
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+
/*
* FUNCTION: Peek at a pipe (get information about messages)
* ARGUMENTS:
* RETURNS:
* Status of operation
*/
+static NTSTATUS
+NpfsPeekPipe(PIRP Irp,
+ PIO_STACK_LOCATION IoStack)
{
ULONG OutputBufferLength;
PNPFS_PIPE Pipe;
if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
{
DPRINT("Buffer too small\n");
- return(STATUS_INVALID_PARAMETER);
+ return STATUS_INVALID_PARAMETER;
}
Fcb = IoStack->FileObject->FsContext;
Status = STATUS_NOT_IMPLEMENTED;
- return(Status);
+ return Status;
}
-
NTSTATUS STDCALL
NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PEXTENDED_IO_STACK_LOCATION IoStack;
+ PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PNPFS_DEVICE_EXTENSION DeviceExt;
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- IoStack = (PEXTENDED_IO_STACK_LOCATION) IoGetCurrentIrpStackLocation(Irp);
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;
DPRINT("FileObject: %p\n", FileObject);
DPRINT("Pipe: %p\n", Pipe);
DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
+ Irp->IoStatus.Information = 0;
+
switch (IoStack->Parameters.FileSystemControl.FsControlCode)
{
case FSCTL_PIPE_ASSIGN_EVENT:
case FSCTL_PIPE_LISTEN:
DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
- Status = NpfsConnectPipe(Fcb);
+ Status = NpfsConnectPipe(Irp, Fcb);
break;
case FSCTL_PIPE_PEEK:
Status = STATUS_NOT_IMPLEMENTED;
break;
- case FSCTL_PIPE_GET_STATE:
- DPRINT("Get state\n");
- Status = NpfsGetState(Irp, (PIO_STACK_LOCATION)IoStack);
- break;
-
- case FSCTL_PIPE_SET_STATE:
- DPRINT("Set state\n");
- Status = NpfsSetState(Irp, (PIO_STACK_LOCATION)IoStack);
- break;
-
case FSCTL_PIPE_INTERNAL_READ:
DPRINT("Internal read\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
- DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
+ DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.FsControlCode);
Status = STATUS_UNSUCCESSFUL;
}
- Irp->IoStatus.Status = Status;
+ if (Status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return Status;
+}
+
+
+NTSTATUS STDCALL
+NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ /* FIXME: Implement */
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(Status);
+ return STATUS_SUCCESS;
}
/* EOF */