reactos/drivers/filesystems/npfs/readsup.c

168 lines
5.2 KiB
C

/*
* PROJECT: ReactOS Named Pipe FileSystem
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: drivers/filesystems/npfs/readsup.c
* PURPOSE: Pipes Reading Support
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
#include "npfs.h"
// File ID number for NPFS bugchecking support
#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_READSUP)
/* FUNCTIONS ******************************************************************/
IO_STATUS_BLOCK
NTAPI
NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
IN BOOLEAN Peek,
IN BOOLEAN ReadOverflowOperation,
IN PVOID Buffer,
IN ULONG BufferSize,
IN ULONG Mode,
IN PNP_CCB Ccb,
IN PLIST_ENTRY List)
{
PNP_DATA_QUEUE_ENTRY DataEntry, TempDataEntry;
PVOID DataBuffer;
ULONG DataSize, DataLength, TotalBytesCopied, RemainingSize, Offset;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
BOOLEAN CompleteWrites = FALSE;
PAGED_CODE();
if (ReadOverflowOperation) Peek = TRUE;
RemainingSize = BufferSize;
IoStatus.Status = STATUS_SUCCESS;
TotalBytesCopied = 0;
if (Peek)
{
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
NP_DATA_QUEUE_ENTRY,
QueueEntry);
}
else
{
DataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(DataQueue, List),
NP_DATA_QUEUE_ENTRY,
QueueEntry);
}
while ((&DataEntry->QueueEntry != &DataQueue->Queue) && (RemainingSize))
{
if (!Peek ||
DataEntry->DataEntryType == Buffered ||
DataEntry->DataEntryType == Unbuffered)
{
if (DataEntry->DataEntryType == Unbuffered)
{
DataBuffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
}
else
{
DataBuffer = &DataEntry[1];
}
DataSize = DataEntry->DataSize;
Offset = DataSize;
if (&DataEntry->QueueEntry == DataQueue->Queue.Flink)
{
Offset -= DataQueue->ByteOffset;
}
DataLength = Offset;
if (DataLength >= RemainingSize) DataLength = RemainingSize;
_SEH2_TRY
{
RtlCopyMemory((PVOID)((ULONG_PTR)Buffer + BufferSize - RemainingSize),
(PVOID)((ULONG_PTR)DataBuffer + DataSize - Offset),
DataLength);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ASSERT(FALSE);
}
_SEH2_END;
RemainingSize -= DataLength;
Offset -= DataLength;
TotalBytesCopied += DataLength;
if (!Peek)
{
DataEntry->QuotaInEntry -= DataLength;
DataQueue->QuotaUsed -= DataLength;
DataQueue->ByteOffset += DataLength;
CompleteWrites = TRUE;
}
NpCopyClientContext(Ccb, DataEntry);
if ((Offset) || (ReadOverflowOperation && !TotalBytesCopied))
{
if (Mode == FILE_PIPE_MESSAGE_MODE)
{
IoStatus.Status = STATUS_BUFFER_OVERFLOW;
break;
}
}
else
{
if (!Peek || ReadOverflowOperation)
{
if (ReadOverflowOperation)
{
TempDataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(DataQueue, List),
NP_DATA_QUEUE_ENTRY,
QueueEntry);
ASSERT(TempDataEntry == DataEntry);
}
Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List);
if (Irp)
{
Irp->IoStatus.Information = DataSize;
Irp->IoStatus.Status = STATUS_SUCCESS;
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
}
}
if (Mode == FILE_PIPE_MESSAGE_MODE)
{
IoStatus.Status = STATUS_SUCCESS;
break;
}
ASSERT(!ReadOverflowOperation);
}
}
if (Peek)
{
DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink,
NP_DATA_QUEUE_ENTRY,
QueueEntry);
}
else
{
DataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(DataQueue, List),
NP_DATA_QUEUE_ENTRY,
QueueEntry);
}
}
IoStatus.Information = TotalBytesCopied;
if (CompleteWrites) NpCompleteStalledWrites(DataQueue, List);
return IoStatus;
}
/* EOF */