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 /* FUNCTIONS ******************************************************************/
17 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue
,
20 IN ULONG OutBufferSize
,
22 OUT PULONG BytesNotWritten
,
24 IN ULONG NamedPipeEnd
,
28 BOOLEAN HaveContext
= FALSE
, MoreProcessing
, AllocatedBuffer
;
29 PNP_DATA_QUEUE_ENTRY DataEntry
;
30 ULONG DataSize
, BufferSize
;
32 PIO_STACK_LOCATION IoStack
;
35 PSECURITY_CLIENT_CONTEXT ClientContext
;
38 *BytesNotWritten
= OutBufferSize
;
40 MoreProcessing
= TRUE
;
41 if ((PipeType
!= FILE_PIPE_MESSAGE_MODE
) || (OutBufferSize
))
43 MoreProcessing
= FALSE
;
46 for (DataEntry
= NpGetNextRealDataQueueEntry(WriteQueue
, List
);
47 ((WriteQueue
->QueueState
== ReadEntries
) &&
48 ((*BytesNotWritten
> 0) || (MoreProcessing
)));
49 DataEntry
= NpGetNextRealDataQueueEntry(WriteQueue
, List
))
51 DataSize
= DataEntry
->DataSize
;
53 IoStack
= IoGetCurrentIrpStackLocation( DataEntry
->Irp
);
55 if (IoStack
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
&&
56 IoStack
->Parameters
.FileSystemControl
.FsControlCode
== FSCTL_PIPE_INTERNAL_READ_OVFLOW
&&
57 (DataSize
< OutBufferSize
|| MoreProcessing
))
59 WriteIrp
= NpRemoveDataQueueEntry(WriteQueue
, TRUE
, List
);
62 WriteIrp
->IoStatus
.Status
= STATUS_BUFFER_OVERFLOW
;
63 InsertTailList(List
, &WriteIrp
->Tail
.Overlay
.ListEntry
);
68 if (DataEntry
->DataEntryType
== Unbuffered
)
70 DataEntry
->Irp
->Overlay
.AllocationSize
.QuadPart
= 0;
73 BufferSize
= *BytesNotWritten
;
74 if (BufferSize
>= DataSize
) BufferSize
= DataSize
;
76 if (DataEntry
->DataEntryType
!= Unbuffered
&& BufferSize
)
78 Buffer
= ExAllocatePoolWithTag(NonPagedPool
, BufferSize
, NPFS_DATA_ENTRY_TAG
);
79 if (!Buffer
) return STATUS_INSUFFICIENT_RESOURCES
;
80 AllocatedBuffer
= TRUE
;
84 Buffer
= DataEntry
->Irp
->AssociatedIrp
.SystemBuffer
;
85 AllocatedBuffer
= FALSE
;
91 (PVOID
)((ULONG_PTR
)OutBuffer
+ OutBufferSize
- *BytesNotWritten
),
94 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
96 if (AllocatedBuffer
) ExFreePool(Buffer
);
97 return _SEH2_GetExceptionCode();
104 Status
= NpGetClientSecurityContext(NamedPipeEnd
, Ccb
, Thread
, &ClientContext
);
105 if (!NT_SUCCESS(Status
))
107 if (AllocatedBuffer
) ExFreePool(Buffer
);
113 NpFreeClientSecurityContext(Ccb
->ClientContext
);
114 Ccb
->ClientContext
= ClientContext
;
118 WriteIrp
= NpRemoveDataQueueEntry(WriteQueue
, TRUE
, List
);
121 *BytesNotWritten
-= BufferSize
;
122 WriteIrp
->IoStatus
.Information
= BufferSize
;
126 WriteIrp
->AssociatedIrp
.SystemBuffer
= Buffer
;
127 WriteIrp
->Flags
|= IRP_DEALLOCATE_BUFFER
| IRP_BUFFERED_IO
| IRP_INPUT_OPERATION
;
130 if (!*BytesNotWritten
)
132 MoreProcessing
= FALSE
;
133 WriteIrp
->IoStatus
.Status
= STATUS_SUCCESS
;
134 InsertTailList(List
, &WriteIrp
->Tail
.Overlay
.ListEntry
);
138 if (Mode
== FILE_PIPE_MESSAGE_MODE
)
140 WriteIrp
->IoStatus
.Status
= STATUS_BUFFER_OVERFLOW
;
144 WriteIrp
->IoStatus
.Status
= STATUS_SUCCESS
;
147 InsertTailList(List
, &WriteIrp
->Tail
.Overlay
.ListEntry
);
149 else if (AllocatedBuffer
)
155 if (*BytesNotWritten
> 0 || MoreProcessing
)
157 ASSERT(WriteQueue
->QueueState
!= ReadEntries
);
158 Status
= STATUS_MORE_PROCESSING_REQUIRED
;
162 Status
= STATUS_SUCCESS
;