ReactOS  0.4.15-dev-1070-ge1a01de
write.c
Go to the documentation of this file.
1 /*
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
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "npfs.h"
12 
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_WRITE)
15 
16 /* GLOBALS ********************************************************************/
17 
21 
22 /* FUNCTIONS ******************************************************************/
23 
24 BOOLEAN
25 NTAPI
27  IN PVOID Buffer,
31  IN PIRP Irp,
33 {
35  BOOLEAN WriteOk;
36  PNP_CCB Ccb;
37  PNP_NONPAGED_CCB NonPagedCcb;
38  PNP_DATA_QUEUE WriteQueue;
40  PNP_EVENT_BUFFER EventBuffer;
41  ULONG BytesWritten, NamedPipeEnd, ReadMode;
42  PAGED_CODE();
43 
44  IoStatus->Information = 0;
45  NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
46 
47  if (!NodeType)
48  {
50  return TRUE;
51  }
52 
53  if (NodeType != NPFS_NTC_CCB)
54  {
56  return TRUE;
57  }
58 
59  NonPagedCcb = Ccb->NonPagedCcb;
61 
62  if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
63  {
64  if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE)
65  {
67  }
68  else if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE)
69  {
71  }
72  else
73  {
74  ASSERT(Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE);
75  IoStatus->Status = STATUS_PIPE_CLOSING;
76  }
77 
78  WriteOk = TRUE;
79  goto Quickie;
80  }
81 
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))
84  {
86  WriteOk = TRUE;
87  goto Quickie;
88  }
89 
90  IoStatus->Status = STATUS_SUCCESS;
91  IoStatus->Information = DataSize;
92 
93  if (NamedPipeEnd == FILE_PIPE_SERVER_END)
94  {
95  WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
96  ReadMode = Ccb->ReadMode[FILE_PIPE_CLIENT_END];
97  }
98  else
99  {
100  WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
101  ReadMode = Ccb->ReadMode[FILE_PIPE_SERVER_END];
102  }
103 
104  EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
105 
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))
111  {
112  if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE &&
113  Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
114  {
115  IoStatus->Information = 0;
116  IoStatus->Status = STATUS_SUCCESS;
117  WriteOk = TRUE;
118  goto Quickie;
119  }
120 
121  if (!Irp)
122  {
123  WriteOk = FALSE;
124  goto Quickie;
125  }
126  }
127 
128  Status = NpWriteDataQueue(WriteQueue,
129  ReadMode,
130  Buffer,
131  DataSize,
132  Ccb->Fcb->NamedPipeType,
133  &BytesWritten,
134  Ccb,
135  NamedPipeEnd,
136  Thread,
137  List);
138  IoStatus->Status = Status;
139 
141  {
142  ASSERT(WriteQueue->QueueState != ReadEntries);
143  if ((Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION || !Irp) &&
144  ((WriteQueue->Quota - WriteQueue->QuotaUsed) < BytesWritten))
145  {
146  IoStatus->Information = DataSize - BytesWritten;
147  IoStatus->Status = STATUS_SUCCESS;
148  }
149  else
150  {
151  ASSERT(WriteQueue->QueueState != ReadEntries);
152 
153  IoStatus->Status = NpAddDataQueueEntry(NamedPipeEnd,
154  Ccb,
155  WriteQueue,
156  WriteEntries,
157  Buffered,
158  DataSize,
159  Irp,
160  Buffer,
162  }
163  }
164 
165  if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
166  WriteOk = TRUE;
167 
168 Quickie:
169  ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
170  return WriteOk;
171 }
172 
173 NTSTATUS
174 NTAPI
176  IN PIRP Irp)
177 {
178  PIO_STACK_LOCATION IoStack;
180  LIST_ENTRY DeferredList;
181  PAGED_CODE();
183 
184  InitializeListHead(&DeferredList);
186 
189 
190  NpCommonWrite(IoStack->FileObject,
191  Irp->UserBuffer,
192  IoStack->Parameters.Write.Length,
193  Irp->Tail.Overlay.Thread,
194  &IoStatus,
195  Irp,
196  &DeferredList);
197 
198  NpReleaseVcb();
199  NpCompleteDeferredIrps(&DeferredList);
201 
202  if (IoStatus.Status != STATUS_PENDING)
203  {
204  Irp->IoStatus.Information = IoStatus.Information;
205  Irp->IoStatus.Status = IoStatus.Status;
207  }
208 
209  return IoStatus.Status;
210 }
211 
212 
213 _Function_class_(FAST_IO_WRITE)
215 BOOLEAN
216 NTAPI
217 NpFastWrite(
220  _In_ ULONG Length,
221  _In_ BOOLEAN Wait,
223  _In_ PVOID Buffer,
226 {
227  LIST_ENTRY DeferredList;
228  BOOLEAN Result;
229  PAGED_CODE();
230 
231  InitializeListHead(&DeferredList);
232 
235 
237  Buffer,
238  Length,
240  IoStatus,
241  NULL,
242  &DeferredList);
243  if (Result)
244  ++NpFastWriteTrue;
245  else
247 
248  NpReleaseVcb();
249  NpCompleteDeferredIrps(&DeferredList);
251 
252  return Result;
253 }
254 
255 /* EOF */
NTSTATUS NTAPI NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue, IN ULONG Mode, IN PVOID OutBuffer, IN ULONG OutBufferSize, IN ULONG PipeType, OUT PULONG BytesWritten, IN PNP_CCB Ccb, IN ULONG NamedPipeEnd, IN PETHREAD Thread, IN PLIST_ENTRY List)
Definition: writesup.c:20
#define _IRQL_requires_same_
Definition: no_sal2.h:652
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
FORCEINLINE VOID NpAcquireSharedVcb(VOID)
Definition: npfs.h:328
#define FsRtlEnterFileSystem
#define STATUS_PIPE_DISCONNECTED
Definition: ntstatus.h:412
NTSTATUS Status
Definition: write.c:2803
PNP_EVENT_BUFFER EventBuffer[2]
Definition: npfs.h:253
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define FsRtlExitFileSystem
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define FILE_PIPE_CLOSING_STATE
Definition: winternl.h:793
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2659
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _FCB::@712::@715 Fcb
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_PIPE_MESSAGE_TYPE
Definition: iotypes.h:76
#define FILE_PIPE_CLIENT_END
Definition: iotypes.h:84
#define NPFS_NTC_CCB
Definition: npfs.h:115
ULONG Quota
Definition: npfs.h:144
Definition: npfs.h:131
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define STATUS_PIPE_CLOSING
Definition: ntstatus.h:413
#define FILE_PIPE_CONNECTED_STATE
Definition: winternl.h:792
ULONG NpFastWriteTrue
Definition: write.c:19
_Function_class_(IO_COMPLETION_ROUTINE)
Definition: write.c:28
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
Definition: npfs.h:258
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _Out_
Definition: no_sal2.h:323
#define IoCompleteRequest
Definition: irp.c:1240
ULONG QuotaUsed
Definition: npfs.h:142
Definition: bufpool.h:45
NodeType
Definition: Node.h:5
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
ULONG QueueState
Definition: npfs.h:139
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2659
ULONG BytesInQueue
Definition: npfs.h:140
LIST_ENTRY List
Definition: psmgr.c:57
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_PIPE_LISTENING
Definition: ntstatus.h:415
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1978
#define FILE_PIPE_SERVER_END
Definition: iotypes.h:85
#define IO_NAMED_PIPE_INCREMENT
Definition: iotypes.h:587
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
#define FILE_PIPE_COMPLETE_OPERATION
Definition: iotypes.h:80
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
Definition: typedefs.h:119
LONG NpSlowWriteCalls
Definition: write.c:18
#define _In_
Definition: no_sal2.h:204
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
PKEVENT Event
Definition: npfs.h:179
FORCEINLINE VOID NpReleaseVcb(VOID)
Definition: npfs.h:344
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define FILE_PIPE_OUTBOUND
Definition: iotypes.h:82
#define FILE_PIPE_DISCONNECTED_STATE
Definition: winternl.h:790
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI NpAddDataQueueEntry(IN ULONG NamedPipeEnd, IN PNP_CCB Ccb, IN PNP_DATA_QUEUE DataQueue, IN ULONG Who, IN ULONG Type, IN ULONG DataSize, IN PIRP Irp, IN PVOID Buffer, IN ULONG ByteOffset)
Definition: datasup.c:295
NTSTATUS NTAPI NpFsdWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: write.c:175
BOOLEAN NTAPI NpCommonWrite(IN PFILE_OBJECT FileObject, IN PVOID Buffer, IN ULONG DataSize, IN PETHREAD Thread, IN PIO_STATUS_BLOCK IoStatus, IN PIRP Irp, IN PLIST_ENTRY List)
Definition: write.c:26
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
NODE_TYPE_CODE NTAPI NpDecodeFileObject(IN PFILE_OBJECT FileObject, OUT PVOID *PrimaryContext OPTIONAL, OUT PNP_CCB *Ccb, OUT PULONG NamedPipeEnd OPTIONAL)
Definition: fileobsup.c:20
#define FILE_PIPE_INBOUND
Definition: iotypes.h:81
ERESOURCE Lock
Definition: npfs.h:254
USHORT NODE_TYPE_CODE
Definition: nodetype.h:22
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
ULONG NpFastWriteFalse
Definition: write.c:20
return STATUS_SUCCESS
Definition: btrfs.c:3014
FORCEINLINE VOID NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
Definition: npfs.h:356
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
#define FILE_PIPE_LISTENING_STATE
Definition: winternl.h:791
#define PAGED_CODE()
IN BOOLEAN Wait
Definition: fatprocs.h:1538