- Fix formatting

svn path=/trunk/; revision=39477
This commit is contained in:
Michael Martin 2009-02-08 09:04:42 +00:00
parent 5b794bd721
commit c15c8ae183
7 changed files with 2214 additions and 2215 deletions

File diff suppressed because it is too large Load diff

View file

@ -18,287 +18,286 @@
static
NTSTATUS
NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_CCB Ccb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
PNPFS_CCB Ccb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_FCB Fcb;
PFILE_PIPE_INFORMATION Request;
DPRINT("NpfsSetPipeInformation()\n");
PNPFS_FCB Fcb;
PFILE_PIPE_INFORMATION Request;
DPRINT("NpfsSetPipeInformation()\n");
/* Get the Pipe and data */
Fcb = Ccb->Fcb;
Request = (PFILE_PIPE_INFORMATION)Info;
/* Get the Pipe and data */
Fcb = Ccb->Fcb;
Request = (PFILE_PIPE_INFORMATION)Info;
if ((Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE) && (Request->ReadMode == FILE_PIPE_MESSAGE_MODE))
{
DPRINT("Cannot change readmode to message type on a byte type pipe!\n");
return STATUS_ACCESS_DENIED;
}
/* Set Pipe Data */
if (Ccb->PipeEnd == FILE_PIPE_CLIENT_END)
{
Fcb->ClientReadMode = Request->ReadMode;
}
else
{
Fcb->ServerReadMode = Request->ReadMode;
}
if ((Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE) && (Request->ReadMode == FILE_PIPE_MESSAGE_MODE))
{
DPRINT("Cannot change readmode to message type on a byte type pipe!\n");
return STATUS_ACCESS_DENIED;
}
Fcb->CompletionMode = Request->CompletionMode;
/* Set Pipe Data */
if (Ccb->PipeEnd == FILE_PIPE_CLIENT_END)
{
Fcb->ClientReadMode = Request->ReadMode;
}
else
{
Fcb->ServerReadMode = Request->ReadMode;
}
/* Return Success */
return STATUS_SUCCESS;
Fcb->CompletionMode = Request->CompletionMode;
/* Return Success */
return STATUS_SUCCESS;
}
static
NTSTATUS
NpfsSetPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_CCB Ccb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
PNPFS_CCB Ccb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_FCB Fcb;
PFILE_PIPE_REMOTE_INFORMATION Request;
DPRINT("NpfsSetPipeRemoteInformation()\n");
PNPFS_FCB Fcb;
PFILE_PIPE_REMOTE_INFORMATION Request;
DPRINT("NpfsSetPipeRemoteInformation()\n");
/* Get the Pipe and data */
Fcb = Ccb->Fcb;
Request = (PFILE_PIPE_REMOTE_INFORMATION)Info;
/* Get the Pipe and data */
Fcb = Ccb->Fcb;
Request = (PFILE_PIPE_REMOTE_INFORMATION)Info;
/* Set the Settings */
Fcb->TimeOut = Request->CollectDataTime;
Fcb->InboundQuota = Request->MaximumCollectionCount;
/* Set the Settings */
Fcb->TimeOut = Request->CollectDataTime;
Fcb->InboundQuota = Request->MaximumCollectionCount;
/* Return Success */
return STATUS_SUCCESS;
/* Return Success */
return STATUS_SUCCESS;
}
static
NTSTATUS
NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_CCB Ccb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
PNPFS_CCB Ccb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_FCB Fcb;
ULONG ConnectionSideReadMode;
DPRINT("NpfsQueryPipeInformation()\n");
PNPFS_FCB Fcb;
ULONG ConnectionSideReadMode;
DPRINT("NpfsQueryPipeInformation()\n");
/* Get the Pipe */
Fcb = Ccb->Fcb;
/* Get the Pipe */
Fcb = Ccb->Fcb;
/* Clear Info */
RtlZeroMemory(Info, sizeof(FILE_PIPE_INFORMATION));
/* Clear Info */
RtlZeroMemory(Info, sizeof(FILE_PIPE_INFORMATION));
if (Ccb->PipeEnd == FILE_PIPE_CLIENT_END) ConnectionSideReadMode=Ccb->Fcb->ClientReadMode;
else ConnectionSideReadMode = Ccb->Fcb->ServerReadMode;
if (Ccb->PipeEnd == FILE_PIPE_CLIENT_END) ConnectionSideReadMode=Ccb->Fcb->ClientReadMode;
else ConnectionSideReadMode = Ccb->Fcb->ServerReadMode;
/* Return Info */
Info->CompletionMode = Fcb->CompletionMode;
Info->ReadMode = ConnectionSideReadMode;
/* Return Info */
Info->CompletionMode = Fcb->CompletionMode;
Info->ReadMode = ConnectionSideReadMode;
/* Return success */
*BufferLength -= sizeof(FILE_PIPE_INFORMATION);
return STATUS_SUCCESS;
/* Return success */
*BufferLength -= sizeof(FILE_PIPE_INFORMATION);
return STATUS_SUCCESS;
}
static
NTSTATUS
NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_CCB Ccb,
PFILE_PIPE_REMOTE_INFORMATION Info,
PULONG BufferLength)
PNPFS_CCB Ccb,
PFILE_PIPE_REMOTE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_FCB Fcb;
DPRINT("NpfsQueryPipeRemoteInformation()\n");
PNPFS_FCB Fcb;
DPRINT("NpfsQueryPipeRemoteInformation()\n");
/* Get the Pipe */
Fcb = Ccb->Fcb;
/* Get the Pipe */
Fcb = Ccb->Fcb;
/* Clear Info */
RtlZeroMemory(Info, sizeof(FILE_PIPE_REMOTE_INFORMATION));
/* Clear Info */
RtlZeroMemory(Info, sizeof(FILE_PIPE_REMOTE_INFORMATION));
/* Return Info */
Info->MaximumCollectionCount = Fcb->InboundQuota;
Info->CollectDataTime = Fcb->TimeOut;
/* Return Info */
Info->MaximumCollectionCount = Fcb->InboundQuota;
Info->CollectDataTime = Fcb->TimeOut;
/* Return success */
*BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION);
return STATUS_SUCCESS;
/* Return success */
*BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION);
return STATUS_SUCCESS;
}
static NTSTATUS
NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_CCB Ccb,
PFILE_PIPE_LOCAL_INFORMATION Info,
PULONG BufferLength)
PNPFS_CCB Ccb,
PFILE_PIPE_LOCAL_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_FCB Fcb;
PNPFS_FCB Fcb;
DPRINT("NpfsQueryLocalPipeInformation()\n");
DPRINT("NpfsQueryLocalPipeInformation()\n");
Fcb = Ccb->Fcb;
Fcb = Ccb->Fcb;
RtlZeroMemory(Info,
sizeof(FILE_PIPE_LOCAL_INFORMATION));
RtlZeroMemory(Info,
sizeof(FILE_PIPE_LOCAL_INFORMATION));
Info->NamedPipeType = Fcb->PipeType;
Info->NamedPipeConfiguration = Fcb->PipeConfiguration;
Info->MaximumInstances = Fcb->MaximumInstances;
Info->CurrentInstances = Fcb->CurrentInstances;
Info->InboundQuota = Fcb->InboundQuota;
Info->OutboundQuota = Fcb->OutboundQuota;
Info->NamedPipeState = Ccb->PipeState;
Info->NamedPipeEnd = Ccb->PipeEnd;
Info->NamedPipeType = Fcb->PipeType;
Info->NamedPipeConfiguration = Fcb->PipeConfiguration;
Info->MaximumInstances = Fcb->MaximumInstances;
Info->CurrentInstances = Fcb->CurrentInstances;
Info->InboundQuota = Fcb->InboundQuota;
Info->OutboundQuota = Fcb->OutboundQuota;
Info->NamedPipeState = Ccb->PipeState;
Info->NamedPipeEnd = Ccb->PipeEnd;
if (Ccb->PipeEnd == FILE_PIPE_SERVER_END)
{
Info->ReadDataAvailable = Ccb->ReadDataAvailable;
Info->WriteQuotaAvailable = Ccb->WriteQuotaAvailable;
}
else if (Ccb->OtherSide != NULL)
{
Info->ReadDataAvailable = Ccb->OtherSide->ReadDataAvailable;
Info->WriteQuotaAvailable = Ccb->OtherSide->WriteQuotaAvailable;
}
if (Ccb->PipeEnd == FILE_PIPE_SERVER_END)
{
Info->ReadDataAvailable = Ccb->ReadDataAvailable;
Info->WriteQuotaAvailable = Ccb->WriteQuotaAvailable;
}
else if (Ccb->OtherSide != NULL)
{
Info->ReadDataAvailable = Ccb->OtherSide->ReadDataAvailable;
Info->WriteQuotaAvailable = Ccb->OtherSide->WriteQuotaAvailable;
}
*BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION);
return STATUS_SUCCESS;
*BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject;
PNPFS_DEVICE_EXTENSION DeviceExtension;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PVOID SystemBuffer;
ULONG BufferLength;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject;
PNPFS_DEVICE_EXTENSION DeviceExtension;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PVOID SystemBuffer;
ULONG BufferLength;
NTSTATUS Status;
DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
DeviceExtension = DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = (PNPFS_CCB)FileObject->FsContext2;
Fcb = Ccb->Fcb;
IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
DeviceExtension = DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = (PNPFS_CCB)FileObject->FsContext2;
Fcb = Ccb->Fcb;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = IoStack->Parameters.QueryFile.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = IoStack->Parameters.QueryFile.Length;
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("BufferLength %lu\n", BufferLength);
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("BufferLength %lu\n", BufferLength);
switch (FileInformationClass)
{
case FilePipeInformation:
Status = NpfsQueryPipeInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
switch (FileInformationClass)
{
case FilePipeInformation:
Status = NpfsQueryPipeInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
case FilePipeLocalInformation:
Status = NpfsQueryLocalPipeInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
case FilePipeLocalInformation:
Status = NpfsQueryLocalPipeInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
case FilePipeRemoteInformation:
Status = NpfsQueryPipeRemoteInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
case FilePipeRemoteInformation:
Status = NpfsQueryPipeRemoteInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
default:
Status = STATUS_NOT_SUPPORTED;
}
default:
Status = STATUS_NOT_SUPPORTED;
}
Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
IoStack->Parameters.QueryFile.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
IoStack->Parameters.QueryFile.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Status;
return Status;
}
NTSTATUS NTAPI
NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PVOID SystemBuffer;
ULONG BufferLength;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PVOID SystemBuffer;
ULONG BufferLength;
NTSTATUS Status;
DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
FileObject = IoStack->FileObject;
Ccb = (PNPFS_CCB)FileObject->FsContext2;
Fcb = Ccb->Fcb;
IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
FileObject = IoStack->FileObject;
Ccb = (PNPFS_CCB)FileObject->FsContext2;
Fcb = Ccb->Fcb;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = IoStack->Parameters.QueryFile.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = IoStack->Parameters.QueryFile.Length;
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("BufferLength %lu\n", BufferLength);
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("BufferLength %lu\n", BufferLength);
switch (FileInformationClass)
{
case FilePipeInformation:
/* Call the handler */
Status = NpfsSetPipeInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
switch (FileInformationClass)
{
case FilePipeInformation:
/* Call the handler */
Status = NpfsSetPipeInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
case FilePipeLocalInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FilePipeLocalInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FilePipeRemoteInformation:
/* Call the handler */
Status = NpfsSetPipeRemoteInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
default:
Status = STATUS_NOT_SUPPORTED;
}
case FilePipeRemoteInformation:
/* Call the handler */
Status = NpfsSetPipeRemoteInformation(DeviceObject,
Ccb,
SystemBuffer,
&BufferLength);
break;
default:
Status = STATUS_NOT_SUPPORTED;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
/* EOF */

View file

@ -20,326 +20,326 @@
static DRIVER_CANCEL NpfsListeningCancelRoutine;
static VOID NTAPI
NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
IN PIRP Irp)
{
PNPFS_WAITER_ENTRY Waiter;
PNPFS_WAITER_ENTRY Waiter;
Waiter = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
Waiter = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
&Waiter->Ccb->Fcb->PipeName);
DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
&Waiter->Ccb->Fcb->PipeName);
IoReleaseCancelSpinLock(Irp->CancelIrql);
IoReleaseCancelSpinLock(Irp->CancelIrql);
KeLockMutex(&Waiter->Ccb->Fcb->CcbListLock);
RemoveEntryList(&Waiter->Entry);
KeUnlockMutex(&Waiter->Ccb->Fcb->CcbListLock);
KeLockMutex(&Waiter->Ccb->Fcb->CcbListLock);
RemoveEntryList(&Waiter->Entry);
KeUnlockMutex(&Waiter->Ccb->Fcb->CcbListLock);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
static NTSTATUS
NpfsAddListeningServerInstance(PIRP Irp,
PNPFS_CCB Ccb)
PNPFS_CCB Ccb)
{
PNPFS_WAITER_ENTRY Entry;
KIRQL oldIrql;
PNPFS_WAITER_ENTRY Entry;
KIRQL oldIrql;
Entry = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
Entry = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
Entry->Ccb = Ccb;
Entry->Ccb = Ccb;
KeLockMutex(&Ccb->Fcb->CcbListLock);
KeLockMutex(&Ccb->Fcb->CcbListLock);
IoMarkIrpPending(Irp);
InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
IoMarkIrpPending(Irp);
InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
IoAcquireCancelSpinLock(&oldIrql);
if (!Irp->Cancel)
{
(void)IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
IoReleaseCancelSpinLock(oldIrql);
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
return STATUS_PENDING;
}
IoReleaseCancelSpinLock(oldIrql);
IoAcquireCancelSpinLock(&oldIrql);
if (!Irp->Cancel)
{
(void)IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
IoReleaseCancelSpinLock(oldIrql);
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
return STATUS_PENDING;
}
IoReleaseCancelSpinLock(oldIrql);
RemoveEntryList(&Entry->Entry);
RemoveEntryList(&Entry->Entry);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
return STATUS_CANCELLED;
return STATUS_CANCELLED;
}
static NTSTATUS
NpfsConnectPipe(PIRP Irp,
PNPFS_CCB Ccb)
PNPFS_CCB Ccb)
{
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
ULONG Flags;
PLIST_ENTRY current_entry;
PNPFS_FCB Fcb;
PNPFS_CCB ClientCcb;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
ULONG Flags;
PLIST_ENTRY current_entry;
PNPFS_FCB Fcb;
PNPFS_CCB ClientCcb;
NTSTATUS Status;
DPRINT("NpfsConnectPipe()\n");
DPRINT("NpfsConnectPipe()\n");
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
KeResetEvent(&Ccb->ConnectEvent);
return STATUS_PIPE_CONNECTED;
}
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
KeResetEvent(&Ccb->ConnectEvent);
return STATUS_PIPE_CONNECTED;
}
if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
return STATUS_PIPE_CLOSING;
if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
return STATUS_PIPE_CLOSING;
DPRINT("Waiting for connection...\n");
DPRINT("Waiting for connection...\n");
Fcb = Ccb->Fcb;
IoStack = IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
Flags = FileObject->Flags;
Fcb = Ccb->Fcb;
IoStack = IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
Flags = FileObject->Flags;
/* search for a listening client fcb */
KeLockMutex(&Fcb->CcbListLock);
/* search for a listening client fcb */
KeLockMutex(&Fcb->CcbListLock);
current_entry = Fcb->ClientCcbListHead.Flink;
while (current_entry != &Fcb->ClientCcbListHead)
{
ClientCcb = CONTAINING_RECORD(current_entry,
NPFS_CCB,
CcbListEntry);
current_entry = Fcb->ClientCcbListHead.Flink;
while (current_entry != &Fcb->ClientCcbListHead)
{
ClientCcb = CONTAINING_RECORD(current_entry,
NPFS_CCB,
CcbListEntry);
if (ClientCcb->PipeState == 0)
{
/* found a passive (waiting) client CCB */
DPRINT("Passive (waiting) client CCB found -- wake the client\n");
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
break;
}
if (ClientCcb->PipeState == 0)
{
/* found a passive (waiting) client CCB */
DPRINT("Passive (waiting) client CCB found -- wake the client\n");
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
break;
}
#if 0
if (ClientCcb->PipeState == FILE_PIPE_LISTENING_STATE)
{
/* found a listening client CCB */
DPRINT("Listening client CCB found -- connecting\n");
if (ClientCcb->PipeState == FILE_PIPE_LISTENING_STATE)
{
/* found a listening client CCB */
DPRINT("Listening client CCB found -- connecting\n");
/* connect client and server CCBs */
Ccb->OtherSide = ClientCcb;
ClientCcb->OtherSide = Ccb;
/* connect client and server CCBs */
Ccb->OtherSide = ClientCcb;
ClientCcb->OtherSide = Ccb;
/* set connected state */
Ccb->PipeState = FILE_PIPE_CONNECTED_STATE;
ClientCcb->PipeState = FILE_PIPE_CONNECTED_STATE;
/* set connected state */
Ccb->PipeState = FILE_PIPE_CONNECTED_STATE;
ClientCcb->PipeState = FILE_PIPE_CONNECTED_STATE;
KeUnlockMutex(&Fcb->CcbListLock);
KeUnlockMutex(&Fcb->CcbListLock);
/* FIXME: create and initialize data queues */
/* FIXME: create and initialize data queues */
/* signal client's connect event */
DPRINT("Setting the ConnectEvent for %x\n", ClientCcb);
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
/* signal client's connect event */
DPRINT("Setting the ConnectEvent for %x\n", ClientCcb);
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
return STATUS_PIPE_CONNECTED;
}
return STATUS_PIPE_CONNECTED;
}
#endif
current_entry = current_entry->Flink;
}
current_entry = current_entry->Flink;
}
/* no listening client fcb found */
DPRINT("No listening client fcb found -- waiting for client\n");
/* no listening client fcb found */
DPRINT("No listening client fcb found -- waiting for client\n");
Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
Status = NpfsAddListeningServerInstance(Irp, Ccb);
Status = NpfsAddListeningServerInstance(Irp, Ccb);
KeUnlockMutex(&Fcb->CcbListLock);
KeUnlockMutex(&Fcb->CcbListLock);
if (Flags & FO_SYNCHRONOUS_IO)
{
KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest,
Irp->RequestorMode,
FALSE,
NULL);
}
if (Flags & FO_SYNCHRONOUS_IO)
{
KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest,
Irp->RequestorMode,
FALSE,
NULL);
}
DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
return Status;
return Status;
}
static NTSTATUS
NpfsDisconnectPipe(PNPFS_CCB Ccb)
{
NTSTATUS Status;
PNPFS_FCB Fcb;
PNPFS_CCB OtherSide;
BOOLEAN Server;
NTSTATUS Status;
PNPFS_FCB Fcb;
PNPFS_CCB OtherSide;
BOOLEAN Server;
DPRINT("NpfsDisconnectPipe()\n");
DPRINT("NpfsDisconnectPipe()\n");
Fcb = Ccb->Fcb;
KeLockMutex(&Fcb->CcbListLock);
Fcb = Ccb->Fcb;
KeLockMutex(&Fcb->CcbListLock);
if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
{
DPRINT("Pipe is already disconnected\n");
Status = STATUS_SUCCESS;
}
else if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
OtherSide = Ccb->OtherSide;
//Ccb->OtherSide = NULL;
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
/* Lock the server first */
if (Server)
{
ExAcquireFastMutex(&Ccb->DataListLock);
ExAcquireFastMutex(&OtherSide->DataListLock);
}
else
{
ExAcquireFastMutex(&OtherSide->DataListLock);
ExAcquireFastMutex(&Ccb->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(&OtherSide->DataListLock);
ExReleaseFastMutex(&Ccb->DataListLock);
}
else
{
ExReleaseFastMutex(&Ccb->DataListLock);
ExReleaseFastMutex(&OtherSide->DataListLock);
}
Status = STATUS_SUCCESS;
}
else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
{
PLIST_ENTRY Entry;
PNPFS_WAITER_ENTRY WaitEntry = NULL;
BOOLEAN Complete = FALSE;
PIRP Irp = NULL;
if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
{
DPRINT("Pipe is already disconnected\n");
Status = STATUS_SUCCESS;
}
else if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
OtherSide = Ccb->OtherSide;
//Ccb->OtherSide = NULL;
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
/* Lock the server first */
if (Server)
{
ExAcquireFastMutex(&Ccb->DataListLock);
ExAcquireFastMutex(&OtherSide->DataListLock);
}
else
{
ExAcquireFastMutex(&OtherSide->DataListLock);
ExAcquireFastMutex(&Ccb->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(&OtherSide->DataListLock);
ExReleaseFastMutex(&Ccb->DataListLock);
}
else
{
ExReleaseFastMutex(&Ccb->DataListLock);
ExReleaseFastMutex(&OtherSide->DataListLock);
}
Status = STATUS_SUCCESS;
}
else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
{
PLIST_ENTRY Entry;
PNPFS_WAITER_ENTRY WaitEntry = NULL;
BOOLEAN Complete = FALSE;
PIRP Irp = NULL;
Entry = Ccb->Fcb->WaiterListHead.Flink;
while (Entry != &Ccb->Fcb->WaiterListHead)
{
WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
if (WaitEntry->Ccb == Ccb)
{
RemoveEntryList(Entry);
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
Complete = (NULL == IoSetCancelRoutine(Irp, NULL));
break;
}
Entry = Entry->Flink;
}
Entry = Ccb->Fcb->WaiterListHead.Flink;
while (Entry != &Ccb->Fcb->WaiterListHead)
{
WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
if (WaitEntry->Ccb == Ccb)
{
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);
}
}
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
Status = STATUS_SUCCESS;
}
else if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
{
Status = STATUS_PIPE_CLOSING;
}
else
{
Status = STATUS_UNSUCCESSFUL;
}
KeUnlockMutex(&Fcb->CcbListLock);
return Status;
if (Irp)
{
if (Complete)
{
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
Status = STATUS_SUCCESS;
}
else if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
{
Status = STATUS_PIPE_CLOSING;
}
else
{
Status = STATUS_UNSUCCESSFUL;
}
KeUnlockMutex(&Fcb->CcbListLock);
return Status;
}
static NTSTATUS
NpfsWaitPipe(PIRP Irp,
PNPFS_CCB Ccb)
PNPFS_CCB Ccb)
{
PLIST_ENTRY current_entry;
PNPFS_FCB Fcb;
PNPFS_CCB ServerCcb;
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
NTSTATUS Status;
LARGE_INTEGER TimeOut;
PLIST_ENTRY current_entry;
PNPFS_FCB Fcb;
PNPFS_CCB ServerCcb;
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
NTSTATUS Status;
LARGE_INTEGER TimeOut;
DPRINT("NpfsWaitPipe\n");
DPRINT("NpfsWaitPipe\n");
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
Fcb = Ccb->Fcb;
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
Fcb = Ccb->Fcb;
if (Ccb->PipeState != 0)
{
DPRINT("Pipe is not in passive (waiting) state!\n");
return STATUS_UNSUCCESSFUL;
}
if (Ccb->PipeState != 0)
{
DPRINT("Pipe is not in passive (waiting) state!\n");
return STATUS_UNSUCCESSFUL;
}
/* search for listening server */
current_entry = Fcb->ServerCcbListHead.Flink;
while (current_entry != &Fcb->ServerCcbListHead)
{
ServerCcb = CONTAINING_RECORD(current_entry,
NPFS_CCB,
CcbListEntry);
/* search for listening server */
current_entry = Fcb->ServerCcbListHead.Flink;
while (current_entry != &Fcb->ServerCcbListHead)
{
ServerCcb = CONTAINING_RECORD(current_entry,
NPFS_CCB,
CcbListEntry);
if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
{
/* found a listening server CCB */
DPRINT("Listening server CCB found -- connecting\n");
if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
{
/* found a listening server CCB */
DPRINT("Listening server CCB found -- connecting\n");
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
current_entry = current_entry->Flink;
}
current_entry = current_entry->Flink;
}
/* No listening server fcb found */
/* No listening server fcb found */
/* If no timeout specified, use the default one */
if (WaitPipe->TimeoutSpecified)
TimeOut = WaitPipe->Timeout;
else
TimeOut = Fcb->TimeOut;
/* If no timeout specified, use the default one */
if (WaitPipe->TimeoutSpecified)
TimeOut = WaitPipe->Timeout;
else
TimeOut = Fcb->TimeOut;
/* Wait for one */
Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest,
KernelMode,
FALSE,
&TimeOut);
/* Wait for one */
Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest,
KernelMode,
FALSE,
&TimeOut);
DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
return Status;
return Status;
}
@ -362,243 +362,243 @@ NpfsWaitPipe(PIRP Irp,
*/
static NTSTATUS
NpfsPeekPipe(PIRP Irp,
PIO_STACK_LOCATION IoStack)
PIO_STACK_LOCATION IoStack)
{
ULONG OutputBufferLength;
ULONG ReturnLength = 0;
PFILE_PIPE_PEEK_BUFFER Reply;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
NTSTATUS Status;
ULONG MessageCount = 0;
ULONG MessageLength;
ULONG ReadDataAvailable;
PVOID BufferPtr;
ULONG OutputBufferLength;
ULONG ReturnLength = 0;
PFILE_PIPE_PEEK_BUFFER Reply;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
NTSTATUS Status;
ULONG MessageCount = 0;
ULONG MessageLength;
ULONG ReadDataAvailable;
PVOID BufferPtr;
DPRINT("NpfsPeekPipe\n");
DPRINT("NpfsPeekPipe\n");
OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
DPRINT("OutputBufferLength: %lu\n", OutputBufferLength);
OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
DPRINT("OutputBufferLength: %lu\n", OutputBufferLength);
/* Validate parameters */
if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
{
DPRINT1("Buffer too small\n");
return STATUS_INVALID_PARAMETER;
}
/* Validate parameters */
if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
{
DPRINT1("Buffer too small\n");
return STATUS_INVALID_PARAMETER;
}
Ccb = IoStack->FileObject->FsContext2;
Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
Fcb = Ccb->Fcb;
Ccb = IoStack->FileObject->FsContext2;
Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
Fcb = Ccb->Fcb;
Reply->NamedPipeState = Ccb->PipeState;
Reply->NamedPipeState = Ccb->PipeState;
Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
ExAcquireFastMutex(&Ccb->DataListLock);
BufferPtr = Ccb->ReadPtr;
DPRINT("BufferPtr = %x\n", BufferPtr);
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
{
DPRINT("Byte Stream Mode\n");
Reply->MessageLength = Ccb->ReadDataAvailable;
DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength );
MessageCount = 1;
ExAcquireFastMutex(&Ccb->DataListLock);
BufferPtr = Ccb->ReadPtr;
DPRINT("BufferPtr = %x\n", BufferPtr);
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
{
DPRINT("Byte Stream Mode\n");
Reply->MessageLength = Ccb->ReadDataAvailable;
DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength );
MessageCount = 1;
if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
{
ReturnLength = Ccb->ReadDataAvailable;
memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
}
}
else
{
DPRINT("Message Mode\n");
ReadDataAvailable=Ccb->ReadDataAvailable;
if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
{
ReturnLength = Ccb->ReadDataAvailable;
memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
}
}
else
{
DPRINT("Message Mode\n");
ReadDataAvailable=Ccb->ReadDataAvailable;
if (ReadDataAvailable > 0)
{
memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
if (ReadDataAvailable > 0)
{
memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
{
memcpy(&MessageLength, BufferPtr, sizeof(MessageLength));
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
{
memcpy(&MessageLength, BufferPtr, sizeof(MessageLength));
ASSERT(MessageLength > 0);
ASSERT(MessageLength > 0);
DPRINT("MessageLength = %lu\n",MessageLength);
ReadDataAvailable -= MessageLength;
MessageCount++;
DPRINT("MessageLength = %lu\n",MessageLength);
ReadDataAvailable -= MessageLength;
MessageCount++;
/* If its the first message, copy the Message if the size of buffer is large enough */
if (MessageCount==1)
{
if ((Reply->Data[0])
&& (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
{
memcpy(&Reply->Data[0], (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)), MessageLength);
ReturnLength = MessageLength;
}
}
/* If its the first message, copy the Message if the size of buffer is large enough */
if (MessageCount==1)
{
if ((Reply->Data[0])
&& (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
{
memcpy(&Reply->Data[0], (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)), MessageLength);
ReturnLength = MessageLength;
}
}
BufferPtr =(PVOID)((ULONG_PTR)BufferPtr + MessageLength + sizeof(MessageLength));
DPRINT("BufferPtr = %x\n", BufferPtr);
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
}
BufferPtr =(PVOID)((ULONG_PTR)BufferPtr + MessageLength + sizeof(MessageLength));
DPRINT("BufferPtr = %x\n", BufferPtr);
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
}
if (ReadDataAvailable != 0)
{
DPRINT1("Possible memory corruption.\n");
ASSERT(FALSE);
}
}
}
ExReleaseFastMutex(&Ccb->DataListLock);
if (ReadDataAvailable != 0)
{
DPRINT1("Possible memory corruption.\n");
ASSERT(FALSE);
}
}
}
ExReleaseFastMutex(&Ccb->DataListLock);
Reply->NumberOfMessages = MessageCount;
Reply->NumberOfMessages = MessageCount;
Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
Irp->IoStatus.Status = STATUS_SUCCESS;
Status = STATUS_SUCCESS;
Status = STATUS_SUCCESS;
DPRINT("NpfsPeekPipe done\n");
DPRINT("NpfsPeekPipe done\n");
return Status;
return Status;
}
NTSTATUS NTAPI
NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PNPFS_DEVICE_EXTENSION DeviceExt;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PNPFS_DEVICE_EXTENSION DeviceExt;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;
DPRINT("FileObject: %p\n", FileObject);
Ccb = FileObject->FsContext2;
DPRINT("CCB: %p\n", Ccb);
Fcb = Ccb->Fcb;
DPRINT("Pipe: %p\n", Fcb);
DPRINT("PipeName: %wZ\n", &Fcb->PipeName);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;
DPRINT("FileObject: %p\n", FileObject);
Ccb = FileObject->FsContext2;
DPRINT("CCB: %p\n", Ccb);
Fcb = Ccb->Fcb;
DPRINT("Pipe: %p\n", Fcb);
DPRINT("PipeName: %wZ\n", &Fcb->PipeName);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Information = 0;
switch (IoStack->Parameters.FileSystemControl.FsControlCode)
{
case FSCTL_PIPE_ASSIGN_EVENT:
DPRINT1("Assign event not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
switch (IoStack->Parameters.FileSystemControl.FsControlCode)
{
case FSCTL_PIPE_ASSIGN_EVENT:
DPRINT1("Assign event not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_DISCONNECT:
DPRINT("Disconnecting pipe %wZ\n", &Fcb->PipeName);
Status = NpfsDisconnectPipe(Ccb);
break;
case FSCTL_PIPE_DISCONNECT:
DPRINT("Disconnecting pipe %wZ\n", &Fcb->PipeName);
Status = NpfsDisconnectPipe(Ccb);
break;
case FSCTL_PIPE_LISTEN:
DPRINT("Connecting pipe %wZ\n", &Fcb->PipeName);
Status = NpfsConnectPipe(Irp, Ccb);
break;
case FSCTL_PIPE_LISTEN:
DPRINT("Connecting pipe %wZ\n", &Fcb->PipeName);
Status = NpfsConnectPipe(Irp, Ccb);
break;
case FSCTL_PIPE_PEEK:
DPRINT("Peeking pipe %wZ\n", &Fcb->PipeName);
Status = NpfsPeekPipe(Irp, (PIO_STACK_LOCATION)IoStack);
break;
case FSCTL_PIPE_PEEK:
DPRINT("Peeking pipe %wZ\n", &Fcb->PipeName);
Status = NpfsPeekPipe(Irp, (PIO_STACK_LOCATION)IoStack);
break;
case FSCTL_PIPE_QUERY_EVENT:
DPRINT1("Query event not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_QUERY_EVENT:
DPRINT1("Query event not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_TRANSCEIVE:
/* If you implement this, please remove the workaround in
lib/kernel32/file/npipe.c function TransactNamedPipe() */
DPRINT1("Transceive not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_TRANSCEIVE:
/* If you implement this, please remove the workaround in
lib/kernel32/file/npipe.c function TransactNamedPipe() */
DPRINT1("Transceive not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_WAIT:
DPRINT("Waiting for pipe %wZ\n", &Fcb->PipeName);
Status = NpfsWaitPipe(Irp, Ccb);
break;
case FSCTL_PIPE_WAIT:
DPRINT("Waiting for pipe %wZ\n", &Fcb->PipeName);
Status = NpfsWaitPipe(Irp, Ccb);
break;
case FSCTL_PIPE_IMPERSONATE:
DPRINT1("Impersonate not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_IMPERSONATE:
DPRINT1("Impersonate not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_SET_CLIENT_PROCESS:
DPRINT1("Set client process not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_SET_CLIENT_PROCESS:
DPRINT1("Set client process not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
DPRINT1("Query client process not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
DPRINT1("Query client process not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_READ:
DPRINT1("Internal read not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_READ:
DPRINT1("Internal read not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_WRITE:
DPRINT1("Internal write not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_WRITE:
DPRINT1("Internal write not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
DPRINT1("Internal transceive not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
DPRINT1("Internal transceive not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
DPRINT1("Internal read overflow not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
DPRINT1("Internal read overflow not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DPRINT1("Unrecognized IoControlCode: %x\n",
IoStack->Parameters.FileSystemControl.FsControlCode);
Status = STATUS_UNSUCCESSFUL;
}
default:
DPRINT1("Unrecognized IoControlCode: %x\n",
IoStack->Parameters.FileSystemControl.FsControlCode);
Status = STATUS_UNSUCCESSFUL;
}
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return Status;
return Status;
}
NTSTATUS NTAPI
NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
/* FIXME: Implement */
/* FIXME: Implement */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -17,73 +17,73 @@
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
PUNICODE_STRING RegistryPath)
{
PNPFS_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
NTSTATUS Status;
PNPFS_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
NTSTATUS Status;
DPRINT("Named Pipe FSD 0.0.2\n");
DPRINT("Named Pipe FSD 0.0.2\n");
ASSERT (sizeof(NPFS_CONTEXT) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
ASSERT (sizeof(NPFS_WAITER_ENTRY) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
ASSERT (sizeof(NPFS_CONTEXT) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
ASSERT (sizeof(NPFS_WAITER_ENTRY) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
NpfsCreateNamedPipe;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpfsClose;
DriverObject->MajorFunction[IRP_MJ_READ] = NpfsRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NpfsWrite;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
NpfsQueryInformation;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
NpfsSetInformation;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
NpfsQueryVolumeInformation;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
// DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
// NpfsDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
NpfsFileSystemControl;
// DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =
// NpfsQuerySecurity;
// DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =
// NpfsSetSecurity;
DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
NpfsCreateNamedPipe;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpfsClose;
DriverObject->MajorFunction[IRP_MJ_READ] = NpfsRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NpfsWrite;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
NpfsQueryInformation;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
NpfsSetInformation;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
NpfsQueryVolumeInformation;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
// DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
// NpfsDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
NpfsFileSystemControl;
// DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =
// NpfsQuerySecurity;
// DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =
// NpfsSetSecurity;
DriverObject->DriverUnload = NULL;
DriverObject->DriverUnload = NULL;
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
Status = IoCreateDevice(DriverObject,
sizeof(NPFS_DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_NAMED_PIPE,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
return Status;
}
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
Status = IoCreateDevice(DriverObject,
sizeof(NPFS_DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_NAMED_PIPE,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
return Status;
}
/* initialize the device object */
DeviceObject->Flags |= DO_DIRECT_IO;
/* initialize the device object */
DeviceObject->Flags |= DO_DIRECT_IO;
/* initialize the device extension */
DeviceExtension = DeviceObject->DeviceExtension;
InitializeListHead(&DeviceExtension->PipeListHead);
InitializeListHead(&DeviceExtension->ThreadListHead);
KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
DeviceExtension->EmptyWaiterCount = 0;
/* initialize the device extension */
DeviceExtension = DeviceObject->DeviceExtension;
InitializeListHead(&DeviceExtension->PipeListHead);
InitializeListHead(&DeviceExtension->ThreadListHead);
KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
DeviceExtension->EmptyWaiterCount = 0;
/* set the size quotas */
DeviceExtension->MinQuota = PAGE_SIZE;
DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
/* set the size quotas */
DeviceExtension->MinQuota = PAGE_SIZE;
DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -6,82 +6,82 @@
typedef struct _NPFS_DEVICE_EXTENSION
{
LIST_ENTRY PipeListHead;
LIST_ENTRY ThreadListHead;
KMUTEX PipeListLock;
ULONG EmptyWaiterCount;
ULONG MinQuota;
ULONG DefaultQuota;
ULONG MaxQuota;
LIST_ENTRY PipeListHead;
LIST_ENTRY ThreadListHead;
KMUTEX PipeListLock;
ULONG EmptyWaiterCount;
ULONG MinQuota;
ULONG DefaultQuota;
ULONG MaxQuota;
} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
typedef struct _NPFS_FCB
{
FSRTL_COMMON_FCB_HEADER RFCB;
UNICODE_STRING PipeName;
LIST_ENTRY PipeListEntry;
KMUTEX CcbListLock;
LIST_ENTRY ServerCcbListHead;
LIST_ENTRY ClientCcbListHead;
LIST_ENTRY WaiterListHead;
LIST_ENTRY EmptyBufferListHead;
ULONG PipeType;
ULONG ClientReadMode;
ULONG ServerReadMode;
ULONG CompletionMode;
ULONG PipeConfiguration;
ULONG MaximumInstances;
ULONG CurrentInstances;
ULONG InboundQuota;
ULONG OutboundQuota;
LARGE_INTEGER TimeOut;
FSRTL_COMMON_FCB_HEADER RFCB;
UNICODE_STRING PipeName;
LIST_ENTRY PipeListEntry;
KMUTEX CcbListLock;
LIST_ENTRY ServerCcbListHead;
LIST_ENTRY ClientCcbListHead;
LIST_ENTRY WaiterListHead;
LIST_ENTRY EmptyBufferListHead;
ULONG PipeType;
ULONG ClientReadMode;
ULONG ServerReadMode;
ULONG CompletionMode;
ULONG PipeConfiguration;
ULONG MaximumInstances;
ULONG CurrentInstances;
ULONG InboundQuota;
ULONG OutboundQuota;
LARGE_INTEGER TimeOut;
} NPFS_FCB, *PNPFS_FCB;
typedef struct _NPFS_CCB
{
LIST_ENTRY CcbListEntry;
struct _NPFS_CCB* OtherSide;
struct ETHREAD *Thread;
PNPFS_FCB Fcb;
KEVENT ConnectEvent;
KEVENT ReadEvent;
KEVENT WriteEvent;
ULONG PipeEnd;
ULONG PipeState;
ULONG ReadDataAvailable;
ULONG WriteQuotaAvailable;
LIST_ENTRY CcbListEntry;
struct _NPFS_CCB* OtherSide;
struct ETHREAD *Thread;
PNPFS_FCB Fcb;
KEVENT ConnectEvent;
KEVENT ReadEvent;
KEVENT WriteEvent;
ULONG PipeEnd;
ULONG PipeState;
ULONG ReadDataAvailable;
ULONG WriteQuotaAvailable;
LIST_ENTRY ReadRequestListHead;
LIST_ENTRY ReadRequestListHead;
PVOID Data;
PVOID ReadPtr;
PVOID WritePtr;
ULONG MaxDataLength;
PVOID Data;
PVOID ReadPtr;
PVOID WritePtr;
ULONG MaxDataLength;
FAST_MUTEX DataListLock; /* Data queue lock */
FAST_MUTEX DataListLock; /* Data queue lock */
} NPFS_CCB, *PNPFS_CCB;
typedef struct _NPFS_CONTEXT
{
LIST_ENTRY ListEntry;
PKEVENT WaitEvent;
LIST_ENTRY ListEntry;
PKEVENT WaitEvent;
} NPFS_CONTEXT, *PNPFS_CONTEXT;
typedef struct _NPFS_THREAD_CONTEXT
{
ULONG Count;
KEVENT Event;
PNPFS_DEVICE_EXTENSION DeviceExt;
LIST_ENTRY ListEntry;
PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
PIRP WaitIrpArray[MAXIMUM_WAIT_OBJECTS];
ULONG Count;
KEVENT Event;
PNPFS_DEVICE_EXTENSION DeviceExt;
LIST_ENTRY ListEntry;
PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
PIRP WaitIrpArray[MAXIMUM_WAIT_OBJECTS];
} NPFS_THREAD_CONTEXT, *PNPFS_THREAD_CONTEXT;
typedef struct _NPFS_WAITER_ENTRY
{
LIST_ENTRY Entry;
PNPFS_CCB Ccb;
LIST_ENTRY Entry;
PNPFS_CCB Ccb;
} NPFS_WAITER_ENTRY, *PNPFS_WAITER_ENTRY;
@ -89,10 +89,10 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
#define KeLockMutex(x) KeWaitForSingleObject(x, \
UserRequest, \
KernelMode, \
FALSE, \
NULL);
UserRequest, \
KernelMode, \
FALSE, \
NULL);
#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
@ -133,6 +133,6 @@ NTSTATUS NTAPI NpfsQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
PUNICODE_STRING RegistryPath);
#endif /* __DRIVERS_FS_NP_NPFS_H */

File diff suppressed because it is too large Load diff

View file

@ -17,99 +17,99 @@
static NTSTATUS
NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
PULONG BufferLength)
PULONG BufferLength)
{
DPRINT("NpfsQueryFsDeviceInformation()\n");
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
DPRINT("NpfsQueryFsDeviceInformation()\n");
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
FsDeviceInfo->Characteristics = 0;
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
FsDeviceInfo->Characteristics = 0;
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
static NTSTATUS
NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
PULONG BufferLength)
PULONG BufferLength)
{
DPRINT("NpfsQueryFsAttributeInformation() called.\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
DPRINT("NpfsQueryFsAttributeInformation() called.\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
return STATUS_BUFFER_OVERFLOW;
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
return STATUS_BUFFER_OVERFLOW;
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
FsAttributeInfo->MaximumComponentNameLength = 255;
FsAttributeInfo->FileSystemNameLength = 8;
wcscpy(FsAttributeInfo->FileSystemName,
L"NPFS");
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
FsAttributeInfo->MaximumComponentNameLength = 255;
FsAttributeInfo->FileSystemNameLength = 8;
wcscpy(FsAttributeInfo->FileSystemName,
L"NPFS");
DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PIO_STACK_LOCATION Stack;
FS_INFORMATION_CLASS FsInformationClass;
NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
PIO_STACK_LOCATION Stack;
FS_INFORMATION_CLASS FsInformationClass;
NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
/* PRECONDITION */
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
/* PRECONDITION */
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
DPRINT("NpfsQueryVolumeInformation(DeviceObject %p, Irp %p)\n",
DeviceObject,
Irp);
DPRINT("NpfsQueryVolumeInformation(DeviceObject %p, Irp %p)\n",
DeviceObject,
Irp);
Stack = IoGetCurrentIrpStackLocation(Irp);
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
BufferLength = Stack->Parameters.QueryVolume.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
Stack = IoGetCurrentIrpStackLocation(Irp);
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
BufferLength = Stack->Parameters.QueryVolume.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FsInformationClass %d\n", FsInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("FsInformationClass %d\n", FsInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
switch (FsInformationClass)
{
case FileFsDeviceInformation:
Status = NpfsQueryFsDeviceInformation(SystemBuffer,
&BufferLength);
break;
switch (FsInformationClass)
{
case FileFsDeviceInformation:
Status = NpfsQueryFsDeviceInformation(SystemBuffer,
&BufferLength);
break;
case FileFsAttributeInformation:
Status = NpfsQueryFsAttributeInformation(SystemBuffer,
&BufferLength);
break;
case FileFsAttributeInformation:
Status = NpfsQueryFsAttributeInformation(SystemBuffer,
&BufferLength);
break;
default:
Status = STATUS_NOT_SUPPORTED;
}
default:
Status = STATUS_NOT_SUPPORTED;
}
Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return Status;
return Status;
}
/* EOF */