2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/writesup.c
5 * PURPOSE: Pipes Writing Support
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_WRITESUP)
16 /* FUNCTIONS ******************************************************************/
20 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue
,
23 IN ULONG OutBufferSize
,
25 OUT PULONG BytesNotWritten
,
27 IN ULONG NamedPipeEnd
,
31 BOOLEAN HaveContext
= FALSE
, MoreProcessing
, AllocatedBuffer
;
32 PNP_DATA_QUEUE_ENTRY DataEntry
;
33 ULONG DataSize
, BufferSize
;
35 PIO_STACK_LOCATION IoStack
;
38 PSECURITY_CLIENT_CONTEXT ClientContext
;
41 *BytesNotWritten
= OutBufferSize
;
43 MoreProcessing
= TRUE
;
44 if ((PipeType
!= FILE_PIPE_MESSAGE_MODE
) || (OutBufferSize
))
46 MoreProcessing
= FALSE
;
49 for (DataEntry
= CONTAINING_RECORD(NpGetNextRealDataQueueEntry(WriteQueue
, List
),
52 ((WriteQueue
->QueueState
== ReadEntries
) &&
53 ((*BytesNotWritten
> 0) || (MoreProcessing
)));
54 DataEntry
= CONTAINING_RECORD(NpGetNextRealDataQueueEntry(WriteQueue
, List
),
58 DataSize
= DataEntry
->DataSize
;
60 IoStack
= IoGetCurrentIrpStackLocation(DataEntry
->Irp
);
62 if (IoStack
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
&&
63 IoStack
->Parameters
.FileSystemControl
.FsControlCode
== FSCTL_PIPE_INTERNAL_READ_OVFLOW
&&
64 (DataSize
< OutBufferSize
|| MoreProcessing
))
66 WriteIrp
= NpRemoveDataQueueEntry(WriteQueue
, TRUE
, List
);
69 WriteIrp
->IoStatus
.Status
= STATUS_BUFFER_OVERFLOW
;
70 InsertTailList(List
, &WriteIrp
->Tail
.Overlay
.ListEntry
);
75 if (DataEntry
->DataEntryType
== Unbuffered
)
77 DataEntry
->Irp
->Overlay
.AllocationSize
.QuadPart
= 0;
80 BufferSize
= *BytesNotWritten
;
81 if (BufferSize
>= DataSize
) BufferSize
= DataSize
;
83 if (DataEntry
->DataEntryType
!= Unbuffered
&& BufferSize
)
85 Buffer
= ExAllocatePoolWithTag(NonPagedPool
, BufferSize
, NPFS_DATA_ENTRY_TAG
);
86 if (!Buffer
) return STATUS_INSUFFICIENT_RESOURCES
;
87 AllocatedBuffer
= TRUE
;
91 Buffer
= DataEntry
->Irp
->AssociatedIrp
.SystemBuffer
;
92 AllocatedBuffer
= FALSE
;
98 (PVOID
)((ULONG_PTR
)OutBuffer
+ OutBufferSize
- *BytesNotWritten
),
101 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
103 if (AllocatedBuffer
) ExFreePool(Buffer
);
104 _SEH2_YIELD(return _SEH2_GetExceptionCode());
111 Status
= NpGetClientSecurityContext(NamedPipeEnd
, Ccb
, Thread
, &ClientContext
);
112 if (!NT_SUCCESS(Status
))
114 if (AllocatedBuffer
) ExFreePool(Buffer
);
120 NpFreeClientSecurityContext(Ccb
->ClientContext
);
121 Ccb
->ClientContext
= ClientContext
;
125 WriteIrp
= NpRemoveDataQueueEntry(WriteQueue
, TRUE
, List
);
128 *BytesNotWritten
-= BufferSize
;
129 WriteIrp
->IoStatus
.Information
= BufferSize
;
133 WriteIrp
->AssociatedIrp
.SystemBuffer
= Buffer
;
134 WriteIrp
->Flags
|= IRP_DEALLOCATE_BUFFER
| IRP_BUFFERED_IO
| IRP_INPUT_OPERATION
;
137 if (!*BytesNotWritten
)
139 MoreProcessing
= FALSE
;
140 WriteIrp
->IoStatus
.Status
= STATUS_SUCCESS
;
141 InsertTailList(List
, &WriteIrp
->Tail
.Overlay
.ListEntry
);
145 if (Mode
== FILE_PIPE_MESSAGE_MODE
)
147 WriteIrp
->IoStatus
.Status
= STATUS_BUFFER_OVERFLOW
;
151 WriteIrp
->IoStatus
.Status
= STATUS_SUCCESS
;
154 InsertTailList(List
, &WriteIrp
->Tail
.Overlay
.ListEntry
);
156 else if (AllocatedBuffer
)
162 if (*BytesNotWritten
> 0 || MoreProcessing
)
164 ASSERT(WriteQueue
->QueueState
!= ReadEntries
);
165 Status
= STATUS_MORE_PROCESSING_REQUIRED
;
169 Status
= STATUS_SUCCESS
;