mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 14:30:57 +00:00
167 lines
5.2 KiB
C
167 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 */
|