ReactOS 0.4.15-dev-7659-ga55345b
rw.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/filesystems/msfs/rw.c
5 * PURPOSE: Mailslot filesystem
6 * PROGRAMMER: Eric Kohl
7 * Nikita Pechenkin (n.pechenkin@mail.ru)
8 */
9
10/* INCLUDES ******************************************************************/
11
12#include "msfs.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/* FUNCTIONS *****************************************************************/
18
21 PIRP Irp)
22{
23 PIO_STACK_LOCATION IoStack;
28 KIRQL oldIrql;
30 ULONG LengthRead = 0;
35 PKDPC Dpc;
37
38 DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
39
41 FileObject = IoStack->FileObject;
42 Fcb = (PMSFS_FCB)FileObject->FsContext;
43 Ccb = (PMSFS_CCB)FileObject->FsContext2;
44
45 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
46
47 /* reading is not permitted on client side */
48 if (Fcb->ServerCcb != Ccb)
49 {
50 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
51 Irp->IoStatus.Information = 0;
52
54
56 }
57
58 Length = IoStack->Parameters.Read.Length;
59 if (Irp->MdlAddress)
61 else
62 Buffer = Irp->UserBuffer;
63
64
65 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
66 if (Fcb->MessageCount > 0)
67 {
68 Entry = RemoveHeadList(&Fcb->MessageListHead);
69 Fcb->MessageCount--;
70 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
71
72 /* copy current message into buffer */
73 Message = CONTAINING_RECORD(Entry, MSFS_MESSAGE, MessageListEntry);
74 memcpy(Buffer, &Message->Buffer, min(Message->Size,Length));
75 LengthRead = Message->Size;
76
78
79 Irp->IoStatus.Status = STATUS_SUCCESS;
80 Irp->IoStatus.Information = LengthRead;
82
83 return STATUS_SUCCESS;
84 }
85 else
86 {
87 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
88 }
89
90 Timeout = Fcb->TimeOut;
91 if (Timeout.HighPart == 0 && Timeout.LowPart == 0)
92 {
93 Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
94 Irp->IoStatus.Information = 0;
96
97 return STATUS_IO_TIMEOUT;
98 }
99
101 if (Context == NULL)
102 {
103 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
104 Irp->IoStatus.Information = 0;
106
108 }
109
111 IoCsqInsertIrp(&Fcb->CancelSafeQueue, Irp, &Context->CsqContext);
112 Timer = &Context->Timer;
113 Dpc = &Context->Dpc;
114 Context->Csq = &Fcb->CancelSafeQueue;
115 Irp->Tail.Overlay.DriverContext[0] = Context;
116
117 /* No timer for INFINITY_WAIT */
118 if (Timeout.QuadPart != -1)
119 {
123 }
124
126
127 return STATUS_PENDING;
128}
129
130
133 PIRP Irp)
134{
135 PIO_STACK_LOCATION IoStack;
140 KIRQL oldIrql;
143 PIRP CsqIrp;
145
146 DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
147
149 FileObject = IoStack->FileObject;
150 Fcb = (PMSFS_FCB)FileObject->FsContext;
151 Ccb = (PMSFS_CCB)FileObject->FsContext2;
152
153 DPRINT("MailslotName: %wZ\n", &Fcb->Name);
154
155 /* writing is not permitted on server side */
156 if (Fcb->ServerCcb == Ccb)
157 {
158 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
159 Irp->IoStatus.Information = 0;
160
162
164 }
165
166 Length = IoStack->Parameters.Write.Length;
167 if (Irp->MdlAddress)
169 else
170 Buffer = Irp->UserBuffer;
171
172 DPRINT("Length: %lu Message: %s\n", Length, (PUCHAR)Buffer);
173
174 /* Allocate new message */
176 sizeof(MSFS_MESSAGE) + Length,
177 'rFsM');
178 if (Message == NULL)
179 {
180 Irp->IoStatus.Status = STATUS_NO_MEMORY;
181 Irp->IoStatus.Information = 0;
182
184
185 return STATUS_NO_MEMORY;
186 }
187
188 Message->Size = Length;
189 memcpy(&Message->Buffer, Buffer, Length);
190
191 KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
192 InsertTailList(&Fcb->MessageListHead, &Message->MessageListEntry);
193 Fcb->MessageCount++;
194 KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
195
196 CsqIrp = IoCsqRemoveNextIrp(&Fcb->CancelSafeQueue, NULL);
197 if (CsqIrp != NULL)
198 {
199 /* Get the context */
200 Context = CsqIrp->Tail.Overlay.DriverContext[0];
201 /* DPC was queued, wait for it to fail (IRP is ours) */
202 if (Fcb->TimeOut.QuadPart != -1 && !KeCancelTimer(&Context->Timer))
203 {
205 }
206
207 /* Free context & attempt read */
208 ExFreePoolWithTag(Context, 'NFsM');
209 MsfsRead(DeviceObject, CsqIrp);
210 }
211
212 Irp->IoStatus.Status = STATUS_SUCCESS;
213 Irp->IoStatus.Information = Length;
214
216
217 return STATUS_SUCCESS;
218}
219
220/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
NTKERNELAPI VOID NTAPI IoCsqInsertIrp(_Inout_ PIO_CSQ Csq, _Inout_ PIRP Irp, _Out_opt_ PIO_CSQ_IRP_CONTEXT Context)
Insert an IRP into the CSQ.
Definition: csq.c:177
NTKERNELAPI PIRP NTAPI IoCsqRemoveNextIrp(_Inout_ PIO_CSQ Csq, _In_opt_ PVOID PeekContext)
IoCsqRemoveNextIrp - Removes the next IRP from the queue.
Definition: csq.c:398
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
static const WCHAR Message[]
Definition: register.c:74
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
IoMarkIrpPending(Irp)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ NormalPagePriority
Definition: imports.h:56
#define min(a, b)
Definition: monoChain.cc:55
DRIVER_DISPATCH MsfsRead
Definition: msfs.h:92
KDEFERRED_ROUTINE MsfsTimeout
Definition: msfs.h:129
#define DEFAULTAPI
Definition: msfs.h:15
DRIVER_DISPATCH MsfsWrite
Definition: msfs.h:95
struct _MSFS_FCB * PMSFS_FCB
#define KernelMode
Definition: asm.h:34
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ SynchronizationEvent
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
static ULONG Timeout
Definition: ping.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:83
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: ketypes.h:699
Definition: typedefs.h:120
Definition: msfs.h:55
Definition: msfs.h:25
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:415
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)