482ea5ba041501290dd8c7abc838f284819e69d3
[reactos.git] / reactos / drivers / filesystems / npfs_new / readsup.c
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 /* FUNCTIONS ******************************************************************/
14
15 IO_STATUS_BLOCK
16 NTAPI
17 NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
18 IN BOOLEAN Peek,
19 IN BOOLEAN ReadOverflowOperation,
20 IN PVOID Buffer,
21 IN ULONG BufferSize,
22 IN ULONG Mode,
23 IN PNP_CCB Ccb,
24 IN PLIST_ENTRY List)
25 {
26 PNP_DATA_QUEUE_ENTRY DataEntry, TempDataEntry;
27 PVOID DataBuffer;
28 ULONG DataSize, DataLength, TotalBytesCopied, RemainingSize, Offset;
29 PIRP Irp;
30 IO_STATUS_BLOCK Status;
31 BOOLEAN CompleteWrites = FALSE;
32 PAGED_CODE();
33
34 if (ReadOverflowOperation) Peek = TRUE;
35
36 RemainingSize = BufferSize;
37 Status.Status = STATUS_SUCCESS;
38 TotalBytesCopied = 0;
39
40 if (Peek)
41 {
42 DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
43 NP_DATA_QUEUE_ENTRY,
44 QueueEntry);
45 }
46 else
47 {
48 DataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
49 }
50
51 while ((&DataEntry->QueueEntry != &DataQueue->Queue) && (RemainingSize))
52 {
53 if (!Peek ||
54 DataEntry->DataEntryType == Buffered ||
55 DataEntry->DataEntryType == Unbuffered)
56 {
57 if (DataEntry->DataEntryType == Unbuffered)
58 {
59 DataBuffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
60 }
61 else
62 {
63 DataBuffer = &DataEntry[1];
64 }
65
66 DataSize = DataEntry->DataSize;
67 Offset = DataSize;
68
69 if (&DataEntry->QueueEntry == DataQueue->Queue.Flink)
70 {
71 Offset -= DataQueue->ByteOffset;
72 }
73
74 DataLength = Offset;
75 if (Offset >= RemainingSize) DataLength = RemainingSize;
76
77 _SEH2_TRY
78 {
79 RtlCopyMemory((PVOID)((ULONG_PTR)Buffer + BufferSize - RemainingSize),
80 (PVOID)((ULONG_PTR)DataBuffer + DataSize - Offset),
81 DataLength);
82 }
83 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
84 {
85 ASSERT(FALSE);
86 }
87 _SEH2_END;
88
89
90 RemainingSize -= DataLength;
91 Offset -= DataLength;
92 TotalBytesCopied += DataLength;
93
94 if (!Peek)
95 {
96 DataEntry->QuotaInEntry -= DataLength;
97 DataQueue->QuotaUsed -= DataLength;
98 DataQueue->ByteOffset += DataLength;
99 CompleteWrites = TRUE;
100 }
101
102 NpCopyClientContext(Ccb, DataEntry);
103
104 if ((Offset) || (ReadOverflowOperation && !TotalBytesCopied))
105 {
106 if (Mode == FILE_PIPE_MESSAGE_MODE)
107 {
108 Status.Status = STATUS_BUFFER_OVERFLOW;
109 break;
110 }
111 }
112 else
113 {
114 if (!Peek || ReadOverflowOperation)
115 {
116 if (ReadOverflowOperation)
117 {
118 TempDataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
119 ASSERT(TempDataEntry == DataEntry);
120 }
121
122 Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List);
123 if (Irp)
124 {
125 Irp->IoStatus.Information = DataSize;
126 Irp->IoStatus.Status = STATUS_SUCCESS;
127 InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
128 }
129 }
130 if (Mode == FILE_PIPE_MESSAGE_MODE)
131 {
132 Status.Status = STATUS_SUCCESS;
133 break;
134 }
135 ASSERT(!ReadOverflowOperation);
136 }
137 }
138 if (Peek)
139 {
140 DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink,
141 NP_DATA_QUEUE_ENTRY,
142 QueueEntry);
143 }
144 else
145 {
146 DataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
147 }
148 }
149
150 Status.Information = TotalBytesCopied;
151 if (CompleteWrites) NpCompleteStalledWrites(DataQueue, List);
152 return Status;
153 }
154
155 /* EOF */