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
;
20 /* FUNCTIONS ******************************************************************/
24 NpCommonWrite(IN PFILE_OBJECT FileObject
,
28 IN PIO_STATUS_BLOCK IoStatus
,
32 NODE_TYPE_CODE NodeType
;
35 PNP_NONPAGED_CCB NonPagedCcb
;
36 PNP_DATA_QUEUE WriteQueue
;
38 PNP_EVENT_BUFFER EventBuffer
;
39 ULONG BytesWritten
, NamedPipeEnd
, ReadMode
;
42 IoStatus
->Information
= 0;
43 NodeType
= NpDecodeFileObject(FileObject
, NULL
, &Ccb
, &NamedPipeEnd
);
47 IoStatus
->Status
= STATUS_PIPE_DISCONNECTED
;
51 if (NodeType
!= NPFS_NTC_CCB
)
53 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
57 NonPagedCcb
= Ccb
->NonPagedCcb
;
58 ExAcquireResourceExclusiveLite(&NonPagedCcb
->Lock
, TRUE
);
60 if (Ccb
->NamedPipeState
!= FILE_PIPE_CONNECTED_STATE
)
62 if (Ccb
->NamedPipeState
== FILE_PIPE_DISCONNECTED_STATE
)
64 IoStatus
->Status
= STATUS_PIPE_DISCONNECTED
;
66 else if (Ccb
->NamedPipeState
== FILE_PIPE_LISTENING_STATE
)
68 IoStatus
->Status
= STATUS_PIPE_LISTENING
;
72 ASSERT(Ccb
->NamedPipeState
== FILE_PIPE_CLOSING_STATE
);
73 IoStatus
->Status
= STATUS_PIPE_CLOSING
;
80 if ((NamedPipeEnd
== FILE_PIPE_SERVER_END
&& Ccb
->Fcb
->NamedPipeConfiguration
== FILE_PIPE_INBOUND
) ||
81 (NamedPipeEnd
== FILE_PIPE_CLIENT_END
&& Ccb
->Fcb
->NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
))
83 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
88 IoStatus
->Status
= STATUS_SUCCESS
;
89 IoStatus
->Information
= DataSize
;
91 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
93 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
94 ReadMode
= Ccb
->ReadMode
[FILE_PIPE_CLIENT_END
];
98 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
99 ReadMode
= Ccb
->ReadMode
[FILE_PIPE_SERVER_END
];
102 EventBuffer
= NonPagedCcb
->EventBuffer
[NamedPipeEnd
];
104 if ((WriteQueue
->QueueState
== ReadEntries
&&
105 WriteQueue
->BytesInQueue
< DataSize
&&
106 WriteQueue
->Quota
< DataSize
- WriteQueue
->BytesInQueue
) ||
107 (WriteQueue
->QueueState
== ReadEntries
&&
108 WriteQueue
->Quota
- WriteQueue
->QuotaUsed
< DataSize
))
110 if (Ccb
->Fcb
->NamedPipeType
== FILE_PIPE_MESSAGE_TYPE
&&
111 Ccb
->CompletionMode
[NamedPipeEnd
] == FILE_PIPE_COMPLETE_OPERATION
)
113 IoStatus
->Information
= 0;
114 IoStatus
->Status
= STATUS_SUCCESS
;
126 Status
= NpWriteDataQueue(WriteQueue
,
130 Ccb
->Fcb
->NamedPipeType
,
136 IoStatus
->Status
= Status
;
138 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
140 ASSERT(WriteQueue
->QueueState
!= ReadEntries
);
141 if ((Ccb
->CompletionMode
[NamedPipeEnd
] == FILE_PIPE_COMPLETE_OPERATION
|| !Irp
) &&
142 ((WriteQueue
->Quota
- WriteQueue
->QuotaUsed
) < BytesWritten
))
144 IoStatus
->Information
= DataSize
- BytesWritten
;
145 IoStatus
->Status
= STATUS_SUCCESS
;
149 ASSERT(WriteQueue
->QueueState
!= ReadEntries
);
151 IoStatus
->Status
= NpAddDataQueueEntry(NamedPipeEnd
,
159 DataSize
- BytesWritten
);
163 if (EventBuffer
) KeSetEvent(EventBuffer
->Event
, IO_NO_INCREMENT
, FALSE
);
167 ExReleaseResourceLite(&Ccb
->NonPagedCcb
->Lock
);
173 NpFsdWrite(IN PDEVICE_OBJECT DeviceObject
,
176 PIO_STACK_LOCATION IoStack
;
177 IO_STATUS_BLOCK IoStatus
;
178 LIST_ENTRY DeferredList
;
182 InitializeListHead(&DeferredList
);
183 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
185 FsRtlEnterFileSystem();
186 NpAcquireSharedVcb();
188 NpCommonWrite(IoStack
->FileObject
,
190 IoStack
->Parameters
.Write
.Length
,
191 Irp
->Tail
.Overlay
.Thread
,
197 NpCompleteDeferredIrps(&DeferredList
);
198 FsRtlExitFileSystem();
200 if (IoStatus
.Status
!= STATUS_PENDING
)
202 Irp
->IoStatus
.Information
= IoStatus
.Information
;
203 Irp
->IoStatus
.Status
= IoStatus
.Status
;
204 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
207 return IoStatus
.Status
;