5 NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
)
9 ASSERT(DataQueue
->QueueState
== Empty
);
11 RtlZeroMemory(DataQueue
, sizeof(*DataQueue
));
12 return STATUS_SUCCESS
;
17 NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
,
22 DataQueue
->BytesInQueue
= 0;
23 DataQueue
->EntriesInQueue
= 0;
24 DataQueue
->QuotaUsed
= 0;
25 DataQueue
->ByteOffset
= 0;
26 DataQueue
->QueueState
= Empty
;
27 DataQueue
->Quota
= Quota
;
28 InitializeListHead(&DataQueue
->Queue
);
29 return STATUS_SUCCESS
;
34 NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue
,
37 ULONG QuotaLeft
, ByteOffset
, DataLeft
, NewQuotaLeft
;
38 PNP_DATA_QUEUE_ENTRY DataQueueEntry
;
40 PLIST_ENTRY NextEntry
;
42 QuotaLeft
= DataQueue
->Quota
- DataQueue
->QuotaUsed
;
43 ByteOffset
= DataQueue
->ByteOffset
;
45 NextEntry
= DataQueue
->Queue
.Flink
;
46 while (NextEntry
!= &DataQueue
->Queue
)
48 if (!QuotaLeft
) break;
50 DataQueueEntry
= CONTAINING_RECORD(NextEntry
, NP_DATA_QUEUE_ENTRY
, Irp
);
52 Irp
= DataQueueEntry
->Irp
;
54 if ((DataQueueEntry
->DataEntryType
== 0) && (Irp
))
56 DataLeft
= DataQueueEntry
->DataSize
- ByteOffset
;
58 if (DataQueueEntry
->QuotaInEntry
< DataLeft
)
60 NewQuotaLeft
= DataLeft
- DataQueueEntry
->QuotaInEntry
;
61 if (NewQuotaLeft
> QuotaLeft
) NewQuotaLeft
= QuotaLeft
;
63 QuotaLeft
-= NewQuotaLeft
;
64 DataQueueEntry
->QuotaInEntry
+= NewQuotaLeft
;
66 if (DataQueueEntry
->QuotaInEntry
== DataLeft
&&
67 IoSetCancelRoutine(Irp
, NULL
))
69 DataQueueEntry
->Irp
= NULL
;
71 Irp
->IoStatus
.Status
= 0;
72 Irp
->IoStatus
.Information
= DataQueueEntry
->DataSize
;
74 InsertTailList(List
, &Irp
->Tail
.Overlay
.ListEntry
);
79 NextEntry
= NextEntry
->Flink
;
83 DataQueue
->QuotaUsed
= DataQueue
->Quota
- QuotaLeft
;
88 NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
93 PNP_DATA_QUEUE_ENTRY QueueEntry
;
96 if (DataQueue
->QueueState
== Empty
)
99 ASSERT(IsListEmpty(&DataQueue
->Queue
));
100 ASSERT(DataQueue
->EntriesInQueue
== 0);
101 ASSERT(DataQueue
->BytesInQueue
== 0);
102 ASSERT(DataQueue
->QuotaUsed
== 0);
106 QueueEntry
= CONTAINING_RECORD(RemoveHeadList(&DataQueue
->Queue
),
110 DataQueue
->BytesInQueue
-= QueueEntry
->DataSize
;
111 --DataQueue
->EntriesInQueue
;
114 if (!DataQueue
->QueueState
!= WriteEntries
|| DataQueue
->QuotaUsed
< DataQueue
->Quota
|| !QueueEntry
->QuotaInEntry
)
119 DataQueue
->QuotaUsed
-= QueueEntry
->QuotaInEntry
;
121 if (DataQueue
->Queue
.Flink
== &DataQueue
->Queue
)
123 DataQueue
->QueueState
= Empty
;
127 Irp
= QueueEntry
->Irp
;
128 NpFreeClientSecurityContext(QueueEntry
->ClientSecurityContext
);
130 if (Irp
&& IoSetCancelRoutine(Irp
, NULL
))
132 Irp
->Tail
.Overlay
.DriverContext
[3] = NULL
;
135 ExFreePool(QueueEntry
);
139 NpGetNextRealDataQueueEntry(DataQueue
, List
);
144 NpCompleteStalledWrites(DataQueue
, List
);
148 DataQueue
->ByteOffset
= 0;
154 NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
157 PNP_DATA_QUEUE_ENTRY DataEntry
;
160 PLIST_ENTRY NextEntry
;
165 NextEntry
= DataQueue
->Queue
.Flink
;
166 while (NextEntry
!= &DataQueue
->Queue
)
168 DataEntry
= CONTAINING_RECORD(NextEntry
, NP_DATA_QUEUE_ENTRY
, QueueEntry
);
170 Type
= DataEntry
->DataEntryType
;
171 if (Type
== Buffered
|| Type
== Unbuffered
) break;
173 Irp
= NpRemoveDataQueueEntry(DataQueue
, FALSE
, List
);
176 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
177 InsertTailList(List
, &Irp
->Tail
.Overlay
.ListEntry
);
186 NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject
,
189 PNP_DATA_QUEUE DataQueue
;
190 PNP_DATA_QUEUE_ENTRY DataEntry
;
191 LIST_ENTRY DeferredList
;
192 PSECURITY_CLIENT_CONTEXT ClientSecurityContext
;
193 BOOLEAN CompleteWrites
, FirstEntry
;
195 if (DeviceObject
) IoReleaseCancelSpinLock(Irp
->CancelIrql
);
197 InitializeListHead(&DeferredList
);
199 DataQueue
= (PNP_DATA_QUEUE
)Irp
->Tail
.Overlay
.DriverContext
[2];
200 ClientSecurityContext
= NULL
;
204 FsRtlEnterFileSystem();
205 NpAcquireExclusiveVcb();
208 DataEntry
= (PNP_DATA_QUEUE_ENTRY
)Irp
->Tail
.Overlay
.DriverContext
[3];
211 if (DataEntry
->QueueEntry
.Blink
== &DataQueue
->Queue
)
213 DataQueue
->ByteOffset
= 0;
221 RemoveEntryList(&DataEntry
->QueueEntry
);
223 ClientSecurityContext
= DataEntry
->ClientSecurityContext
;
226 if (!DataQueue
->QueueState
!= WriteEntries
|| DataQueue
->QuotaUsed
< DataQueue
->Quota
|| !DataEntry
->QuotaInEntry
)
231 DataQueue
->BytesInQueue
-= DataEntry
->DataSize
;
232 DataQueue
->QuotaUsed
-= DataEntry
->QuotaInEntry
;
233 --DataQueue
->EntriesInQueue
;
235 if (DataQueue
->Queue
.Flink
== &DataQueue
->Queue
)
237 DataQueue
->QueueState
= Empty
;
238 ASSERT(DataQueue
->BytesInQueue
== 0);
239 ASSERT(DataQueue
->EntriesInQueue
== 0);
240 ASSERT(DataQueue
->QuotaUsed
== 0);
246 NpGetNextRealDataQueueEntry(DataQueue
, &DeferredList
);
250 NpCompleteStalledWrites(DataQueue
, &DeferredList
);
258 FsRtlExitFileSystem();
261 if (DataEntry
) ExFreePool(DataEntry
);
263 NpFreeClientSecurityContext(ClientSecurityContext
);
264 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
265 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
267 NpCompleteDeferredIrps(&DeferredList
);
272 NpAddDataQueueEntry(IN ULONG NamedPipeEnd
,
274 IN PNP_DATA_QUEUE DataQueue
,
283 PNP_DATA_QUEUE_ENTRY DataEntry
;
286 PSECURITY_CLIENT_CONTEXT ClientContext
;
289 ClientContext
= NULL
;
290 ASSERT((DataQueue
->QueueState
== Empty
) || (DataQueue
->QueueState
== Who
));
292 Status
= STATUS_SUCCESS
;
294 if ((Type
!= 2) && (Who
== WriteEntries
))
296 Status
= NpGetClientSecurityContext(NamedPipeEnd
,
298 Irp
? Irp
->Tail
.Overlay
.Thread
:
299 PsGetCurrentThread(),
301 if (!NT_SUCCESS(Status
))
314 DataEntry
= ExAllocatePoolWithQuotaTag(NonPagedPool
,
316 NPFS_DATA_ENTRY_TAG
);
319 NpFreeClientSecurityContext(ClientContext
);
320 return STATUS_INSUFFICIENT_RESOURCES
;
323 DataEntry
->DataEntryType
= Type
;
324 DataEntry
->QuotaInEntry
= 0;
325 DataEntry
->Irp
= Irp
;
326 DataEntry
->DataSize
= DataSize
;
327 DataEntry
->ClientSecurityContext
= ClientContext
;
328 ASSERT((DataQueue
->QueueState
== Empty
) || (DataQueue
->QueueState
== Who
));
329 Status
= STATUS_PENDING
;
334 EntrySize
= sizeof(*DataEntry
);
335 if (Who
!= ReadEntries
)
337 EntrySize
+= DataSize
;
338 if (EntrySize
< DataSize
)
340 NpFreeClientSecurityContext(ClientContext
);
341 return STATUS_INVALID_PARAMETER
;
345 QuotaInEntry
= DataSize
- ByteOffset
;
346 if (DataQueue
->Quota
- DataQueue
->QuotaUsed
< QuotaInEntry
)
348 QuotaInEntry
= DataQueue
->Quota
- DataQueue
->QuotaUsed
;
356 DataEntry
= ExAllocatePoolWithQuotaTag(NonPagedPool
,
358 NPFS_DATA_ENTRY_TAG
);
361 NpFreeClientSecurityContext(ClientContext
);
362 return STATUS_INSUFFICIENT_RESOURCES
;
365 DataEntry
->QuotaInEntry
= QuotaInEntry
;
366 DataEntry
->Irp
= Irp
;
367 DataEntry
->DataEntryType
= Buffered
;
368 DataEntry
->ClientSecurityContext
= ClientContext
;
369 DataEntry
->DataSize
= DataSize
;
371 if (Who
== ReadEntries
)
375 Status
= STATUS_PENDING
;
376 ASSERT((DataQueue
->QueueState
== Empty
) ||
377 (DataQueue
->QueueState
== Who
));
383 RtlCopyMemory(DataEntry
+ 1,
384 Irp
? Irp
->UserBuffer
: Buffer
,
387 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
389 NpFreeClientSecurityContext(ClientContext
);
390 return _SEH2_GetExceptionCode();
396 Status
= STATUS_PENDING
;
400 DataEntry
->Irp
= NULL
;
401 Status
= STATUS_SUCCESS
;
404 ASSERT((DataQueue
->QueueState
== Empty
) ||
405 (DataQueue
->QueueState
== Who
));
411 NpFreeClientSecurityContext(ClientContext
);
412 return STATUS_INVALID_PARAMETER
;
415 ASSERT((DataQueue
->QueueState
== Empty
) || (DataQueue
->QueueState
== Who
));
416 if (DataQueue
->QueueState
== Empty
)
418 ASSERT(DataQueue
->BytesInQueue
== 0);
419 ASSERT(DataQueue
->EntriesInQueue
== 0);
420 ASSERT(IsListEmpty (&DataQueue
->Queue
));
424 ASSERT(DataQueue
->QueueState
== Who
);
425 ASSERT(DataQueue
->QueueState
!= Empty
);
426 ASSERT(DataQueue
->EntriesInQueue
!= 0);
429 DataQueue
->QuotaUsed
+= DataEntry
->QuotaInEntry
;
430 DataQueue
->QueueState
= Who
;
431 DataQueue
->BytesInQueue
+= DataEntry
->DataSize
;
432 DataQueue
->EntriesInQueue
++;
436 DataQueue
->ByteOffset
= ByteOffset
;
437 ASSERT(Who
== WriteEntries
);
438 ASSERT(ByteOffset
< DataEntry
->DataSize
);
439 ASSERT(DataQueue
->EntriesInQueue
== 1);
442 InsertTailList(&DataQueue
->Queue
, &DataEntry
->QueueEntry
);
444 if (Status
== STATUS_PENDING
)
446 IoMarkIrpPending(Irp
);
447 Irp
->Tail
.Overlay
.DriverContext
[2] = DataQueue
;
448 Irp
->Tail
.Overlay
.DriverContext
[3] = DataEntry
;
450 IoSetCancelRoutine(Irp
, NpCancelDataQueueIrp
);
452 if ((Irp
->Cancel
) && (IoSetCancelRoutine(Irp
, NULL
)))
454 NpCancelDataQueueIrp(NULL
, Irp
);