reactos/drivers/filesystems/npfs/read.c

237 lines
6.2 KiB
C

/*
* 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 ******************************************************************/
BOOLEAN
NTAPI
NpCommonRead(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;
}
NTSTATUS
NTAPI
NpFsdRead(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_
BOOLEAN
NTAPI
NpFastRead(
_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 */