1 /* $Id: rw.c,v 1.4 2001/10/21 18:58:32 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/np/rw.c
6 * PURPOSE: Named pipe filesystem
7 * PROGRAMMER: David Welch <welch@cwcom.net>
10 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
19 /* FUNCTIONS *****************************************************************/
21 static inline VOID
NpfsFreePipeData(
22 PNPFS_PIPE_DATA PipeData
)
26 ExFreePool(PipeData
->Data
);
29 ExFreeToNPagedLookasideList(&NpfsPipeDataLookasideList
, PipeData
);
33 static inline PNPFS_PIPE_DATA
38 PNPFS_PIPE_DATA PipeData
;
40 PipeData
= ExAllocateFromNPagedLookasideList(&NpfsPipeDataLookasideList
);
46 PipeData
->Data
= Data
;
47 PipeData
->Size
= Size
;
54 static inline PNPFS_PIPE_DATA
55 NpfsInitializePipeData(
59 PNPFS_PIPE_DATA PipeData
;
62 Buffer
= ExAllocatePool(NonPagedPool
, Size
);
68 RtlMoveMemory(Buffer
, Data
, Size
);
70 PipeData
= NpfsAllocatePipeData(Buffer
, Size
);
81 NpfsRead(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
83 PIO_STACK_LOCATION IoStack
;
84 PFILE_OBJECT FileObject
;
86 PNPFS_DEVICE_EXTENSION DeviceExt
;
89 PLIST_ENTRY CurrentEntry
;
90 PNPFS_PIPE_DATA Current
;
98 DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
100 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
101 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
102 FileObject
= IoStack
->FileObject
;
103 Fcb
= FileObject
->FsContext
;
105 Status
= STATUS_SUCCESS
;
106 Length
= IoStack
->Parameters
.Read
.Length
;
108 DPRINT("Irp->MdlAddress %p\n", Irp
->MdlAddress
);
110 Buffer
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
111 KeAcquireSpinLock(&Pipe
->ServerDataListLock
, &OldIrql
);
113 if (Pipe
->PipeReadMode
& FILE_PIPE_BYTE_STREAM_MODE
)
115 DPRINT("Byte stream mode\n");
117 /* Byte stream mode */
119 CurrentEntry
= Pipe
->ServerDataListHead
.Flink
;
120 while ((Length
> 0) && (CurrentEntry
= RemoveHeadList(&Pipe
->ServerDataListHead
)))
122 Current
= CONTAINING_RECORD(CurrentEntry
, NPFS_PIPE_DATA
, ListEntry
);
124 DPRINT("Took pipe data at %p off the queue\n", Current
);
126 CopyLength
= RtlMin(Current
->Size
, Length
);
127 RtlCopyMemory(Buffer
,
128 ((PVOID
)((ULONG_PTR
)Current
->Data
+ Current
->Offset
)),
130 Buffer
+= CopyLength
;
131 Length
-= CopyLength
;
132 Information
+= CopyLength
;
134 /* Update the data buffer */
135 Current
->Offset
+= CopyLength
;
136 Current
->Size
-= CopyLength
;
138 CurrentEntry
= CurrentEntry
->Flink
;
141 if ((CurrentEntry
!= &Pipe
->ServerDataListHead
) && (Current
->Offset
!= Current
->Size
))
143 DPRINT("Putting pipe data at %p back in queue\n", Current
);
145 /* The caller's buffer could not contain the complete message,
146 so put it back on the queue */
147 InsertHeadList(&Pipe
->ServerDataListHead
, &Current
->ListEntry
);
152 DPRINT("Message mode\n");
155 CurrentEntry
= Pipe
->ServerDataListHead
.Flink
;
156 if (CurrentEntry
= RemoveHeadList(&Pipe
->ServerDataListHead
))
158 Current
= CONTAINING_RECORD(CurrentEntry
, NPFS_PIPE_DATA
, ListEntry
);
160 DPRINT("Took pipe data at %p off the queue\n", Current
);
162 /* Truncate the message if the receive buffer is too small */
163 CopyLength
= RtlMin(Current
->Size
, Length
);
164 RtlCopyMemory(Buffer
, Current
->Data
, CopyLength
);
165 Information
= CopyLength
;
167 Current
->Offset
+= CopyLength
;
169 CurrentEntry
= CurrentEntry
->Flink
;
173 KeReleaseSpinLock(&Pipe
->ServerDataListLock
, OldIrql
);
175 Irp
->IoStatus
.Status
= Status
;
176 Irp
->IoStatus
.Information
= Information
;
178 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
185 NpfsWrite(PDEVICE_OBJECT DeviceObject
,
188 PIO_STACK_LOCATION IoStack
;
189 PFILE_OBJECT FileObject
;
190 PNPFS_FCB Fcb
= NULL
;
191 PNPFS_PIPE Pipe
= NULL
;
193 NTSTATUS Status
= STATUS_SUCCESS
;
197 PNPFS_PIPE_DATA PipeData
;
199 DPRINT("NpfsWrite()\n");
201 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
202 FileObject
= IoStack
->FileObject
;
203 DPRINT("FileObject %p\n", FileObject
);
204 DPRINT("Pipe name %wZ\n", &FileObject
->FileName
);
206 Fcb
= FileObject
->FsContext
;
209 Length
= IoStack
->Parameters
.Write
.Length
;
210 Buffer
= MmGetSystemAddressForMdl (Irp
->MdlAddress
);
211 Offset
= IoStack
->Parameters
.Write
.ByteOffset
.u
.LowPart
;
213 PipeData
= NpfsInitializePipeData(Buffer
, Length
);
216 DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData
, Length
);
218 KeAcquireSpinLock(&Pipe
->ServerDataListLock
, &OldIrql
);
220 InsertTailList(&Pipe
->ServerDataListHead
, &PipeData
->ListEntry
);
222 KeReleaseSpinLock(&Pipe
->ServerDataListLock
, OldIrql
);
227 Status
= STATUS_INSUFFICIENT_RESOURCES
;
230 Irp
->IoStatus
.Status
= Status
;
231 Irp
->IoStatus
.Information
= Length
;
233 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);