ReactOS  0.4.13-dev-52-g0efcfec
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;
25  PMSFS_FCB Fcb;
26  PMSFS_CCB Ccb;
28  KIRQL oldIrql;
29  ULONG Length;
30  ULONG LengthRead = 0;
31  PVOID Buffer;
33  PKTIMER Timer;
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 
55  return STATUS_ACCESS_DENIED;
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 
77  ExFreePoolWithTag(Message, 'rFsM');
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;
137  PMSFS_FCB Fcb;
138  PMSFS_CCB Ccb;
140  KIRQL oldIrql;
141  ULONG Length;
142  PVOID Buffer;
143  PIRP CsqIrp;
145 
146  DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
147 
148  IoStack = IoGetCurrentIrpStackLocation (Irp);
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 
163  return STATUS_ACCESS_DENIED;
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 */
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _Entry Entry
Definition: kefuncs.h:640
NTKERNELAPI PIRP NTAPI IoCsqRemoveNextIrp(_Inout_ PIO_CSQ Csq, _In_opt_ PVOID PeekContext)
IoCsqRemoveNextIrp - Removes the next IRP from the queue.
Definition: csq.c:398
_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
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS DEFAULTAPI MsfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: rw.c:20
LONG NTSTATUS
Definition: precomp.h:26
#define InsertTailList(ListHead, Entry)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS DEFAULTAPI MsfsWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: rw.c:132
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
struct _MSFS_FCB * PMSFS_FCB
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define STATUS_PENDING
Definition: ntstatus.h:82
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1954
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: ketypes.h:687
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
Definition: typedefs.h:117
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
UINT Timer
Definition: capclock.c:11
static ULONG Timeout
Definition: ping.c:61
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define min(a, b)
Definition: monoChain.cc:55
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
KDEFERRED_ROUTINE MsfsTimeout
Definition: msfs.h:129
#define DEFAULTAPI
Definition: msfs.h:15
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
Definition: msfs.h:24
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
_In_ PFCB Fcb
Definition: cdprocs.h:151
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
Definition: msfs.h:54
base of all file and directory entries
Definition: entries.h:82