mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[NPFS-NEW]: Implement Close, Cleanup, Disconnect, Flush, Listen, Peek, SetInfo, Transceive, Wait, Write. Only QueryInfo remains as critical functionality to support the Kernel32 APIs. Code is WIP, untested, and ugly! But it is now 90% complete. r60000 should hopefully finalize the implementation. As long as I didn't forget a file :)
svn path=/trunk/; revision=59999
This commit is contained in:
parent
b5edd2ce20
commit
3dfdce74d8
14 changed files with 2057 additions and 106 deletions
|
@ -1,8 +1,13 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
cleanup.c
|
||||
close.c
|
||||
create.c
|
||||
datasup.c
|
||||
fileinfo.c
|
||||
fileobsup.c
|
||||
flushbuf.c
|
||||
fsctrl.c
|
||||
main.c
|
||||
prefxsup.c
|
||||
read.c
|
||||
|
@ -10,7 +15,9 @@ list(APPEND SOURCE
|
|||
secursup.c
|
||||
statesup.c
|
||||
strucsup.c
|
||||
waitsup.c)
|
||||
waitsup.c
|
||||
write.c
|
||||
writesup.c)
|
||||
|
||||
add_library(npfs_new SHARED ${SOURCE})
|
||||
set_module_type(npfs_new kernelmodedriver)
|
||||
|
|
73
reactos/drivers/filesystems/npfs_new/cleanup.c
Normal file
73
reactos/drivers/filesystems/npfs_new/cleanup.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
LIST_ENTRY List;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
PLIST_ENTRY ThisEntry, NextEntry;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
InitializeListHead(&List);
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB )
|
||||
{
|
||||
if ( ServerSide == 1 )
|
||||
{
|
||||
ASSERT(Ccb->Fcb->ServerOpenCount != 0);
|
||||
--Ccb->Fcb->ServerOpenCount;
|
||||
}
|
||||
|
||||
NpSetClosingPipeState(Ccb, Irp, ServerSide, &List);
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
NextEntry = List.Flink;
|
||||
while (NextEntry != &List)
|
||||
{
|
||||
ThisEntry = NextEntry;
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
|
||||
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
|
||||
Status = NpCommonCleanup(DeviceObject, Irp);
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
68
reactos/drivers/filesystems/npfs_new/close.c
Normal file
68
reactos/drivers/filesystems/npfs_new/close.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
LIST_ENTRY List;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
PLIST_ENTRY ThisEntry, NextEntry;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
InitializeListHead(&List);
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if (NodeTypeCode == NPFS_NTC_ROOT_DCB)
|
||||
{
|
||||
--Fcb->CurrentInstances;
|
||||
NpDeleteCcb(Ccb, &List);
|
||||
}
|
||||
else if (NodeTypeCode == NPFS_NTC_VCB)
|
||||
{
|
||||
--NpVcb->ReferenceCount;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
NextEntry = List.Flink;
|
||||
while (NextEntry != &List)
|
||||
{
|
||||
ThisEntry = NextEntry;
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
|
||||
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
|
||||
Status = NpCommonClose(DeviceObject, Irp);
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
178
reactos/drivers/filesystems/npfs_new/fileinfo.c
Normal file
178
reactos/drivers/filesystems/npfs_new/fileinfo.c
Normal file
|
@ -0,0 +1,178 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetBasicInfo(IN PNP_CCB Ccb,
|
||||
IN PFILE_BASIC_INFORMATION Buffer)
|
||||
{
|
||||
PAGED_CODE();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetPipeInfo(IN PNP_FCB Fcb,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PFILE_PIPE_INFORMATION Buffer,
|
||||
IN ULONG ServerSide,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
||||
ULONG CompletionMode;
|
||||
PAGED_CODE();
|
||||
|
||||
if ( Buffer->ReadMode == FILE_PIPE_MESSAGE_MODE && Fcb->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE )
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ( ServerSide )
|
||||
{
|
||||
if ( ServerSide != 1 ) KeBugCheckEx(NPFS_FILE_SYSTEM, 0xA04EFu, ServerSide, 0, 0);
|
||||
ReadQueue = &Ccb->InQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
CompletionMode = Ccb->ServerCompletionMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
CompletionMode = Ccb->ClientCompletionMode;
|
||||
}
|
||||
|
||||
if ( Buffer->CompletionMode != FILE_PIPE_COMPLETE_OPERATION ||
|
||||
CompletionMode == FILE_PIPE_COMPLETE_OPERATION ||
|
||||
(ReadQueue->QueueState == ReadEntries &&
|
||||
WriteQueue->QueueState != WriteEntries ))
|
||||
{
|
||||
if (ServerSide)
|
||||
{
|
||||
Ccb->ServerReadMode = Buffer->ReadMode & 0xFF;
|
||||
Ccb->ServerCompletionMode = Buffer->CompletionMode & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ccb->ClientReadMode = Buffer->ReadMode & 0xFF;
|
||||
Ccb->ClientCompletionMode = Buffer->CompletionMode & 0xFF;
|
||||
}
|
||||
|
||||
NpCheckForNotify(Fcb->ParentDcb, 0, List);
|
||||
Status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_PIPE_BUSY;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
ULONG InfoClass;
|
||||
PVOID Buffer;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if ( !NodeTypeCode ) return STATUS_PIPE_DISCONNECTED;
|
||||
if ( NodeTypeCode != NPFS_NTC_CCB ) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
InfoClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
if ( InfoClass == FileBasicInformation ) return NpSetBasicInfo(Ccb, Buffer);
|
||||
|
||||
if ( InfoClass != FilePipeInformation ) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
return NpSetPipeInfo(Fcb, Ccb, Buffer, ServerSide, List);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LIST_ENTRY List;
|
||||
PLIST_ENTRY NextEntry, ThisEntry;
|
||||
PAGED_CODE();
|
||||
|
||||
InitializeListHead(&List);
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
Status = NpCommonSetInformation(DeviceObject, Irp, &List);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
NextEntry = List.Flink;
|
||||
while (NextEntry != &List)
|
||||
{
|
||||
ThisEntry = NextEntry;
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
|
||||
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
}
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
Status = NpCommonQueryInformation(DeviceObject, Irp);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
68
reactos/drivers/filesystems/npfs_new/flushbuf.c
Normal file
68
reactos/drivers/filesystems/npfs_new/flushbuf.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
NTSTATUS Status;
|
||||
PNP_DATA_QUEUE FlushQueue;
|
||||
PAGED_CODE();
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoGetCurrentIrpStackLocation(Irp)->FileObject,
|
||||
NULL,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if (NodeTypeCode != NPFS_NTC_CCB ) return STATUS_PIPE_DISCONNECTED;
|
||||
|
||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||
//ms_exc.registration.TryLevel = 0;
|
||||
|
||||
FlushQueue = &Ccb->OutQueue;
|
||||
if ( ServerSide != 1 ) FlushQueue = &Ccb->InQueue;
|
||||
|
||||
if ( FlushQueue->QueueState == WriteEntries)
|
||||
{
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Ccb,
|
||||
FlushQueue,
|
||||
1,
|
||||
2u,
|
||||
0,
|
||||
Irp,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
Status = NpCommonFlushBuffers(DeviceObject, Irp);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
692
reactos/drivers/filesystems/npfs_new/fsctrl.c
Normal file
692
reactos/drivers/filesystems/npfs_new/fsctrl.c
Normal file
|
@ -0,0 +1,692 @@
|
|||
#include "npfs.h"
|
||||
|
||||
IO_STATUS_BLOCK NpUserIoStatusBlock;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpInternalTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpInternalRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN BOOLEAN Overflow,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpInternalWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryClientProcess(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetClientProcess(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpAssignEvent(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryEvent(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpImpersonate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
BOOLEAN ServerSide;
|
||||
PNP_CCB Ccb;
|
||||
NTSTATUS Status;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||
{
|
||||
if ( ServerSide == 1 )
|
||||
{
|
||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||
|
||||
Status = NpSetDisconnectedPipeState(Ccb, List);
|
||||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_ILLEGAL_FUNCTION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpListen(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
BOOLEAN ServerSide;
|
||||
PNP_CCB Ccb;
|
||||
NTSTATUS Status;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||
{
|
||||
if ( ServerSide == 1 )
|
||||
{
|
||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||
|
||||
Status = NpSetListeningPipeState(Ccb, Irp, List);
|
||||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_ILLEGAL_FUNCTION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_ILLEGAL_FUNCTION;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NODE_TYPE_CODE Type;
|
||||
ULONG InputLength;
|
||||
BOOLEAN ServerSide;
|
||||
PNP_CCB Ccb;
|
||||
PFILE_PIPE_PEEK_BUFFER PeekBuffer;
|
||||
PNP_DATA_QUEUE DataQueue;
|
||||
ULONG BytesPeeked;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
NTSTATUS Status;
|
||||
PNP_DATA_QUEUE_ENTRY DataEntry;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
InputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
||||
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
if (!Type) return STATUS_PIPE_DISCONNECTED;
|
||||
|
||||
if ((Type != NPFS_NTC_CCB) && (InputLength < sizeof(*PeekBuffer)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PeekBuffer = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||
if ( ServerSide )
|
||||
{
|
||||
if ( ServerSide != 1 )
|
||||
{
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD02E5, ServerSide, 0, 0);
|
||||
}
|
||||
DataQueue = &Ccb->InQueue;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataQueue = &Ccb->OutQueue;
|
||||
}
|
||||
|
||||
if ( Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE )
|
||||
{
|
||||
if ( Ccb->NamedPipeState != FILE_PIPE_CLOSING_STATE )
|
||||
{
|
||||
return STATUS_INVALID_PIPE_STATE;
|
||||
}
|
||||
if ( DataQueue->QueueState != WriteEntries)
|
||||
{
|
||||
return STATUS_PIPE_BROKEN;
|
||||
}
|
||||
}
|
||||
|
||||
PeekBuffer->NamedPipeState = 0;
|
||||
PeekBuffer->ReadDataAvailable = 0;
|
||||
PeekBuffer->NumberOfMessages = 0;
|
||||
PeekBuffer->MessageLength = 0;
|
||||
PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
|
||||
BytesPeeked = sizeof(*PeekBuffer);
|
||||
|
||||
if ( DataQueue->QueueState == WriteEntries)
|
||||
{
|
||||
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
||||
NP_DATA_QUEUE_ENTRY,
|
||||
QueueEntry);
|
||||
ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));
|
||||
|
||||
PeekBuffer->ReadDataAvailable = DataQueue->BytesInQueue - DataQueue->ByteOffset;
|
||||
if ( Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE)
|
||||
{
|
||||
PeekBuffer->NumberOfMessages = DataQueue->EntriesInQueue;
|
||||
PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
|
||||
}
|
||||
if ( InputLength == sizeof(*PeekBuffer) )
|
||||
{
|
||||
Status = PeekBuffer->ReadDataAvailable != 0 ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
IoStatus = NpReadDataQueue(DataQueue,
|
||||
TRUE,
|
||||
FALSE,
|
||||
PeekBuffer->Data,
|
||||
InputLength - sizeof(*PeekBuffer),
|
||||
Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE,
|
||||
Ccb,
|
||||
List);
|
||||
Status = IoStatus.Status;
|
||||
BytesPeeked = IoStatus.Information + sizeof(*PeekBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = BytesPeeked;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCompleteTransceiveIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if ( Irp->AssociatedIrp.SystemBuffer )
|
||||
{
|
||||
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
||||
}
|
||||
|
||||
IoFreeIrp(Irp);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PVOID InBuffer, OutBuffer;
|
||||
ULONG InLength, OutLength, ReadMode, BytesWritten;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
NTSTATUS Status;
|
||||
PIRP NewIrp;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
InLength = IoStack->Parameters.FileSystemControl.InputBufferLength;
|
||||
InBuffer = IoStack->Parameters.FileSystemControl.Type3InputBuffer;
|
||||
OutLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
||||
OutBuffer = Irp->UserBuffer;
|
||||
|
||||
if ( Irp->RequestorMode == UserMode)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(InBuffer, InLength, sizeof(CHAR));
|
||||
ProbeForWrite(OutBuffer, OutLength, sizeof(CHAR));
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
if (NodeTypeCode != NPFS_NTC_CCB )
|
||||
{
|
||||
return STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
|
||||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
||||
|
||||
//ms_exc.registration.TryLevel = 1;
|
||||
if ( Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE )
|
||||
{
|
||||
Status = STATUS_INVALID_PIPE_STATE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( ServerSide )
|
||||
{
|
||||
if ( ServerSide != 1 ) KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD0538, ServerSide, 0, 0);
|
||||
ReadQueue = &Ccb->InQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
ReadMode = Ccb->ServerReadMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
ReadMode = Ccb->ClientReadMode;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
}
|
||||
|
||||
if (Ccb->Fcb->NamedPipeConfiguration != FILE_PIPE_FULL_DUPLEX ||
|
||||
ReadMode != FILE_PIPE_MESSAGE_MODE )
|
||||
{
|
||||
Status = STATUS_INVALID_PIPE_STATE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( ReadQueue->QueueState != Empty)
|
||||
{
|
||||
Status = STATUS_PIPE_BUSY;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
Status = NpWriteDataQueue(WriteQueue,
|
||||
1,
|
||||
InBuffer,
|
||||
InLength,
|
||||
Ccb->Fcb->NamedPipeType,
|
||||
&BytesWritten,
|
||||
Ccb,
|
||||
ServerSide,
|
||||
Irp->Tail.Overlay.Thread,
|
||||
List);
|
||||
if ( Status == STATUS_MORE_PROCESSING_REQUIRED )
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
NewIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||
if ( !NewIrp )
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
IoSetCompletionRoutine(Irp, NpCompleteTransceiveIrp, NULL, TRUE, TRUE, TRUE);
|
||||
|
||||
if ( BytesWritten )
|
||||
{
|
||||
NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool, BytesWritten, 'wFpN');
|
||||
if ( !NewIrp->AssociatedIrp.SystemBuffer )
|
||||
{
|
||||
IoFreeIrp(NewIrp);
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
RtlCopyMemory(NewIrp->AssociatedIrp.SystemBuffer,
|
||||
(PVOID)((ULONG_PTR)InBuffer + InLength - BytesWritten),
|
||||
BytesWritten);
|
||||
//ms_exc.registration.TryLevel = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewIrp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
|
||||
IoStack = IoGetNextIrpStackLocation(NewIrp);
|
||||
IoSetNextIrpStackLocation(NewIrp);
|
||||
|
||||
NewIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
|
||||
NewIrp->IoStatus.Information = BytesWritten;
|
||||
|
||||
IoStack->Parameters.Read.Length = BytesWritten;
|
||||
IoStack->MajorFunction = IRP_MJ_WRITE;
|
||||
|
||||
if ( BytesWritten > 0 ) NewIrp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
|
||||
NewIrp->UserIosb = &NpUserIoStatusBlock;
|
||||
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Ccb,
|
||||
WriteQueue,
|
||||
WriteEntries,
|
||||
1,
|
||||
BytesWritten,
|
||||
NewIrp,
|
||||
NULL,
|
||||
0);
|
||||
if ( Status != STATUS_PENDING )
|
||||
{
|
||||
NewIrp->IoStatus.Status = Status;
|
||||
InsertTailList(List, &NewIrp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
ASSERT(ReadQueue->QueueState == Empty);
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Ccb,
|
||||
ReadQueue,
|
||||
ReadEntries,
|
||||
0,
|
||||
OutLength,
|
||||
Irp,
|
||||
NULL,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
}
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
ULONG InLength, NameLength;
|
||||
UNICODE_STRING SourceString, Prefix;
|
||||
BOOLEAN ServerSide;
|
||||
PNP_CCB Ccb;
|
||||
PFILE_PIPE_WAIT_FOR_BUFFER Buffer;
|
||||
NTSTATUS Status;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PNP_FCB Fcb;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
InLength = IoStack->Parameters.DeviceIoControl.InputBufferLength;
|
||||
|
||||
SourceString.Buffer = NULL;
|
||||
|
||||
//ms_exc.registration.TryLevel = 0;
|
||||
|
||||
if (NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide) != NPFS_NTC_ROOT_DCB )
|
||||
{
|
||||
Status = STATUS_ILLEGAL_FUNCTION;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
Buffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||
if (InLength < sizeof(*Buffer))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
NameLength = Buffer->NameLength;
|
||||
if ((NameLength > 0xFFFD) || ((NameLength + sizeof(*Buffer)) > InLength ))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
||||
SourceString.Buffer = ExAllocatePoolWithTag(PagedPool, SourceString.Length, 'WFpN');
|
||||
if (!SourceString.Buffer )
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
SourceString.Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
|
||||
RtlCopyMemory(&SourceString.Buffer[1], Buffer->Name, Buffer->NameLength);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
//Status = NpTranslateAlias(&SourceString);
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
Fcb = NpFindPrefix(&SourceString, TRUE, &Prefix);
|
||||
Fcb = (PNP_FCB)((ULONG_PTR)Fcb & ~1);
|
||||
|
||||
NodeTypeCode = Fcb ? Fcb->NodeType : 0;
|
||||
if ( NodeTypeCode != NPFS_NTC_FCB )
|
||||
{
|
||||
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
for (NextEntry = Fcb->CcbList.Flink;
|
||||
NextEntry != &Fcb->CcbList;
|
||||
NextEntry = NextEntry->Flink)
|
||||
{
|
||||
Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry);
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE ) break;
|
||||
}
|
||||
|
||||
if ( NextEntry == &Fcb->CcbList )
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = NpAddWaiter(&NpVcb->WaitQueue,
|
||||
Fcb->Timeout,
|
||||
Irp,
|
||||
&SourceString);
|
||||
}
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
if ( SourceString.Buffer ) ExFreePool(SourceString.Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG Fsctl;
|
||||
BOOLEAN Overflow = FALSE;
|
||||
LIST_ENTRY List;
|
||||
PLIST_ENTRY NextEntry, ThisEntry;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
InitializeListHead(&List);
|
||||
Fsctl = IoGetCurrentIrpStackLocation(Irp)->Parameters.FileSystemControl.FsControlCode;
|
||||
|
||||
switch (Fsctl)
|
||||
{
|
||||
case FSCTL_PIPE_PEEK:
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpPeek(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_WRITE:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
Status = NpInternalWrite(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_TRANSCEIVE:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
Status = NpTransceive(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
Status = NpInternalTransceive(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
|
||||
Overflow = TRUE;
|
||||
// on purpose
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_READ:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
Status = NpInternalRead(DeviceObject, Irp, Overflow, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
||||
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
Status = NpQueryClientProcess(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_ASSIGN_EVENT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpAssignEvent(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_DISCONNECT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpDisconnect(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_LISTEN:
|
||||
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
Status = NpListen(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_QUERY_EVENT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpQueryEvent(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_WAIT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpWaitForNamedPipe(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_IMPERSONATE:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpImpersonate(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
Status = NpSetClientProcess(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
NextEntry = List.Flink;
|
||||
while (NextEntry != &List)
|
||||
{
|
||||
ThisEntry = NextEntry;
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
|
||||
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
|
||||
Status = NpCommonFileSystemControl(DeviceObject, Irp);
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
@ -4,8 +4,8 @@ PDEVICE_OBJECT NpfsDeviceObject;
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
NpFsdSetSecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
|
@ -18,36 +18,8 @@ NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
NpFsdQuerySecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
|
@ -72,34 +44,6 @@ NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -114,20 +58,6 @@ NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
|
@ -152,14 +82,12 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
|||
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpFsdFlushBuffers;
|
||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = NpFsdDirectoryControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = NpFsdFileSystemControl;
|
||||
// DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =
|
||||
// NpfsQuerySecurity;
|
||||
// DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =
|
||||
// NpfsSetSecurity;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = NpFsdQuerySecurity;
|
||||
DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = NpFsdSetSecurity;
|
||||
|
||||
DriverObject->DriverUnload = NULL;
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe2");
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(NP_VCB),
|
||||
&DeviceName,
|
||||
|
|
|
@ -82,6 +82,19 @@ typedef struct _NP_WAIT_QUEUE
|
|||
KSPIN_LOCK WaitLock;
|
||||
} NP_WAIT_QUEUE, *PNP_WAIT_QUEUE;
|
||||
|
||||
//
|
||||
// The Entries in the Queue above, one for each Waiter.
|
||||
//
|
||||
typedef struct _NP_WAIT_QUEUE_ENTRY
|
||||
{
|
||||
PIRP Irp;
|
||||
KDPC Dpc;
|
||||
KTIMER Timer;
|
||||
PNP_WAIT_QUEUE WaitQueue;
|
||||
UNICODE_STRING String;
|
||||
PFILE_OBJECT FileObject;
|
||||
} NP_WAIT_QUEUE_ENTRY, *PNP_WAIT_QUEUE_ENTRY;
|
||||
|
||||
//
|
||||
// The event buffer in the NonPaged CCB
|
||||
//
|
||||
|
@ -225,6 +238,11 @@ typedef struct _NP_VCB
|
|||
|
||||
extern PNP_VCB NpVcb;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
|
||||
IN PVOID Buffer);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue);
|
||||
|
@ -320,12 +338,47 @@ NTAPI
|
|||
NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetConnectedPipeState(IN PNP_CCB Ccb,
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetListeningPipeState(IN PNP_CCB Ccb,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetClosingPipeState(IN PNP_CCB Ccb,
|
||||
IN PIRP Irp,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext);
|
||||
|
@ -386,6 +439,13 @@ NpCheckForNotify(IN PNP_DCB Dcb,
|
|||
IN BOOLEAN SecondList,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||
IN LARGE_INTEGER WaitTime,
|
||||
IN PIRP Irp,
|
||||
IN PUNICODE_STRING Name);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||
|
@ -405,8 +465,43 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
IN PNP_CCB Ccb,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||
IN ULONG Mode,
|
||||
IN PVOID OutBuffer,
|
||||
IN ULONG OutBufferSize,
|
||||
IN ULONG PipeType,
|
||||
OUT PULONG BytesWritten,
|
||||
IN PNP_CCB Ccb,
|
||||
IN BOOLEAN ServerSide,
|
||||
IN PETHREAD Thread,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NODE_TYPE_CODE NodeType;
|
||||
ULONG NamedPipeConfiguation;
|
||||
PNP_DATA_QUEUE Queue;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
NTSTATUS Status;
|
||||
|
@ -51,10 +50,8 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
|
||||
ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
|
||||
|
||||
NamedPipeConfiguation = Ccb->Fcb->NamedPipeConfiguration;
|
||||
|
||||
if ((ServerSide == 1 && NamedPipeConfiguation == FILE_PIPE_OUTBOUND) ||
|
||||
(ServerSide == 0 && NamedPipeConfiguation == FILE_PIPE_INBOUND) )
|
||||
if ((ServerSide == 1 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
|
||||
(ServerSide == 0 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND ))
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
ReadOk = TRUE;
|
||||
|
@ -109,30 +106,32 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( Irp )
|
||||
if ( !Irp )
|
||||
{
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Ccb,
|
||||
Queue,
|
||||
0,
|
||||
0,
|
||||
BufferSize,
|
||||
Irp,
|
||||
0,
|
||||
0);
|
||||
IoStatus->Status = Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ReadOk = FALSE;
|
||||
goto Quickie;
|
||||
}
|
||||
ReadOk = FALSE;
|
||||
goto Quickie;
|
||||
|
||||
}
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Ccb,
|
||||
Queue,
|
||||
0,
|
||||
0,
|
||||
BufferSize,
|
||||
Irp,
|
||||
0,
|
||||
0);
|
||||
IoStatus->Status = Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ReadOk = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadOk = TRUE;
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
ReadOk = FALSE;
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
|
@ -182,7 +181,7 @@ NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
Irp->IoStatus.Information = IoStatus.Information;
|
||||
Irp->IoStatus.Status = IoStatus.Status;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return IoStatus.Status;
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
#include "npfs.h"
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NpCancelListeningQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetConnectedPipeState(IN PNP_CCB Ccb,
|
||||
|
@ -37,3 +54,316 @@ NpSetConnectedPipeState(IN PNP_CCB Ccb,
|
|||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
PIRP Irp;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
NTSTATUS Status;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
|
||||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
|
||||
switch (Ccb->NamedPipeState)
|
||||
{
|
||||
case FILE_PIPE_DISCONNECTED_STATE:
|
||||
Status = STATUS_PIPE_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case FILE_PIPE_LISTENING_STATE:
|
||||
while (!IsListEmpty(&Ccb->IrpList))
|
||||
{
|
||||
NextEntry = RemoveHeadList(&Ccb->IrpList);
|
||||
|
||||
Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
|
||||
|
||||
if (IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, NextEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeListHead(NextEntry);
|
||||
}
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CONNECTED_STATE:
|
||||
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
while ( Ccb->OutQueue.QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->OutQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CLOSING_STATE:
|
||||
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(Ccb->OutQueue.QueueState == Empty);
|
||||
|
||||
NpDeleteEventTableEntry(&NpVcb->EventTable, EventBuffer);
|
||||
NonPagedCcb->EventBufferClient = NULL;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = NULL;
|
||||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
if ( Ccb->ClientSession )
|
||||
{
|
||||
ExFreePool(Ccb->ClientSession);
|
||||
Ccb->ClientSession = NULL;
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x1603DD, Ccb->NamedPipeState, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
Ccb->NamedPipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetListeningPipeState(IN PNP_CCB Ccb,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
switch (Ccb->NamedPipeState)
|
||||
{
|
||||
case FILE_PIPE_DISCONNECTED_STATE:
|
||||
|
||||
Status = NpCancelWaiter(&NpVcb->WaitQueue,
|
||||
&Ccb->Fcb->FullName,
|
||||
STATUS_SUCCESS,
|
||||
List);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
//
|
||||
// Drop down on purpose
|
||||
//
|
||||
|
||||
case FILE_PIPE_LISTENING_STATE:
|
||||
|
||||
if ( Ccb->ServerCompletionMode == FILE_PIPE_COMPLETE_OPERATION)
|
||||
{
|
||||
Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
|
||||
return STATUS_PIPE_LISTENING;
|
||||
}
|
||||
|
||||
IoSetCancelRoutine(Irp, NpCancelListeningQueueIrp);
|
||||
if ( Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
return STATUS_CANCELLED;
|
||||
}
|
||||
|
||||
Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
|
||||
IoMarkIrpPending(Irp);
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
return STATUS_PENDING;
|
||||
|
||||
case FILE_PIPE_CONNECTED_STATE:
|
||||
Status = STATUS_PIPE_CONNECTED;
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CLOSING_STATE:
|
||||
Status = STATUS_PIPE_CLOSING;
|
||||
break;
|
||||
|
||||
default:
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x160133, Ccb->NamedPipeState, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetClosingPipeState(IN PNP_CCB Ccb,
|
||||
IN PIRP Irp,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
PNP_FCB Fcb;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PNP_DATA_QUEUE ReadQueue, WriteQueue, DataQueue;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
|
||||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
Fcb = Ccb->Fcb;
|
||||
|
||||
switch (Ccb->NamedPipeState)
|
||||
{
|
||||
case FILE_PIPE_LISTENING_STATE:
|
||||
|
||||
ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
|
||||
|
||||
while (!IsListEmpty(&Ccb->IrpList))
|
||||
{
|
||||
NextEntry = RemoveHeadList(&Ccb->IrpList);
|
||||
|
||||
Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
|
||||
|
||||
if (IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, NextEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeListHead(NextEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// Drop on purpose
|
||||
|
||||
case FILE_PIPE_DISCONNECTED_STATE:
|
||||
|
||||
ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
|
||||
|
||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
||||
Ccb->ServerFileObject = NULL;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = NULL;
|
||||
|
||||
NpDeleteCcb(Ccb, List);
|
||||
if ( !Fcb->CurrentInstances ) NpDeleteFcb(Fcb, List);
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CLOSING_STATE:
|
||||
|
||||
if ( NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
DataQueue = &Ccb->InQueue;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataQueue = &Ccb->OutQueue;
|
||||
}
|
||||
|
||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
||||
Ccb->ServerFileObject = NULL;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = NULL;
|
||||
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
if ( Ccb->ClientSession )
|
||||
{
|
||||
ExFreePool(Ccb->ClientSession);
|
||||
Ccb->ClientSession = 0;
|
||||
}
|
||||
|
||||
NpDeleteCcb(Ccb, List);
|
||||
if ( !Fcb->CurrentInstances ) NpDeleteFcb(Fcb, List);
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CONNECTED_STATE:
|
||||
if ( NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
ReadQueue = &Ccb->InQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
|
||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
||||
Ccb->ServerFileObject = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = 0;
|
||||
}
|
||||
|
||||
Ccb->NamedPipeState = FILE_PIPE_CLOSING_STATE;
|
||||
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
while (WriteQueue->QueueState == WriteEntries)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(WriteQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
KeBugCheckEx(0x25u, 0x1602F9, Ccb->NamedPipeState, 0, 0);
|
||||
break;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,10 @@ NTAPI
|
|||
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
if (!Buffer) return FALSE;
|
||||
|
||||
ObfDereferenceObject(((PNP_EVENT_BUFFER)Buffer)->Event);
|
||||
return RtlDeleteElementGenericTable(Table, Buffer);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -1,5 +1,76 @@
|
|||
#include "npfs.h"
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PNP_WAIT_QUEUE_ENTRY WaitEntry;
|
||||
PNP_WAIT_QUEUE WaitQueue;
|
||||
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
|
||||
WaitQueue = (PNP_WAIT_QUEUE)Irp->Tail.Overlay.DriverContext[0];
|
||||
|
||||
OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
|
||||
|
||||
WaitEntry = (PNP_WAIT_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[1];
|
||||
if ( WaitEntry )
|
||||
{
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
if ( !KeCancelTimer(&WaitEntry->Timer) )
|
||||
{
|
||||
WaitEntry->Irp = NULL;
|
||||
WaitEntry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
||||
|
||||
if ( WaitEntry )
|
||||
{
|
||||
ObfDereferenceObject(WaitEntry->FileObject);
|
||||
ExFreePool(WaitEntry);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NpTimerDispatch(IN PKDPC Dpc,
|
||||
IN PVOID Context,
|
||||
IN PVOID Argument1,
|
||||
IN PVOID Argument2)
|
||||
{
|
||||
PIRP Irp;
|
||||
KIRQL OldIrql;
|
||||
PNP_WAIT_QUEUE_ENTRY WaitEntry = Context;
|
||||
|
||||
OldIrql = KfAcquireSpinLock(&WaitEntry->WaitQueue->WaitLock);
|
||||
Irp = WaitEntry->Irp;
|
||||
if ( Irp);
|
||||
{
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
if ( !IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
Irp->Tail.Overlay.DriverContext[1] = NULL;
|
||||
Irp = NULL;
|
||||
}
|
||||
}
|
||||
KfReleaseSpinLock(&WaitEntry->WaitQueue->WaitLock, OldIrql);
|
||||
if ( Irp )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
ObfDereferenceObject(WaitEntry->FileObject);
|
||||
ExFreePoolWithTag(WaitEntry, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue)
|
||||
|
@ -33,3 +104,88 @@ NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
ExFreePool(DestinationString.Buffer);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||
IN LARGE_INTEGER WaitTime,
|
||||
IN PIRP Irp,
|
||||
IN PUNICODE_STRING Name)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
KIRQL OldIrql;
|
||||
NTSTATUS Status;
|
||||
PNP_WAIT_QUEUE_ENTRY WaitEntry;
|
||||
PFILE_PIPE_WAIT_FOR_BUFFER WaitBuffer;
|
||||
LARGE_INTEGER DueTime;
|
||||
ULONG i;
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*WaitEntry), 'wFpN');
|
||||
if ( WaitEntry )
|
||||
{
|
||||
KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
|
||||
KeInitializeTimer(&WaitEntry->Timer);
|
||||
|
||||
if ( Name )
|
||||
{
|
||||
WaitEntry->String = *Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitEntry->String.Length = 0;
|
||||
WaitEntry->String.Buffer = 0;
|
||||
}
|
||||
|
||||
WaitEntry->WaitQueue = WaitQueue;
|
||||
WaitEntry->Irp = Irp;
|
||||
|
||||
WaitBuffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||
if ( WaitBuffer->TimeoutSpecified )
|
||||
{
|
||||
DueTime = WaitBuffer->Timeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
DueTime = WaitTime;
|
||||
}
|
||||
|
||||
for (i = 0; i < WaitBuffer->NameLength / sizeof(WCHAR); i++)
|
||||
{
|
||||
WaitBuffer->Name[i] = RtlUpcaseUnicodeChar(WaitBuffer->Name[i]);
|
||||
}
|
||||
|
||||
Irp->Tail.Overlay.DriverContext[0] = WaitQueue;
|
||||
Irp->Tail.Overlay.DriverContext[1] = WaitEntry;
|
||||
OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
|
||||
|
||||
IoSetCancelRoutine(Irp, NpCancelWaitQueueIrp);
|
||||
|
||||
if ( Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
Status = STATUS_CANCELLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertTailList(&WaitQueue->WaitList, &Irp->Tail.Overlay.ListEntry);
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
Status = STATUS_PENDING;
|
||||
|
||||
WaitEntry->FileObject = IoStack->FileObject;
|
||||
ObfReferenceObject(WaitEntry->FileObject);
|
||||
|
||||
KeSetTimer(&WaitEntry->Timer, DueTime, &WaitEntry->Dpc);
|
||||
WaitEntry = NULL;
|
||||
|
||||
}
|
||||
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
||||
if ( WaitEntry ) ExFreePool(WaitEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
|
204
reactos/drivers/filesystems/npfs_new/write.c
Normal file
204
reactos/drivers/filesystems/npfs_new/write.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
#include "npfs.h"
|
||||
|
||||
LONG NpSlowWriteCalls;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
NpCommonWrite(IN PFILE_OBJECT FileObject,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG DataSize,
|
||||
IN PETHREAD Thread,
|
||||
IN PIO_STATUS_BLOCK IoStatus,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NODE_TYPE_CODE NodeType;
|
||||
BOOLEAN WriteOk, ServerSide;
|
||||
PNP_CCB Ccb;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
PNP_DATA_QUEUE WriteQueue;
|
||||
NTSTATUS Status;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
ULONG BytesWritten;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStatus->Information = 0;
|
||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &ServerSide);
|
||||
|
||||
if (!NodeType)
|
||||
{
|
||||
IoStatus->Status = STATUS_PIPE_DISCONNECTED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( NodeType != NPFS_NTC_CCB )
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
||||
|
||||
// ms_exc.registration.TryLevel = 0;
|
||||
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE )
|
||||
{
|
||||
IoStatus->Status = STATUS_PIPE_DISCONNECTED;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE || Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE )
|
||||
{
|
||||
IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_LISTENING_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_CLOSING;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
ASSERT(Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE);
|
||||
|
||||
if ((ServerSide == 1 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) ||
|
||||
(ServerSide == 0 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND))
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
IoStatus->Status = 0;
|
||||
IoStatus->Information = DataSize;
|
||||
|
||||
if ( ServerSide == 1 )
|
||||
{
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
}
|
||||
|
||||
if (WriteQueue->QueueState != ReadEntries ||
|
||||
WriteQueue->BytesInQueue >= DataSize ||
|
||||
WriteQueue->Quota >= DataSize - WriteQueue->BytesInQueue )
|
||||
{
|
||||
if (WriteQueue->QueueState != ReadEntries ||
|
||||
WriteQueue->Quota - WriteQueue->QuotaUsed >= DataSize )
|
||||
{
|
||||
goto DoWrite;
|
||||
}
|
||||
}
|
||||
|
||||
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE &&
|
||||
Ccb->ServerCompletionMode & FILE_PIPE_COMPLETE_OPERATION)
|
||||
{
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = 0;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if (!Irp )
|
||||
{
|
||||
WriteOk = 0;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
DoWrite:
|
||||
Status = NpWriteDataQueue(WriteQueue,
|
||||
ServerSide ? Ccb->ClientReadMode : Ccb->ServerReadMode,
|
||||
Buffer,
|
||||
DataSize,
|
||||
Ccb->Fcb->NamedPipeType,
|
||||
&BytesWritten,
|
||||
Ccb,
|
||||
ServerSide,
|
||||
Thread,
|
||||
List);
|
||||
IoStatus->Status = Status;
|
||||
if ( Status == STATUS_MORE_PROCESSING_REQUIRED )
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
if ( (Ccb->ServerCompletionMode & FILE_PIPE_COMPLETE_OPERATION || !Irp)
|
||||
&& WriteQueue->Quota - WriteQueue->QuotaUsed < BytesWritten )
|
||||
{
|
||||
IoStatus->Information = DataSize - BytesWritten;
|
||||
IoStatus->Status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
|
||||
IoStatus->Status = NpAddDataQueueEntry(ServerSide,
|
||||
Ccb,
|
||||
WriteQueue,
|
||||
WriteEntries,
|
||||
0,
|
||||
DataSize,
|
||||
Irp,
|
||||
Buffer,
|
||||
DataSize - BytesWritten);
|
||||
}
|
||||
}
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
WriteOk = 1;
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
return WriteOk;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
LIST_ENTRY List;
|
||||
PLIST_ENTRY NextEntry, ThisEntry;
|
||||
PAGED_CODE();
|
||||
NpSlowWriteCalls++;
|
||||
|
||||
InitializeListHead(&List);
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
NpCommonWrite(IoStack->FileObject,
|
||||
Irp->UserBuffer,
|
||||
IoStack->Parameters.Write.Length,
|
||||
Irp->Tail.Overlay.Thread,
|
||||
&IoStatus,
|
||||
Irp,
|
||||
&List);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
NextEntry = List.Flink;
|
||||
while (NextEntry != &List)
|
||||
{
|
||||
ThisEntry = NextEntry;
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
|
||||
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
}
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( IoStatus.Status != STATUS_PENDING )
|
||||
{
|
||||
Irp->IoStatus.Information = IoStatus.Information;
|
||||
Irp->IoStatus.Status = IoStatus.Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return IoStatus.Status;
|
||||
}
|
||||
|
151
reactos/drivers/filesystems/npfs_new/writesup.c
Normal file
151
reactos/drivers/filesystems/npfs_new/writesup.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||
IN ULONG Mode,
|
||||
IN PVOID OutBuffer,
|
||||
IN ULONG OutBufferSize,
|
||||
IN ULONG PipeType,
|
||||
OUT PULONG BytesWritten,
|
||||
IN PNP_CCB Ccb,
|
||||
IN BOOLEAN ServerSide,
|
||||
IN PETHREAD Thread,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
BOOLEAN HaveContext = FALSE, MoreProcessing, AllocatedBuffer;
|
||||
PNP_DATA_QUEUE_ENTRY DataEntry;
|
||||
ULONG DataSize, BufferSize;
|
||||
PIRP WriteIrp;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PVOID Buffer;
|
||||
NTSTATUS Status;
|
||||
PSECURITY_CLIENT_CONTEXT ClientContext;
|
||||
PAGED_CODE();
|
||||
|
||||
*BytesWritten = OutBufferSize;
|
||||
|
||||
MoreProcessing = 1;
|
||||
if ( PipeType != FILE_PIPE_OUTBOUND || (OutBufferSize) ) MoreProcessing = 0;
|
||||
|
||||
for (DataEntry = NpGetNextRealDataQueueEntry(WriteQueue, List);
|
||||
((WriteQueue->QueueState == ReadEntries) &&
|
||||
((*BytesWritten > 0) || (MoreProcessing)));
|
||||
DataEntry = NpGetNextRealDataQueueEntry(WriteQueue, List))
|
||||
{
|
||||
DataSize = DataEntry->DataSize;
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation( DataEntry->Irp);
|
||||
|
||||
if ( IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
|
||||
IoStack->Parameters.FileSystemControl.FsControlCode == FSCTL_PIPE_INTERNAL_WRITE &&
|
||||
(DataSize < OutBufferSize || MoreProcessing) )
|
||||
{
|
||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, 1, List);
|
||||
if (WriteIrp )
|
||||
{
|
||||
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( DataEntry->DataEntryType == Unbuffered )
|
||||
{
|
||||
DataEntry->Irp->Overlay.AllocationSize.QuadPart = 0;
|
||||
}
|
||||
|
||||
BufferSize = *BytesWritten;
|
||||
if ( BufferSize >= DataSize ) BufferSize = DataSize;
|
||||
|
||||
if ( DataEntry->DataEntryType != Unbuffered && BufferSize )
|
||||
{
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, 'RFpN');
|
||||
if ( !Buffer ) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
AllocatedBuffer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
||||
AllocatedBuffer = 0;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
RtlCopyMemory(Buffer,
|
||||
(PVOID)((ULONG_PTR)OutBuffer + OutBufferSize - *BytesWritten),
|
||||
BufferSize);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if ( !HaveContext )
|
||||
{
|
||||
HaveContext = 1;
|
||||
Status = NpGetClientSecurityContext(ServerSide, Ccb, Thread, &ClientContext);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if ( AllocatedBuffer ) ExFreePool(Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ( ClientContext )
|
||||
{
|
||||
NpFreeClientSecurityContext(Ccb->ClientContext);
|
||||
Ccb->ClientContext = ClientContext;
|
||||
}
|
||||
}
|
||||
|
||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, 1, List);
|
||||
if ( WriteIrp )
|
||||
{
|
||||
*BytesWritten -= BufferSize;
|
||||
WriteIrp->IoStatus.Information = BufferSize;
|
||||
|
||||
if ( AllocatedBuffer )
|
||||
{
|
||||
WriteIrp->AssociatedIrp.SystemBuffer = Buffer;
|
||||
WriteIrp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO | IRP_INPUT_OPERATION;
|
||||
}
|
||||
|
||||
if ( !*BytesWritten )
|
||||
{
|
||||
MoreProcessing = 0;
|
||||
WriteIrp->IoStatus.Status = 0;
|
||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( Mode == FILE_PIPE_MESSAGE_MODE )
|
||||
{
|
||||
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteIrp->IoStatus.Status = 0;
|
||||
}
|
||||
|
||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
else if ( AllocatedBuffer )
|
||||
{
|
||||
ExFreePool(Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if ( *BytesWritten > 0 || MoreProcessing )
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
Loading…
Reference in a new issue