Something went wrong. Try again.
Reactos
Something went wrong. Try again.
6.3 kB · 237 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238/* * PROJECT: ReactOS Named Pipe FileSystem * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/filesystems/npfs/read.c * PURPOSE: Pipes Reading * PROGRAMMERS: ReactOS Portable Systems Group */
/* INCLUDES *******************************************************************/
#include "npfs.h"
// File ID number for NPFS bugchecking support#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_READ)
/* GLOBALS ********************************************************************/
LONG NpSlowReadCalls;ULONG NpFastReadTrue;ULONG NpFastReadFalse;
/* FUNCTIONS ******************************************************************/
BOOLEANNTAPINpCommonRead(IN PFILE_OBJECT FileObject, IN PVOID Buffer, IN ULONG BufferSize, OUT PIO_STATUS_BLOCK IoStatus, IN PIRP Irp, IN PLIST_ENTRY List){ NODE_TYPE_CODE NodeType; PNP_DATA_QUEUE ReadQueue; PNP_EVENT_BUFFER EventBuffer; NTSTATUS Status; ULONG NamedPipeEnd; PNP_CCB Ccb; PNP_NONPAGED_CCB NonPagedCcb; BOOLEAN ReadOk; PAGED_CODE();
IoStatus->Information = 0; NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
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);
if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE || Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) { IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_DISCONNECTED_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_DISCONNECTED; ReadOk = TRUE; goto Quickie; }
ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) || (NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND)) { IoStatus->Status = STATUS_INVALID_PARAMETER; ReadOk = TRUE; goto Quickie; }
if (NamedPipeEnd == FILE_PIPE_SERVER_END) { ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND]; } else { ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND]; }
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
if (ReadQueue->QueueState == WriteEntries) { *IoStatus = NpReadDataQueue(ReadQueue, FALSE, FALSE, Buffer, BufferSize, Ccb->ReadMode[NamedPipeEnd], Ccb, List); if (!NT_SUCCESS(IoStatus->Status)) { ReadOk = TRUE; goto Quickie; }
ReadOk = TRUE; if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE); goto Quickie; }
if (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE) { IoStatus->Status = STATUS_PIPE_BROKEN; ReadOk = TRUE; if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE); goto Quickie; }
if (Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION) { IoStatus->Status = STATUS_PIPE_EMPTY; ReadOk = TRUE; if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE); goto Quickie; }
if (!Irp) { ReadOk = FALSE; goto Quickie; }
Status = NpAddDataQueueEntry(NamedPipeEnd, Ccb, ReadQueue, ReadEntries, Buffered, BufferSize, Irp, NULL, 0); IoStatus->Status = Status; if (!NT_SUCCESS(Status)) { ReadOk = FALSE; } else { ReadOk = TRUE; if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE); }
Quickie: ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock); return ReadOk;}
NTSTATUSNTAPINpFsdRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION IoStack; IO_STATUS_BLOCK IoStatus; LIST_ENTRY DeferredList; PAGED_CODE(); NpSlowReadCalls++;
InitializeListHead(&DeferredList); IoStack = IoGetCurrentIrpStackLocation(Irp);
FsRtlEnterFileSystem(); NpAcquireSharedVcb();
NpCommonRead(IoStack->FileObject, Irp->UserBuffer, IoStack->Parameters.Read.Length, &IoStatus, Irp, &DeferredList);
NpReleaseVcb(); NpCompleteDeferredIrps(&DeferredList); 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;}
_Function_class_(FAST_IO_READ)_IRQL_requires_same_BOOLEANNTAPINpFastRead( _In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER FileOffset, _In_ ULONG Length, _In_ BOOLEAN Wait, _In_ ULONG LockKey, _Out_ PVOID Buffer, _Out_ PIO_STATUS_BLOCK IoStatus, _In_ PDEVICE_OBJECT DeviceObject){ LIST_ENTRY DeferredList; BOOLEAN Result; PAGED_CODE();
InitializeListHead(&DeferredList);
FsRtlEnterFileSystem(); NpAcquireSharedVcb();
Result = NpCommonRead(FileObject, Buffer, Length, IoStatus, NULL, &DeferredList); if (Result) ++NpFastReadTrue; else ++NpFastReadFalse;
NpReleaseVcb(); NpCompleteDeferredIrps(&DeferredList); FsRtlExitFileSystem();
return Result;}
/* EOF */