1 /* 2 * PROJECT: ReactOS Named Pipe FileSystem 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: drivers/filesystems/npfs/readsup.c 5 * PURPOSE: Pipes Reading Support 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "npfs.h" 12 13 // File ID number for NPFS bugchecking support 14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_READSUP) 15 16 /* FUNCTIONS ******************************************************************/ 17 18 IO_STATUS_BLOCK 19 NTAPI 20 NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue, 21 IN BOOLEAN Peek, 22 IN BOOLEAN ReadOverflowOperation, 23 IN PVOID Buffer, 24 IN ULONG BufferSize, 25 IN ULONG Mode, 26 IN PNP_CCB Ccb, 27 IN PLIST_ENTRY List) 28 { 29 PNP_DATA_QUEUE_ENTRY DataEntry, TempDataEntry; 30 PVOID DataBuffer; 31 ULONG DataSize, DataLength, TotalBytesCopied, RemainingSize, Offset; 32 PIRP Irp; 33 IO_STATUS_BLOCK IoStatus; 34 BOOLEAN CompleteWrites = FALSE; 35 PAGED_CODE(); 36 37 if (ReadOverflowOperation) Peek = TRUE; 38 39 RemainingSize = BufferSize; 40 IoStatus.Status = STATUS_SUCCESS; 41 TotalBytesCopied = 0; 42 43 if (Peek) 44 { 45 DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink, 46 NP_DATA_QUEUE_ENTRY, 47 QueueEntry); 48 } 49 else 50 { 51 DataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(DataQueue, List), 52 NP_DATA_QUEUE_ENTRY, 53 QueueEntry); 54 } 55 56 while ((&DataEntry->QueueEntry != &DataQueue->Queue) && (RemainingSize)) 57 { 58 if (!Peek || 59 DataEntry->DataEntryType == Buffered || 60 DataEntry->DataEntryType == Unbuffered) 61 { 62 if (DataEntry->DataEntryType == Unbuffered) 63 { 64 DataBuffer = DataEntry->Irp->AssociatedIrp.SystemBuffer; 65 } 66 else 67 { 68 DataBuffer = &DataEntry[1]; 69 } 70 71 DataSize = DataEntry->DataSize; 72 Offset = DataSize; 73 74 if (&DataEntry->QueueEntry == DataQueue->Queue.Flink) 75 { 76 Offset -= DataQueue->ByteOffset; 77 } 78 79 DataLength = Offset; 80 if (DataLength >= RemainingSize) DataLength = RemainingSize; 81 82 _SEH2_TRY 83 { 84 RtlCopyMemory((PVOID)((ULONG_PTR)Buffer + BufferSize - RemainingSize), 85 (PVOID)((ULONG_PTR)DataBuffer + DataSize - Offset), 86 DataLength); 87 } 88 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 89 { 90 ASSERT(FALSE); 91 } 92 _SEH2_END; 93 94 95 RemainingSize -= DataLength; 96 Offset -= DataLength; 97 TotalBytesCopied += DataLength; 98 99 if (!Peek) 100 { 101 DataEntry->QuotaInEntry -= DataLength; 102 DataQueue->QuotaUsed -= DataLength; 103 DataQueue->ByteOffset += DataLength; 104 CompleteWrites = TRUE; 105 } 106 107 NpCopyClientContext(Ccb, DataEntry); 108 109 if ((Offset) || (ReadOverflowOperation && !TotalBytesCopied)) 110 { 111 if (Mode == FILE_PIPE_MESSAGE_MODE) 112 { 113 IoStatus.Status = STATUS_BUFFER_OVERFLOW; 114 break; 115 } 116 } 117 else 118 { 119 if (!Peek || ReadOverflowOperation) 120 { 121 if (ReadOverflowOperation) 122 { 123 TempDataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(DataQueue, List), 124 NP_DATA_QUEUE_ENTRY, 125 QueueEntry); 126 ASSERT(TempDataEntry == DataEntry); 127 } 128 129 Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List); 130 if (Irp) 131 { 132 Irp->IoStatus.Information = DataSize; 133 Irp->IoStatus.Status = STATUS_SUCCESS; 134 InsertTailList(List, &Irp->Tail.Overlay.ListEntry); 135 } 136 } 137 138 if (Mode == FILE_PIPE_MESSAGE_MODE) 139 { 140 IoStatus.Status = STATUS_SUCCESS; 141 break; 142 } 143 144 ASSERT(!ReadOverflowOperation); 145 } 146 } 147 148 if (Peek) 149 { 150 DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink, 151 NP_DATA_QUEUE_ENTRY, 152 QueueEntry); 153 } 154 else 155 { 156 DataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(DataQueue, List), 157 NP_DATA_QUEUE_ENTRY, 158 QueueEntry); 159 } 160 } 161 162 IoStatus.Information = TotalBytesCopied; 163 if (CompleteWrites) NpCompleteStalledWrites(DataQueue, List); 164 return IoStatus; 165 } 166 167 /* EOF */ 168