2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/write.c
5 * PURPOSE: Pipes Writing
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_WRITE)
16 /* GLOBALS ********************************************************************/
18 LONG NpSlowWriteCalls
;
19 ULONG NpFastWriteTrue
;
20 ULONG NpFastWriteFalse
;
22 /* FUNCTIONS ******************************************************************/
26 NpCommonWrite(IN PFILE_OBJECT FileObject
,
30 IN PIO_STATUS_BLOCK IoStatus
,
34 NODE_TYPE_CODE NodeType
;
37 PNP_NONPAGED_CCB NonPagedCcb
;
38 PNP_DATA_QUEUE WriteQueue
;
40 PNP_EVENT_BUFFER EventBuffer
;
41 ULONG BytesWritten
, NamedPipeEnd
, ReadMode
;
44 IoStatus
->Information
= 0;
45 NodeType
= NpDecodeFileObject(FileObject
, NULL
, &Ccb
, &NamedPipeEnd
);
49 IoStatus
->Status
= STATUS_PIPE_DISCONNECTED
;
53 if (NodeType
!= NPFS_NTC_CCB
)
55 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
59 NonPagedCcb
= Ccb
->NonPagedCcb
;
60 ExAcquireResourceExclusiveLite(&NonPagedCcb
->Lock
, TRUE
);
62 if (Ccb
->NamedPipeState
!= FILE_PIPE_CONNECTED_STATE
)
64 if (Ccb
->NamedPipeState
== FILE_PIPE_DISCONNECTED_STATE
)
66 IoStatus
->Status
= STATUS_PIPE_DISCONNECTED
;
68 else if (Ccb
->NamedPipeState
== FILE_PIPE_LISTENING_STATE
)
70 IoStatus
->Status
= STATUS_PIPE_LISTENING
;
74 ASSERT(Ccb
->NamedPipeState
== FILE_PIPE_CLOSING_STATE
);
75 IoStatus
->Status
= STATUS_PIPE_CLOSING
;
82 if ((NamedPipeEnd
== FILE_PIPE_SERVER_END
&& Ccb
->Fcb
->NamedPipeConfiguration
== FILE_PIPE_INBOUND
) ||
83 (NamedPipeEnd
== FILE_PIPE_CLIENT_END
&& Ccb
->Fcb
->NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
))
85 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
90 IoStatus
->Status
= STATUS_SUCCESS
;
91 IoStatus
->Information
= DataSize
;
93 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
95 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
96 ReadMode
= Ccb
->ReadMode
[FILE_PIPE_CLIENT_END
];
100 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
101 ReadMode
= Ccb
->ReadMode
[FILE_PIPE_SERVER_END
];
104 EventBuffer
= NonPagedCcb
->EventBuffer
[NamedPipeEnd
];
106 if ((WriteQueue
->QueueState
== ReadEntries
&&
107 WriteQueue
->BytesInQueue
< DataSize
&&
108 WriteQueue
->Quota
< DataSize
- WriteQueue
->BytesInQueue
) ||
109 (WriteQueue
->QueueState
== ReadEntries
&&
110 WriteQueue
->Quota
- WriteQueue
->QuotaUsed
< DataSize
))
112 if (Ccb
->Fcb
->NamedPipeType
== FILE_PIPE_MESSAGE_TYPE
&&
113 Ccb
->CompletionMode
[NamedPipeEnd
] == FILE_PIPE_COMPLETE_OPERATION
)
115 IoStatus
->Information
= 0;
116 IoStatus
->Status
= STATUS_SUCCESS
;
128 Status
= NpWriteDataQueue(WriteQueue
,
132 Ccb
->Fcb
->NamedPipeType
,
138 IoStatus
->Status
= Status
;
140 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
142 ASSERT(WriteQueue
->QueueState
!= ReadEntries
);
143 if ((Ccb
->CompletionMode
[NamedPipeEnd
] == FILE_PIPE_COMPLETE_OPERATION
|| !Irp
) &&
144 ((WriteQueue
->Quota
- WriteQueue
->QuotaUsed
) < BytesWritten
))
146 IoStatus
->Information
= DataSize
- BytesWritten
;
147 IoStatus
->Status
= STATUS_SUCCESS
;
151 ASSERT(WriteQueue
->QueueState
!= ReadEntries
);
153 IoStatus
->Status
= NpAddDataQueueEntry(NamedPipeEnd
,
161 DataSize
- BytesWritten
);
165 if (EventBuffer
) KeSetEvent(EventBuffer
->Event
, IO_NO_INCREMENT
, FALSE
);
169 ExReleaseResourceLite(&Ccb
->NonPagedCcb
->Lock
);
175 NpFsdWrite(IN PDEVICE_OBJECT DeviceObject
,
178 PIO_STACK_LOCATION IoStack
;
179 IO_STATUS_BLOCK IoStatus
;
180 LIST_ENTRY DeferredList
;
184 InitializeListHead(&DeferredList
);
185 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
187 FsRtlEnterFileSystem();
188 NpAcquireSharedVcb();
190 NpCommonWrite(IoStack
->FileObject
,
192 IoStack
->Parameters
.Write
.Length
,
193 Irp
->Tail
.Overlay
.Thread
,
199 NpCompleteDeferredIrps(&DeferredList
);
200 FsRtlExitFileSystem();
202 if (IoStatus
.Status
!= STATUS_PENDING
)
204 Irp
->IoStatus
.Information
= IoStatus
.Information
;
205 Irp
->IoStatus
.Status
= IoStatus
.Status
;
206 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
209 return IoStatus
.Status
;
213 _Function_class_(FAST_IO_WRITE
)
218 _In_ PFILE_OBJECT FileObject
,
219 _In_ PLARGE_INTEGER FileOffset
,
224 _Out_ PIO_STATUS_BLOCK IoStatus
,
225 _In_ PDEVICE_OBJECT DeviceObject
)
227 LIST_ENTRY DeferredList
;
231 InitializeListHead(&DeferredList
);
233 FsRtlEnterFileSystem();
234 NpAcquireSharedVcb();
236 Result
= NpCommonWrite(FileObject
,
239 PsGetCurrentThread(),
249 NpCompleteDeferredIrps(&DeferredList
);
250 FsRtlExitFileSystem();