/* * 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 */