Sync with trunk for console graphics palettes.
[reactos.git] / drivers / filesystems / npfs / read.c
1 /*
2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/read.c
5 * PURPOSE: Pipes Reading
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_READ)
15
16 /* GLOBALS ********************************************************************/
17
18 LONG NpSlowReadCalls;
19
20 /* FUNCTIONS ******************************************************************/
21
22 BOOLEAN
23 NTAPI
24 NpCommonRead(IN PFILE_OBJECT FileObject,
25 IN PVOID Buffer,
26 IN ULONG BufferSize,
27 OUT PIO_STATUS_BLOCK IoStatus,
28 IN PIRP Irp,
29 IN PLIST_ENTRY List)
30 {
31 NODE_TYPE_CODE NodeType;
32 PNP_DATA_QUEUE ReadQueue;
33 PNP_EVENT_BUFFER EventBuffer;
34 NTSTATUS Status;
35 ULONG NamedPipeEnd;
36 PNP_CCB Ccb;
37 PNP_NONPAGED_CCB NonPagedCcb;
38 BOOLEAN ReadOk;
39 PAGED_CODE();
40
41 IoStatus->Information = 0;
42 NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
43
44 if (!NodeType)
45 {
46 IoStatus->Status = STATUS_PIPE_DISCONNECTED;
47 return TRUE;
48 }
49
50 if (NodeType != NPFS_NTC_CCB)
51 {
52 IoStatus->Status = STATUS_INVALID_PARAMETER;
53 return TRUE;
54 }
55
56 NonPagedCcb = Ccb->NonPagedCcb;
57 ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
58
59 if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE || Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE)
60 {
61 IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_DISCONNECTED_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_DISCONNECTED;
62 ReadOk = TRUE;
63 goto Quickie;
64 }
65
66 ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
67
68 if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
69 (NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND))
70 {
71 IoStatus->Status = STATUS_INVALID_PARAMETER;
72 ReadOk = TRUE;
73 goto Quickie;
74 }
75
76 if (NamedPipeEnd == FILE_PIPE_SERVER_END)
77 {
78 ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
79 }
80 else
81 {
82 ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
83 }
84
85 EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
86
87 if (ReadQueue->QueueState == WriteEntries)
88 {
89 *IoStatus = NpReadDataQueue(ReadQueue,
90 FALSE,
91 FALSE,
92 Buffer,
93 BufferSize,
94 Ccb->ReadMode[NamedPipeEnd],
95 Ccb,
96 List);
97 if (!NT_SUCCESS(IoStatus->Status))
98 {
99 ReadOk = TRUE;
100 goto Quickie;
101 }
102
103 ReadOk = TRUE;
104 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
105 goto Quickie;
106 }
107
108 if (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE)
109 {
110 IoStatus->Status = STATUS_PIPE_BROKEN;
111 ReadOk = TRUE;
112 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
113 goto Quickie;
114 }
115
116 if (Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
117 {
118 IoStatus->Status = STATUS_PIPE_EMPTY;
119 ReadOk = TRUE;
120 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
121 goto Quickie;
122 }
123
124 if (!Irp)
125 {
126 ReadOk = FALSE;
127 goto Quickie;
128 }
129
130 Status = NpAddDataQueueEntry(NamedPipeEnd,
131 Ccb,
132 ReadQueue,
133 ReadEntries,
134 Buffered,
135 BufferSize,
136 Irp,
137 NULL,
138 0);
139 IoStatus->Status = Status;
140 if (!NT_SUCCESS(Status))
141 {
142 ReadOk = FALSE;
143 }
144 else
145 {
146 ReadOk = TRUE;
147 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
148 }
149
150 Quickie:
151 ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
152 return ReadOk;
153 }
154
155 NTSTATUS
156 NTAPI
157 NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
158 IN PIRP Irp)
159 {
160 PIO_STACK_LOCATION IoStack;
161 IO_STATUS_BLOCK IoStatus;
162 LIST_ENTRY DeferredList;
163 PAGED_CODE();
164 NpSlowReadCalls++;
165
166 InitializeListHead(&DeferredList);
167 IoStack = IoGetCurrentIrpStackLocation(Irp);
168
169 FsRtlEnterFileSystem();
170 NpAcquireSharedVcb();
171
172 NpCommonRead(IoStack->FileObject,
173 Irp->UserBuffer,
174 IoStack->Parameters.Read.Length,
175 &IoStatus,
176 Irp,
177 &DeferredList);
178
179 NpReleaseVcb();
180 NpCompleteDeferredIrps(&DeferredList);
181 FsRtlExitFileSystem();
182
183 if (IoStatus.Status != STATUS_PENDING)
184 {
185 Irp->IoStatus.Information = IoStatus.Information;
186 Irp->IoStatus.Status = IoStatus.Status;
187 IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
188 }
189
190 return IoStatus.Status;
191 }
192
193 /* EOF */