mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:15:41 +00:00
- Fix formatting
svn path=/trunk/; revision=39477
This commit is contained in:
parent
5b794bd721
commit
c15c8ae183
7 changed files with 2214 additions and 2215 deletions
File diff suppressed because it is too large
Load diff
|
@ -18,287 +18,286 @@
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PNPFS_CCB Ccb,
|
PNPFS_CCB Ccb,
|
||||||
PFILE_PIPE_INFORMATION Info,
|
PFILE_PIPE_INFORMATION Info,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PFILE_PIPE_INFORMATION Request;
|
PFILE_PIPE_INFORMATION Request;
|
||||||
DPRINT("NpfsSetPipeInformation()\n");
|
DPRINT("NpfsSetPipeInformation()\n");
|
||||||
|
|
||||||
/* Get the Pipe and data */
|
/* Get the Pipe and data */
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
Request = (PFILE_PIPE_INFORMATION)Info;
|
Request = (PFILE_PIPE_INFORMATION)Info;
|
||||||
|
|
||||||
if ((Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE) && (Request->ReadMode == FILE_PIPE_MESSAGE_MODE))
|
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");
|
DPRINT("Cannot change readmode to message type on a byte type pipe!\n");
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Pipe Data */
|
/* Set Pipe Data */
|
||||||
if (Ccb->PipeEnd == FILE_PIPE_CLIENT_END)
|
if (Ccb->PipeEnd == FILE_PIPE_CLIENT_END)
|
||||||
{
|
{
|
||||||
Fcb->ClientReadMode = Request->ReadMode;
|
Fcb->ClientReadMode = Request->ReadMode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Fcb->ServerReadMode = Request->ReadMode;
|
Fcb->ServerReadMode = Request->ReadMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fcb->CompletionMode = Request->CompletionMode;
|
Fcb->CompletionMode = Request->CompletionMode;
|
||||||
|
|
||||||
/* Return Success */
|
/* Return Success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NpfsSetPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsSetPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PNPFS_CCB Ccb,
|
PNPFS_CCB Ccb,
|
||||||
PFILE_PIPE_INFORMATION Info,
|
PFILE_PIPE_INFORMATION Info,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PFILE_PIPE_REMOTE_INFORMATION Request;
|
PFILE_PIPE_REMOTE_INFORMATION Request;
|
||||||
DPRINT("NpfsSetPipeRemoteInformation()\n");
|
DPRINT("NpfsSetPipeRemoteInformation()\n");
|
||||||
|
|
||||||
/* Get the Pipe and data */
|
/* Get the Pipe and data */
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
Request = (PFILE_PIPE_REMOTE_INFORMATION)Info;
|
Request = (PFILE_PIPE_REMOTE_INFORMATION)Info;
|
||||||
|
|
||||||
/* Set the Settings */
|
/* Set the Settings */
|
||||||
Fcb->TimeOut = Request->CollectDataTime;
|
Fcb->TimeOut = Request->CollectDataTime;
|
||||||
Fcb->InboundQuota = Request->MaximumCollectionCount;
|
Fcb->InboundQuota = Request->MaximumCollectionCount;
|
||||||
|
|
||||||
/* Return Success */
|
/* Return Success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PNPFS_CCB Ccb,
|
PNPFS_CCB Ccb,
|
||||||
PFILE_PIPE_INFORMATION Info,
|
PFILE_PIPE_INFORMATION Info,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
ULONG ConnectionSideReadMode;
|
ULONG ConnectionSideReadMode;
|
||||||
DPRINT("NpfsQueryPipeInformation()\n");
|
DPRINT("NpfsQueryPipeInformation()\n");
|
||||||
|
|
||||||
/* Get the Pipe */
|
/* Get the Pipe */
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
/* Clear Info */
|
/* Clear Info */
|
||||||
RtlZeroMemory(Info, sizeof(FILE_PIPE_INFORMATION));
|
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;
|
/* Return Info */
|
||||||
else ConnectionSideReadMode = Ccb->Fcb->ServerReadMode;
|
Info->CompletionMode = Fcb->CompletionMode;
|
||||||
|
Info->ReadMode = ConnectionSideReadMode;
|
||||||
|
|
||||||
/* Return Info */
|
/* Return success */
|
||||||
Info->CompletionMode = Fcb->CompletionMode;
|
*BufferLength -= sizeof(FILE_PIPE_INFORMATION);
|
||||||
Info->ReadMode = ConnectionSideReadMode;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
*BufferLength -= sizeof(FILE_PIPE_INFORMATION);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PNPFS_CCB Ccb,
|
PNPFS_CCB Ccb,
|
||||||
PFILE_PIPE_REMOTE_INFORMATION Info,
|
PFILE_PIPE_REMOTE_INFORMATION Info,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
DPRINT("NpfsQueryPipeRemoteInformation()\n");
|
DPRINT("NpfsQueryPipeRemoteInformation()\n");
|
||||||
|
|
||||||
/* Get the Pipe */
|
/* Get the Pipe */
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
/* Clear Info */
|
/* Clear Info */
|
||||||
RtlZeroMemory(Info, sizeof(FILE_PIPE_REMOTE_INFORMATION));
|
RtlZeroMemory(Info, sizeof(FILE_PIPE_REMOTE_INFORMATION));
|
||||||
|
|
||||||
/* Return Info */
|
/* Return Info */
|
||||||
Info->MaximumCollectionCount = Fcb->InboundQuota;
|
Info->MaximumCollectionCount = Fcb->InboundQuota;
|
||||||
Info->CollectDataTime = Fcb->TimeOut;
|
Info->CollectDataTime = Fcb->TimeOut;
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
*BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION);
|
*BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PNPFS_CCB Ccb,
|
PNPFS_CCB Ccb,
|
||||||
PFILE_PIPE_LOCAL_INFORMATION Info,
|
PFILE_PIPE_LOCAL_INFORMATION Info,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
|
|
||||||
DPRINT("NpfsQueryLocalPipeInformation()\n");
|
DPRINT("NpfsQueryLocalPipeInformation()\n");
|
||||||
|
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
RtlZeroMemory(Info,
|
RtlZeroMemory(Info,
|
||||||
sizeof(FILE_PIPE_LOCAL_INFORMATION));
|
sizeof(FILE_PIPE_LOCAL_INFORMATION));
|
||||||
|
|
||||||
Info->NamedPipeType = Fcb->PipeType;
|
Info->NamedPipeType = Fcb->PipeType;
|
||||||
Info->NamedPipeConfiguration = Fcb->PipeConfiguration;
|
Info->NamedPipeConfiguration = Fcb->PipeConfiguration;
|
||||||
Info->MaximumInstances = Fcb->MaximumInstances;
|
Info->MaximumInstances = Fcb->MaximumInstances;
|
||||||
Info->CurrentInstances = Fcb->CurrentInstances;
|
Info->CurrentInstances = Fcb->CurrentInstances;
|
||||||
Info->InboundQuota = Fcb->InboundQuota;
|
Info->InboundQuota = Fcb->InboundQuota;
|
||||||
Info->OutboundQuota = Fcb->OutboundQuota;
|
Info->OutboundQuota = Fcb->OutboundQuota;
|
||||||
Info->NamedPipeState = Ccb->PipeState;
|
Info->NamedPipeState = Ccb->PipeState;
|
||||||
Info->NamedPipeEnd = Ccb->PipeEnd;
|
Info->NamedPipeEnd = Ccb->PipeEnd;
|
||||||
|
|
||||||
if (Ccb->PipeEnd == FILE_PIPE_SERVER_END)
|
if (Ccb->PipeEnd == FILE_PIPE_SERVER_END)
|
||||||
{
|
{
|
||||||
Info->ReadDataAvailable = Ccb->ReadDataAvailable;
|
Info->ReadDataAvailable = Ccb->ReadDataAvailable;
|
||||||
Info->WriteQuotaAvailable = Ccb->WriteQuotaAvailable;
|
Info->WriteQuotaAvailable = Ccb->WriteQuotaAvailable;
|
||||||
}
|
}
|
||||||
else if (Ccb->OtherSide != NULL)
|
else if (Ccb->OtherSide != NULL)
|
||||||
{
|
{
|
||||||
Info->ReadDataAvailable = Ccb->OtherSide->ReadDataAvailable;
|
Info->ReadDataAvailable = Ccb->OtherSide->ReadDataAvailable;
|
||||||
Info->WriteQuotaAvailable = Ccb->OtherSide->WriteQuotaAvailable;
|
Info->WriteQuotaAvailable = Ccb->OtherSide->WriteQuotaAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
*BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION);
|
*BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
FILE_INFORMATION_CLASS FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PNPFS_DEVICE_EXTENSION DeviceExtension;
|
PNPFS_DEVICE_EXTENSION DeviceExtension;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB Ccb;
|
PNPFS_CCB Ccb;
|
||||||
PVOID SystemBuffer;
|
PVOID SystemBuffer;
|
||||||
ULONG BufferLength;
|
ULONG BufferLength;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation (Irp);
|
IoStack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
FileObject = IoStack->FileObject;
|
FileObject = IoStack->FileObject;
|
||||||
Ccb = (PNPFS_CCB)FileObject->FsContext2;
|
Ccb = (PNPFS_CCB)FileObject->FsContext2;
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
BufferLength = IoStack->Parameters.QueryFile.Length;
|
BufferLength = IoStack->Parameters.QueryFile.Length;
|
||||||
|
|
||||||
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
|
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
|
||||||
DPRINT("FileInformationClass %d\n", FileInformationClass);
|
DPRINT("FileInformationClass %d\n", FileInformationClass);
|
||||||
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
||||||
DPRINT("BufferLength %lu\n", BufferLength);
|
DPRINT("BufferLength %lu\n", BufferLength);
|
||||||
|
|
||||||
switch (FileInformationClass)
|
switch (FileInformationClass)
|
||||||
{
|
{
|
||||||
case FilePipeInformation:
|
case FilePipeInformation:
|
||||||
Status = NpfsQueryPipeInformation(DeviceObject,
|
Status = NpfsQueryPipeInformation(DeviceObject,
|
||||||
Ccb,
|
Ccb,
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilePipeLocalInformation:
|
case FilePipeLocalInformation:
|
||||||
Status = NpfsQueryLocalPipeInformation(DeviceObject,
|
Status = NpfsQueryLocalPipeInformation(DeviceObject,
|
||||||
Ccb,
|
Ccb,
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilePipeRemoteInformation:
|
case FilePipeRemoteInformation:
|
||||||
Status = NpfsQueryPipeRemoteInformation(DeviceObject,
|
Status = NpfsQueryPipeRemoteInformation(DeviceObject,
|
||||||
Ccb,
|
Ccb,
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Status = STATUS_NOT_SUPPORTED;
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Irp->IoStatus.Information =
|
Irp->IoStatus.Information =
|
||||||
IoStack->Parameters.QueryFile.Length - BufferLength;
|
IoStack->Parameters.QueryFile.Length - BufferLength;
|
||||||
else
|
else
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
FILE_INFORMATION_CLASS FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB Ccb;
|
PNPFS_CCB Ccb;
|
||||||
PVOID SystemBuffer;
|
PVOID SystemBuffer;
|
||||||
ULONG BufferLength;
|
ULONG BufferLength;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation (Irp);
|
IoStack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
||||||
FileObject = IoStack->FileObject;
|
FileObject = IoStack->FileObject;
|
||||||
Ccb = (PNPFS_CCB)FileObject->FsContext2;
|
Ccb = (PNPFS_CCB)FileObject->FsContext2;
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
BufferLength = IoStack->Parameters.QueryFile.Length;
|
BufferLength = IoStack->Parameters.QueryFile.Length;
|
||||||
|
|
||||||
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
|
DPRINT("Pipe name: %wZ\n", &Fcb->PipeName);
|
||||||
DPRINT("FileInformationClass %d\n", FileInformationClass);
|
DPRINT("FileInformationClass %d\n", FileInformationClass);
|
||||||
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
||||||
DPRINT("BufferLength %lu\n", BufferLength);
|
DPRINT("BufferLength %lu\n", BufferLength);
|
||||||
|
|
||||||
switch (FileInformationClass)
|
switch (FileInformationClass)
|
||||||
{
|
{
|
||||||
case FilePipeInformation:
|
case FilePipeInformation:
|
||||||
/* Call the handler */
|
/* Call the handler */
|
||||||
Status = NpfsSetPipeInformation(DeviceObject,
|
Status = NpfsSetPipeInformation(DeviceObject,
|
||||||
Ccb,
|
Ccb,
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilePipeLocalInformation:
|
case FilePipeLocalInformation:
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilePipeRemoteInformation:
|
case FilePipeRemoteInformation:
|
||||||
/* Call the handler */
|
/* Call the handler */
|
||||||
Status = NpfsSetPipeRemoteInformation(DeviceObject,
|
Status = NpfsSetPipeRemoteInformation(DeviceObject,
|
||||||
Ccb,
|
Ccb,
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Status = STATUS_NOT_SUPPORTED;
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -20,326 +20,326 @@
|
||||||
static DRIVER_CANCEL NpfsListeningCancelRoutine;
|
static DRIVER_CANCEL NpfsListeningCancelRoutine;
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
|
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",
|
DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
|
||||||
&Waiter->Ccb->Fcb->PipeName);
|
&Waiter->Ccb->Fcb->PipeName);
|
||||||
|
|
||||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
|
|
||||||
|
|
||||||
KeLockMutex(&Waiter->Ccb->Fcb->CcbListLock);
|
KeLockMutex(&Waiter->Ccb->Fcb->CcbListLock);
|
||||||
RemoveEntryList(&Waiter->Entry);
|
RemoveEntryList(&Waiter->Entry);
|
||||||
KeUnlockMutex(&Waiter->Ccb->Fcb->CcbListLock);
|
KeUnlockMutex(&Waiter->Ccb->Fcb->CcbListLock);
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
NpfsAddListeningServerInstance(PIRP Irp,
|
NpfsAddListeningServerInstance(PIRP Irp,
|
||||||
PNPFS_CCB Ccb)
|
PNPFS_CCB Ccb)
|
||||||
{
|
{
|
||||||
PNPFS_WAITER_ENTRY Entry;
|
PNPFS_WAITER_ENTRY Entry;
|
||||||
KIRQL oldIrql;
|
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);
|
IoMarkIrpPending(Irp);
|
||||||
InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
|
InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
|
||||||
|
|
||||||
IoAcquireCancelSpinLock(&oldIrql);
|
IoAcquireCancelSpinLock(&oldIrql);
|
||||||
if (!Irp->Cancel)
|
if (!Irp->Cancel)
|
||||||
{
|
{
|
||||||
(void)IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
|
(void)IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
|
||||||
IoReleaseCancelSpinLock(oldIrql);
|
IoReleaseCancelSpinLock(oldIrql);
|
||||||
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
|
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
IoReleaseCancelSpinLock(oldIrql);
|
IoReleaseCancelSpinLock(oldIrql);
|
||||||
|
|
||||||
RemoveEntryList(&Entry->Entry);
|
RemoveEntryList(&Entry->Entry);
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
|
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
|
||||||
|
|
||||||
return STATUS_CANCELLED;
|
return STATUS_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
NpfsConnectPipe(PIRP Irp,
|
NpfsConnectPipe(PIRP Irp,
|
||||||
PNPFS_CCB Ccb)
|
PNPFS_CCB Ccb)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB ClientCcb;
|
PNPFS_CCB ClientCcb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("NpfsConnectPipe()\n");
|
DPRINT("NpfsConnectPipe()\n");
|
||||||
|
|
||||||
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||||
{
|
{
|
||||||
KeResetEvent(&Ccb->ConnectEvent);
|
KeResetEvent(&Ccb->ConnectEvent);
|
||||||
return STATUS_PIPE_CONNECTED;
|
return STATUS_PIPE_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
|
if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
|
||||||
return STATUS_PIPE_CLOSING;
|
return STATUS_PIPE_CLOSING;
|
||||||
|
|
||||||
DPRINT("Waiting for connection...\n");
|
DPRINT("Waiting for connection...\n");
|
||||||
|
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
FileObject = IoStack->FileObject;
|
FileObject = IoStack->FileObject;
|
||||||
Flags = FileObject->Flags;
|
Flags = FileObject->Flags;
|
||||||
|
|
||||||
/* search for a listening client fcb */
|
/* search for a listening client fcb */
|
||||||
KeLockMutex(&Fcb->CcbListLock);
|
KeLockMutex(&Fcb->CcbListLock);
|
||||||
|
|
||||||
current_entry = Fcb->ClientCcbListHead.Flink;
|
current_entry = Fcb->ClientCcbListHead.Flink;
|
||||||
while (current_entry != &Fcb->ClientCcbListHead)
|
while (current_entry != &Fcb->ClientCcbListHead)
|
||||||
{
|
{
|
||||||
ClientCcb = CONTAINING_RECORD(current_entry,
|
ClientCcb = CONTAINING_RECORD(current_entry,
|
||||||
NPFS_CCB,
|
NPFS_CCB,
|
||||||
CcbListEntry);
|
CcbListEntry);
|
||||||
|
|
||||||
if (ClientCcb->PipeState == 0)
|
if (ClientCcb->PipeState == 0)
|
||||||
{
|
{
|
||||||
/* found a passive (waiting) client CCB */
|
/* found a passive (waiting) client CCB */
|
||||||
DPRINT("Passive (waiting) client CCB found -- wake the client\n");
|
DPRINT("Passive (waiting) client CCB found -- wake the client\n");
|
||||||
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (ClientCcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
if (ClientCcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||||
{
|
{
|
||||||
/* found a listening client CCB */
|
/* found a listening client CCB */
|
||||||
DPRINT("Listening client CCB found -- connecting\n");
|
DPRINT("Listening client CCB found -- connecting\n");
|
||||||
|
|
||||||
/* connect client and server CCBs */
|
/* connect client and server CCBs */
|
||||||
Ccb->OtherSide = ClientCcb;
|
Ccb->OtherSide = ClientCcb;
|
||||||
ClientCcb->OtherSide = Ccb;
|
ClientCcb->OtherSide = Ccb;
|
||||||
|
|
||||||
/* set connected state */
|
/* set connected state */
|
||||||
Ccb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
Ccb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
||||||
ClientCcb->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 */
|
/* signal client's connect event */
|
||||||
DPRINT("Setting the ConnectEvent for %x\n", ClientCcb);
|
DPRINT("Setting the ConnectEvent for %x\n", ClientCcb);
|
||||||
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
|
||||||
return STATUS_PIPE_CONNECTED;
|
return STATUS_PIPE_CONNECTED;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no listening client fcb found */
|
/* no listening client fcb found */
|
||||||
DPRINT("No listening client fcb found -- waiting for client\n");
|
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)
|
if (Flags & FO_SYNCHRONOUS_IO)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Ccb->ConnectEvent,
|
KeWaitForSingleObject(&Ccb->ConnectEvent,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
Irp->RequestorMode,
|
Irp->RequestorMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
|
DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
NpfsDisconnectPipe(PNPFS_CCB Ccb)
|
NpfsDisconnectPipe(PNPFS_CCB Ccb)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB OtherSide;
|
PNPFS_CCB OtherSide;
|
||||||
BOOLEAN Server;
|
BOOLEAN Server;
|
||||||
|
|
||||||
DPRINT("NpfsDisconnectPipe()\n");
|
DPRINT("NpfsDisconnectPipe()\n");
|
||||||
|
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
KeLockMutex(&Fcb->CcbListLock);
|
KeLockMutex(&Fcb->CcbListLock);
|
||||||
|
|
||||||
if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
|
if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
|
||||||
{
|
{
|
||||||
DPRINT("Pipe is already disconnected\n");
|
DPRINT("Pipe is already disconnected\n");
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
else if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||||
{
|
{
|
||||||
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
|
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
|
||||||
OtherSide = Ccb->OtherSide;
|
OtherSide = Ccb->OtherSide;
|
||||||
//Ccb->OtherSide = NULL;
|
//Ccb->OtherSide = NULL;
|
||||||
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||||
/* Lock the server first */
|
/* Lock the server first */
|
||||||
if (Server)
|
if (Server)
|
||||||
{
|
{
|
||||||
ExAcquireFastMutex(&Ccb->DataListLock);
|
ExAcquireFastMutex(&Ccb->DataListLock);
|
||||||
ExAcquireFastMutex(&OtherSide->DataListLock);
|
ExAcquireFastMutex(&OtherSide->DataListLock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExAcquireFastMutex(&OtherSide->DataListLock);
|
ExAcquireFastMutex(&OtherSide->DataListLock);
|
||||||
ExAcquireFastMutex(&Ccb->DataListLock);
|
ExAcquireFastMutex(&Ccb->DataListLock);
|
||||||
}
|
}
|
||||||
OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||||
//OtherSide->OtherSide = NULL;
|
//OtherSide->OtherSide = NULL;
|
||||||
/*
|
/*
|
||||||
* Signaling the write event. If is possible that an other
|
* Signaling the write event. If is possible that an other
|
||||||
* thread waits for an empty buffer.
|
* thread waits for an empty buffer.
|
||||||
*/
|
*/
|
||||||
KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
|
||||||
KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
|
||||||
if (Server)
|
if (Server)
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&OtherSide->DataListLock);
|
ExReleaseFastMutex(&OtherSide->DataListLock);
|
||||||
ExReleaseFastMutex(&Ccb->DataListLock);
|
ExReleaseFastMutex(&Ccb->DataListLock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&Ccb->DataListLock);
|
ExReleaseFastMutex(&Ccb->DataListLock);
|
||||||
ExReleaseFastMutex(&OtherSide->DataListLock);
|
ExReleaseFastMutex(&OtherSide->DataListLock);
|
||||||
}
|
}
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
|
else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
PNPFS_WAITER_ENTRY WaitEntry = NULL;
|
PNPFS_WAITER_ENTRY WaitEntry = NULL;
|
||||||
BOOLEAN Complete = FALSE;
|
BOOLEAN Complete = FALSE;
|
||||||
PIRP Irp = NULL;
|
PIRP Irp = NULL;
|
||||||
|
|
||||||
Entry = Ccb->Fcb->WaiterListHead.Flink;
|
Entry = Ccb->Fcb->WaiterListHead.Flink;
|
||||||
while (Entry != &Ccb->Fcb->WaiterListHead)
|
while (Entry != &Ccb->Fcb->WaiterListHead)
|
||||||
{
|
{
|
||||||
WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
|
WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
|
||||||
if (WaitEntry->Ccb == Ccb)
|
if (WaitEntry->Ccb == Ccb)
|
||||||
{
|
{
|
||||||
RemoveEntryList(Entry);
|
RemoveEntryList(Entry);
|
||||||
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
|
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
|
||||||
Complete = (NULL == IoSetCancelRoutine(Irp, NULL));
|
Complete = (NULL == IoSetCancelRoutine(Irp, NULL));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Irp)
|
if (Irp)
|
||||||
{
|
{
|
||||||
if (Complete)
|
if (Complete)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
|
else if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
|
||||||
{
|
{
|
||||||
Status = STATUS_PIPE_CLOSING;
|
Status = STATUS_PIPE_CLOSING;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
KeUnlockMutex(&Fcb->CcbListLock);
|
KeUnlockMutex(&Fcb->CcbListLock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
NpfsWaitPipe(PIRP Irp,
|
NpfsWaitPipe(PIRP Irp,
|
||||||
PNPFS_CCB Ccb)
|
PNPFS_CCB Ccb)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB ServerCcb;
|
PNPFS_CCB ServerCcb;
|
||||||
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
|
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
LARGE_INTEGER TimeOut;
|
LARGE_INTEGER TimeOut;
|
||||||
|
|
||||||
DPRINT("NpfsWaitPipe\n");
|
DPRINT("NpfsWaitPipe\n");
|
||||||
|
|
||||||
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
if (Ccb->PipeState != 0)
|
if (Ccb->PipeState != 0)
|
||||||
{
|
{
|
||||||
DPRINT("Pipe is not in passive (waiting) state!\n");
|
DPRINT("Pipe is not in passive (waiting) state!\n");
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search for listening server */
|
/* search for listening server */
|
||||||
current_entry = Fcb->ServerCcbListHead.Flink;
|
current_entry = Fcb->ServerCcbListHead.Flink;
|
||||||
while (current_entry != &Fcb->ServerCcbListHead)
|
while (current_entry != &Fcb->ServerCcbListHead)
|
||||||
{
|
{
|
||||||
ServerCcb = CONTAINING_RECORD(current_entry,
|
ServerCcb = CONTAINING_RECORD(current_entry,
|
||||||
NPFS_CCB,
|
NPFS_CCB,
|
||||||
CcbListEntry);
|
CcbListEntry);
|
||||||
|
|
||||||
if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||||
{
|
{
|
||||||
/* found a listening server CCB */
|
/* found a listening server CCB */
|
||||||
DPRINT("Listening server CCB found -- connecting\n");
|
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 no timeout specified, use the default one */
|
||||||
if (WaitPipe->TimeoutSpecified)
|
if (WaitPipe->TimeoutSpecified)
|
||||||
TimeOut = WaitPipe->Timeout;
|
TimeOut = WaitPipe->Timeout;
|
||||||
else
|
else
|
||||||
TimeOut = Fcb->TimeOut;
|
TimeOut = Fcb->TimeOut;
|
||||||
|
|
||||||
/* Wait for one */
|
/* Wait for one */
|
||||||
Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
|
Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
&TimeOut);
|
&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
|
static NTSTATUS
|
||||||
NpfsPeekPipe(PIRP Irp,
|
NpfsPeekPipe(PIRP Irp,
|
||||||
PIO_STACK_LOCATION IoStack)
|
PIO_STACK_LOCATION IoStack)
|
||||||
{
|
{
|
||||||
ULONG OutputBufferLength;
|
ULONG OutputBufferLength;
|
||||||
ULONG ReturnLength = 0;
|
ULONG ReturnLength = 0;
|
||||||
PFILE_PIPE_PEEK_BUFFER Reply;
|
PFILE_PIPE_PEEK_BUFFER Reply;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB Ccb;
|
PNPFS_CCB Ccb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG MessageCount = 0;
|
ULONG MessageCount = 0;
|
||||||
ULONG MessageLength;
|
ULONG MessageLength;
|
||||||
ULONG ReadDataAvailable;
|
ULONG ReadDataAvailable;
|
||||||
PVOID BufferPtr;
|
PVOID BufferPtr;
|
||||||
|
|
||||||
DPRINT("NpfsPeekPipe\n");
|
DPRINT("NpfsPeekPipe\n");
|
||||||
|
|
||||||
OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
|
OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
DPRINT("OutputBufferLength: %lu\n", OutputBufferLength);
|
DPRINT("OutputBufferLength: %lu\n", OutputBufferLength);
|
||||||
|
|
||||||
/* Validate parameters */
|
/* Validate parameters */
|
||||||
if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
|
if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
|
||||||
{
|
{
|
||||||
DPRINT1("Buffer too small\n");
|
DPRINT1("Buffer too small\n");
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ccb = IoStack->FileObject->FsContext2;
|
Ccb = IoStack->FileObject->FsContext2;
|
||||||
Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
|
|
||||||
|
|
||||||
Reply->NamedPipeState = Ccb->PipeState;
|
Reply->NamedPipeState = Ccb->PipeState;
|
||||||
|
|
||||||
Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
|
Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
|
||||||
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
|
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
|
||||||
|
|
||||||
ExAcquireFastMutex(&Ccb->DataListLock);
|
ExAcquireFastMutex(&Ccb->DataListLock);
|
||||||
BufferPtr = Ccb->ReadPtr;
|
BufferPtr = Ccb->ReadPtr;
|
||||||
DPRINT("BufferPtr = %x\n", BufferPtr);
|
DPRINT("BufferPtr = %x\n", BufferPtr);
|
||||||
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
|
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
|
||||||
{
|
{
|
||||||
DPRINT("Byte Stream Mode\n");
|
DPRINT("Byte Stream Mode\n");
|
||||||
Reply->MessageLength = Ccb->ReadDataAvailable;
|
Reply->MessageLength = Ccb->ReadDataAvailable;
|
||||||
DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength );
|
DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength );
|
||||||
MessageCount = 1;
|
MessageCount = 1;
|
||||||
|
|
||||||
if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
|
if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
|
||||||
{
|
{
|
||||||
ReturnLength = Ccb->ReadDataAvailable;
|
ReturnLength = Ccb->ReadDataAvailable;
|
||||||
memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
|
memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("Message Mode\n");
|
DPRINT("Message Mode\n");
|
||||||
ReadDataAvailable=Ccb->ReadDataAvailable;
|
ReadDataAvailable=Ccb->ReadDataAvailable;
|
||||||
|
|
||||||
if (ReadDataAvailable > 0)
|
if (ReadDataAvailable > 0)
|
||||||
{
|
{
|
||||||
memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
|
memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
|
||||||
|
|
||||||
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
|
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
|
||||||
{
|
{
|
||||||
memcpy(&MessageLength, BufferPtr, sizeof(MessageLength));
|
memcpy(&MessageLength, BufferPtr, sizeof(MessageLength));
|
||||||
|
|
||||||
ASSERT(MessageLength > 0);
|
ASSERT(MessageLength > 0);
|
||||||
|
|
||||||
DPRINT("MessageLength = %lu\n",MessageLength);
|
DPRINT("MessageLength = %lu\n",MessageLength);
|
||||||
ReadDataAvailable -= MessageLength;
|
ReadDataAvailable -= MessageLength;
|
||||||
MessageCount++;
|
MessageCount++;
|
||||||
|
|
||||||
/* If its the first message, copy the Message if the size of buffer is large enough */
|
/* If its the first message, copy the Message if the size of buffer is large enough */
|
||||||
if (MessageCount==1)
|
if (MessageCount==1)
|
||||||
{
|
{
|
||||||
if ((Reply->Data[0])
|
if ((Reply->Data[0])
|
||||||
&& (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
|
&& (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
|
||||||
{
|
{
|
||||||
memcpy(&Reply->Data[0], (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)), MessageLength);
|
memcpy(&Reply->Data[0], (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)), MessageLength);
|
||||||
ReturnLength = MessageLength;
|
ReturnLength = MessageLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferPtr =(PVOID)((ULONG_PTR)BufferPtr + MessageLength + sizeof(MessageLength));
|
BufferPtr =(PVOID)((ULONG_PTR)BufferPtr + MessageLength + sizeof(MessageLength));
|
||||||
DPRINT("BufferPtr = %x\n", BufferPtr);
|
DPRINT("BufferPtr = %x\n", BufferPtr);
|
||||||
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
|
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadDataAvailable != 0)
|
if (ReadDataAvailable != 0)
|
||||||
{
|
{
|
||||||
DPRINT1("Possible memory corruption.\n");
|
DPRINT1("Possible memory corruption.\n");
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExReleaseFastMutex(&Ccb->DataListLock);
|
ExReleaseFastMutex(&Ccb->DataListLock);
|
||||||
|
|
||||||
Reply->NumberOfMessages = MessageCount;
|
Reply->NumberOfMessages = MessageCount;
|
||||||
|
|
||||||
Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
|
Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
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
|
NTSTATUS NTAPI
|
||||||
NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB Ccb;
|
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;
|
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
DPRINT("IoStack: %p\n", IoStack);
|
DPRINT("IoStack: %p\n", IoStack);
|
||||||
FileObject = IoStack->FileObject;
|
FileObject = IoStack->FileObject;
|
||||||
DPRINT("FileObject: %p\n", FileObject);
|
DPRINT("FileObject: %p\n", FileObject);
|
||||||
Ccb = FileObject->FsContext2;
|
Ccb = FileObject->FsContext2;
|
||||||
DPRINT("CCB: %p\n", Ccb);
|
DPRINT("CCB: %p\n", Ccb);
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
DPRINT("Pipe: %p\n", Fcb);
|
DPRINT("Pipe: %p\n", Fcb);
|
||||||
DPRINT("PipeName: %wZ\n", &Fcb->PipeName);
|
DPRINT("PipeName: %wZ\n", &Fcb->PipeName);
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
switch (IoStack->Parameters.FileSystemControl.FsControlCode)
|
switch (IoStack->Parameters.FileSystemControl.FsControlCode)
|
||||||
{
|
{
|
||||||
case FSCTL_PIPE_ASSIGN_EVENT:
|
case FSCTL_PIPE_ASSIGN_EVENT:
|
||||||
DPRINT1("Assign event not implemented\n");
|
DPRINT1("Assign event not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_DISCONNECT:
|
case FSCTL_PIPE_DISCONNECT:
|
||||||
DPRINT("Disconnecting pipe %wZ\n", &Fcb->PipeName);
|
DPRINT("Disconnecting pipe %wZ\n", &Fcb->PipeName);
|
||||||
Status = NpfsDisconnectPipe(Ccb);
|
Status = NpfsDisconnectPipe(Ccb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_LISTEN:
|
case FSCTL_PIPE_LISTEN:
|
||||||
DPRINT("Connecting pipe %wZ\n", &Fcb->PipeName);
|
DPRINT("Connecting pipe %wZ\n", &Fcb->PipeName);
|
||||||
Status = NpfsConnectPipe(Irp, Ccb);
|
Status = NpfsConnectPipe(Irp, Ccb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_PEEK:
|
case FSCTL_PIPE_PEEK:
|
||||||
DPRINT("Peeking pipe %wZ\n", &Fcb->PipeName);
|
DPRINT("Peeking pipe %wZ\n", &Fcb->PipeName);
|
||||||
Status = NpfsPeekPipe(Irp, (PIO_STACK_LOCATION)IoStack);
|
Status = NpfsPeekPipe(Irp, (PIO_STACK_LOCATION)IoStack);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_QUERY_EVENT:
|
case FSCTL_PIPE_QUERY_EVENT:
|
||||||
DPRINT1("Query event not implemented\n");
|
DPRINT1("Query event not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_TRANSCEIVE:
|
case FSCTL_PIPE_TRANSCEIVE:
|
||||||
/* If you implement this, please remove the workaround in
|
/* If you implement this, please remove the workaround in
|
||||||
lib/kernel32/file/npipe.c function TransactNamedPipe() */
|
lib/kernel32/file/npipe.c function TransactNamedPipe() */
|
||||||
DPRINT1("Transceive not implemented\n");
|
DPRINT1("Transceive not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_WAIT:
|
case FSCTL_PIPE_WAIT:
|
||||||
DPRINT("Waiting for pipe %wZ\n", &Fcb->PipeName);
|
DPRINT("Waiting for pipe %wZ\n", &Fcb->PipeName);
|
||||||
Status = NpfsWaitPipe(Irp, Ccb);
|
Status = NpfsWaitPipe(Irp, Ccb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_IMPERSONATE:
|
case FSCTL_PIPE_IMPERSONATE:
|
||||||
DPRINT1("Impersonate not implemented\n");
|
DPRINT1("Impersonate not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
||||||
DPRINT1("Set client process not implemented\n");
|
DPRINT1("Set client process not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
||||||
DPRINT1("Query client process not implemented\n");
|
DPRINT1("Query client process not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_READ:
|
case FSCTL_PIPE_INTERNAL_READ:
|
||||||
DPRINT1("Internal read not implemented\n");
|
DPRINT1("Internal read not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_WRITE:
|
case FSCTL_PIPE_INTERNAL_WRITE:
|
||||||
DPRINT1("Internal write not implemented\n");
|
DPRINT1("Internal write not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
||||||
DPRINT1("Internal transceive not implemented\n");
|
DPRINT1("Internal transceive not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
|
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
|
||||||
DPRINT1("Internal read overflow not implemented\n");
|
DPRINT1("Internal read overflow not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINT1("Unrecognized IoControlCode: %x\n",
|
DPRINT1("Unrecognized IoControlCode: %x\n",
|
||||||
IoStack->Parameters.FileSystemControl.FsControlCode);
|
IoStack->Parameters.FileSystemControl.FsControlCode);
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status != STATUS_PENDING)
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject,
|
NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -17,73 +17,73 @@
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject,
|
DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
PUNICODE_STRING RegistryPath)
|
PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
PNPFS_DEVICE_EXTENSION DeviceExtension;
|
PNPFS_DEVICE_EXTENSION DeviceExtension;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
NTSTATUS Status;
|
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_CONTEXT) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
|
||||||
ASSERT (sizeof(NPFS_WAITER_ENTRY) <= 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] = NpfsCreate;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
|
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
|
||||||
NpfsCreateNamedPipe;
|
NpfsCreateNamedPipe;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpfsClose;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpfsClose;
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = NpfsRead;
|
DriverObject->MajorFunction[IRP_MJ_READ] = NpfsRead;
|
||||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = NpfsWrite;
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = NpfsWrite;
|
||||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||||
NpfsQueryInformation;
|
NpfsQueryInformation;
|
||||||
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
|
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
|
||||||
NpfsSetInformation;
|
NpfsSetInformation;
|
||||||
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
|
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
|
||||||
NpfsQueryVolumeInformation;
|
NpfsQueryVolumeInformation;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
|
||||||
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
|
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
|
||||||
// DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
// DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||||
// NpfsDirectoryControl;
|
// NpfsDirectoryControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
NpfsFileSystemControl;
|
NpfsFileSystemControl;
|
||||||
// DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =
|
// DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =
|
||||||
// NpfsQuerySecurity;
|
// NpfsQuerySecurity;
|
||||||
// DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =
|
// DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =
|
||||||
// NpfsSetSecurity;
|
// NpfsSetSecurity;
|
||||||
|
|
||||||
DriverObject->DriverUnload = NULL;
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
|
||||||
Status = IoCreateDevice(DriverObject,
|
Status = IoCreateDevice(DriverObject,
|
||||||
sizeof(NPFS_DEVICE_EXTENSION),
|
sizeof(NPFS_DEVICE_EXTENSION),
|
||||||
&DeviceName,
|
&DeviceName,
|
||||||
FILE_DEVICE_NAMED_PIPE,
|
FILE_DEVICE_NAMED_PIPE,
|
||||||
0,
|
0,
|
||||||
FALSE,
|
FALSE,
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
|
DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the device object */
|
/* initialize the device object */
|
||||||
DeviceObject->Flags |= DO_DIRECT_IO;
|
DeviceObject->Flags |= DO_DIRECT_IO;
|
||||||
|
|
||||||
/* initialize the device extension */
|
/* initialize the device extension */
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
InitializeListHead(&DeviceExtension->PipeListHead);
|
InitializeListHead(&DeviceExtension->PipeListHead);
|
||||||
InitializeListHead(&DeviceExtension->ThreadListHead);
|
InitializeListHead(&DeviceExtension->ThreadListHead);
|
||||||
KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
|
KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
|
||||||
DeviceExtension->EmptyWaiterCount = 0;
|
DeviceExtension->EmptyWaiterCount = 0;
|
||||||
|
|
||||||
/* set the size quotas */
|
/* set the size quotas */
|
||||||
DeviceExtension->MinQuota = PAGE_SIZE;
|
DeviceExtension->MinQuota = PAGE_SIZE;
|
||||||
DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
|
DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
|
||||||
DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
|
DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -6,82 +6,82 @@
|
||||||
|
|
||||||
typedef struct _NPFS_DEVICE_EXTENSION
|
typedef struct _NPFS_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
LIST_ENTRY PipeListHead;
|
LIST_ENTRY PipeListHead;
|
||||||
LIST_ENTRY ThreadListHead;
|
LIST_ENTRY ThreadListHead;
|
||||||
KMUTEX PipeListLock;
|
KMUTEX PipeListLock;
|
||||||
ULONG EmptyWaiterCount;
|
ULONG EmptyWaiterCount;
|
||||||
ULONG MinQuota;
|
ULONG MinQuota;
|
||||||
ULONG DefaultQuota;
|
ULONG DefaultQuota;
|
||||||
ULONG MaxQuota;
|
ULONG MaxQuota;
|
||||||
} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
|
} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _NPFS_FCB
|
typedef struct _NPFS_FCB
|
||||||
{
|
{
|
||||||
FSRTL_COMMON_FCB_HEADER RFCB;
|
FSRTL_COMMON_FCB_HEADER RFCB;
|
||||||
UNICODE_STRING PipeName;
|
UNICODE_STRING PipeName;
|
||||||
LIST_ENTRY PipeListEntry;
|
LIST_ENTRY PipeListEntry;
|
||||||
KMUTEX CcbListLock;
|
KMUTEX CcbListLock;
|
||||||
LIST_ENTRY ServerCcbListHead;
|
LIST_ENTRY ServerCcbListHead;
|
||||||
LIST_ENTRY ClientCcbListHead;
|
LIST_ENTRY ClientCcbListHead;
|
||||||
LIST_ENTRY WaiterListHead;
|
LIST_ENTRY WaiterListHead;
|
||||||
LIST_ENTRY EmptyBufferListHead;
|
LIST_ENTRY EmptyBufferListHead;
|
||||||
ULONG PipeType;
|
ULONG PipeType;
|
||||||
ULONG ClientReadMode;
|
ULONG ClientReadMode;
|
||||||
ULONG ServerReadMode;
|
ULONG ServerReadMode;
|
||||||
ULONG CompletionMode;
|
ULONG CompletionMode;
|
||||||
ULONG PipeConfiguration;
|
ULONG PipeConfiguration;
|
||||||
ULONG MaximumInstances;
|
ULONG MaximumInstances;
|
||||||
ULONG CurrentInstances;
|
ULONG CurrentInstances;
|
||||||
ULONG InboundQuota;
|
ULONG InboundQuota;
|
||||||
ULONG OutboundQuota;
|
ULONG OutboundQuota;
|
||||||
LARGE_INTEGER TimeOut;
|
LARGE_INTEGER TimeOut;
|
||||||
} NPFS_FCB, *PNPFS_FCB;
|
} NPFS_FCB, *PNPFS_FCB;
|
||||||
|
|
||||||
typedef struct _NPFS_CCB
|
typedef struct _NPFS_CCB
|
||||||
{
|
{
|
||||||
LIST_ENTRY CcbListEntry;
|
LIST_ENTRY CcbListEntry;
|
||||||
struct _NPFS_CCB* OtherSide;
|
struct _NPFS_CCB* OtherSide;
|
||||||
struct ETHREAD *Thread;
|
struct ETHREAD *Thread;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
KEVENT ConnectEvent;
|
KEVENT ConnectEvent;
|
||||||
KEVENT ReadEvent;
|
KEVENT ReadEvent;
|
||||||
KEVENT WriteEvent;
|
KEVENT WriteEvent;
|
||||||
ULONG PipeEnd;
|
ULONG PipeEnd;
|
||||||
ULONG PipeState;
|
ULONG PipeState;
|
||||||
ULONG ReadDataAvailable;
|
ULONG ReadDataAvailable;
|
||||||
ULONG WriteQuotaAvailable;
|
ULONG WriteQuotaAvailable;
|
||||||
|
|
||||||
LIST_ENTRY ReadRequestListHead;
|
LIST_ENTRY ReadRequestListHead;
|
||||||
|
|
||||||
PVOID Data;
|
PVOID Data;
|
||||||
PVOID ReadPtr;
|
PVOID ReadPtr;
|
||||||
PVOID WritePtr;
|
PVOID WritePtr;
|
||||||
ULONG MaxDataLength;
|
ULONG MaxDataLength;
|
||||||
|
|
||||||
FAST_MUTEX DataListLock; /* Data queue lock */
|
FAST_MUTEX DataListLock; /* Data queue lock */
|
||||||
} NPFS_CCB, *PNPFS_CCB;
|
} NPFS_CCB, *PNPFS_CCB;
|
||||||
|
|
||||||
typedef struct _NPFS_CONTEXT
|
typedef struct _NPFS_CONTEXT
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PKEVENT WaitEvent;
|
PKEVENT WaitEvent;
|
||||||
} NPFS_CONTEXT, *PNPFS_CONTEXT;
|
} NPFS_CONTEXT, *PNPFS_CONTEXT;
|
||||||
|
|
||||||
typedef struct _NPFS_THREAD_CONTEXT
|
typedef struct _NPFS_THREAD_CONTEXT
|
||||||
{
|
{
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
|
PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
|
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
PIRP WaitIrpArray[MAXIMUM_WAIT_OBJECTS];
|
PIRP WaitIrpArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
} NPFS_THREAD_CONTEXT, *PNPFS_THREAD_CONTEXT;
|
} NPFS_THREAD_CONTEXT, *PNPFS_THREAD_CONTEXT;
|
||||||
|
|
||||||
typedef struct _NPFS_WAITER_ENTRY
|
typedef struct _NPFS_WAITER_ENTRY
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
PNPFS_CCB Ccb;
|
PNPFS_CCB Ccb;
|
||||||
} NPFS_WAITER_ENTRY, *PNPFS_WAITER_ENTRY;
|
} NPFS_WAITER_ENTRY, *PNPFS_WAITER_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,10 +89,10 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
|
||||||
|
|
||||||
|
|
||||||
#define KeLockMutex(x) KeWaitForSingleObject(x, \
|
#define KeLockMutex(x) KeWaitForSingleObject(x, \
|
||||||
UserRequest, \
|
UserRequest, \
|
||||||
KernelMode, \
|
KernelMode, \
|
||||||
FALSE, \
|
FALSE, \
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
|
#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
|
||||||
|
|
||||||
|
@ -133,6 +133,6 @@ NTSTATUS NTAPI NpfsQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject,
|
DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
PUNICODE_STRING RegistryPath);
|
PUNICODE_STRING RegistryPath);
|
||||||
|
|
||||||
#endif /* __DRIVERS_FS_NP_NPFS_H */
|
#endif /* __DRIVERS_FS_NP_NPFS_H */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,99 +17,99 @@
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
|
NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
DPRINT("NpfsQueryFsDeviceInformation()\n");
|
DPRINT("NpfsQueryFsDeviceInformation()\n");
|
||||||
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
|
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
|
||||||
|
|
||||||
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
|
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
|
FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE;
|
||||||
FsDeviceInfo->Characteristics = 0;
|
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
|
static NTSTATUS
|
||||||
NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
|
NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
DPRINT("NpfsQueryFsAttributeInformation() called.\n");
|
DPRINT("NpfsQueryFsAttributeInformation() called.\n");
|
||||||
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
|
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
|
||||||
|
|
||||||
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
|
if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
|
FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
|
||||||
FsAttributeInfo->MaximumComponentNameLength = 255;
|
FsAttributeInfo->MaximumComponentNameLength = 255;
|
||||||
FsAttributeInfo->FileSystemNameLength = 8;
|
FsAttributeInfo->FileSystemNameLength = 8;
|
||||||
wcscpy(FsAttributeInfo->FileSystemName,
|
wcscpy(FsAttributeInfo->FileSystemName,
|
||||||
L"NPFS");
|
L"NPFS");
|
||||||
|
|
||||||
DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
|
DPRINT("NpfsQueryFsAttributeInformation() finished.\n");
|
||||||
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
|
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
|
NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
FS_INFORMATION_CLASS FsInformationClass;
|
FS_INFORMATION_CLASS FsInformationClass;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PVOID SystemBuffer;
|
PVOID SystemBuffer;
|
||||||
ULONG BufferLength;
|
ULONG BufferLength;
|
||||||
|
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
ASSERT(DeviceObject != NULL);
|
ASSERT(DeviceObject != NULL);
|
||||||
ASSERT(Irp != NULL);
|
ASSERT(Irp != NULL);
|
||||||
|
|
||||||
DPRINT("NpfsQueryVolumeInformation(DeviceObject %p, Irp %p)\n",
|
DPRINT("NpfsQueryVolumeInformation(DeviceObject %p, Irp %p)\n",
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
Irp);
|
Irp);
|
||||||
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
|
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
|
||||||
BufferLength = Stack->Parameters.QueryVolume.Length;
|
BufferLength = Stack->Parameters.QueryVolume.Length;
|
||||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
DPRINT("FsInformationClass %d\n", FsInformationClass);
|
DPRINT("FsInformationClass %d\n", FsInformationClass);
|
||||||
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
||||||
|
|
||||||
switch (FsInformationClass)
|
switch (FsInformationClass)
|
||||||
{
|
{
|
||||||
case FileFsDeviceInformation:
|
case FileFsDeviceInformation:
|
||||||
Status = NpfsQueryFsDeviceInformation(SystemBuffer,
|
Status = NpfsQueryFsDeviceInformation(SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FileFsAttributeInformation:
|
case FileFsAttributeInformation:
|
||||||
Status = NpfsQueryFsAttributeInformation(SystemBuffer,
|
Status = NpfsQueryFsAttributeInformation(SystemBuffer,
|
||||||
&BufferLength);
|
&BufferLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Status = STATUS_NOT_SUPPORTED;
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength;
|
Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength;
|
||||||
else
|
else
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp,
|
IoCompleteRequest(Irp,
|
||||||
IO_NO_INCREMENT);
|
IO_NO_INCREMENT);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue