Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / drivers / filesystems / reiserfs / src / dispatch.c
1 /*
2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
4 * FILE: dispatch.c
5 * PURPOSE:
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
7 * HOMEPAGE:
8 * UPDATE HISTORY:
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include "rfsd.h"
14
15 /* GLOBALS ***************************************************************/
16
17 extern PRFSD_GLOBAL RfsdGlobal;
18
19 /* DEFINITIONS *************************************************************/
20
21 #ifdef ALLOC_PRAGMA
22 #pragma alloc_text(PAGE, RfsdQueueRequest)
23 #pragma alloc_text(PAGE, RfsdDeQueueRequest)
24 #pragma alloc_text(PAGE, RfsdDispatchRequest)
25 #pragma alloc_text(PAGE, RfsdBuildRequest)
26 #endif
27
28 NTSTATUS
29 RfsdQueueRequest (IN PRFSD_IRP_CONTEXT IrpContext)
30 {
31 PAGED_CODE();
32
33 ASSERT(IrpContext);
34
35 ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
36 (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
37
38 // IsSynchronous means we can block (so we don't requeue it)
39 IrpContext->IsSynchronous = TRUE;
40
41 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
42
43 IoMarkIrpPending(IrpContext->Irp);
44
45 ExInitializeWorkItem(
46 &IrpContext->WorkQueueItem,
47 RfsdDeQueueRequest,
48 IrpContext );
49
50 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
51
52 return STATUS_PENDING;
53 }
54
55 VOID NTAPI
56 RfsdDeQueueRequest (IN PVOID Context)
57 {
58 PRFSD_IRP_CONTEXT IrpContext;
59
60 PAGED_CODE();
61
62 IrpContext = (PRFSD_IRP_CONTEXT) Context;
63
64 ASSERT(IrpContext);
65
66 ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
67 (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
68
69 _SEH2_TRY {
70
71 _SEH2_TRY {
72
73 FsRtlEnterFileSystem();
74
75 if (!IrpContext->IsTopLevel) {
76
77 IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
78 }
79
80 RfsdDispatchRequest(IrpContext);
81
82 } _SEH2_EXCEPT (RfsdExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
83
84 RfsdExceptionHandler(IrpContext);
85 } _SEH2_END;
86
87 } _SEH2_FINALLY {
88
89 IoSetTopLevelIrp(NULL);
90
91 FsRtlExitFileSystem();
92 } _SEH2_END;
93 }
94
95 __drv_mustHoldCriticalRegion
96 NTSTATUS
97 RfsdDispatchRequest (IN PRFSD_IRP_CONTEXT IrpContext)
98 {
99 PAGED_CODE();
100
101 ASSERT(IrpContext);
102
103 ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
104 (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
105
106 switch (IrpContext->MajorFunction) {
107
108 case IRP_MJ_CREATE:
109 return RfsdCreate(IrpContext);
110
111 case IRP_MJ_CLOSE:
112 return RfsdClose(IrpContext);
113
114 case IRP_MJ_READ:
115 return RfsdRead(IrpContext);
116
117 #if !RFSD_READ_ONLY
118 case IRP_MJ_WRITE:
119 return RfsdWrite(IrpContext);
120 #endif // !RFSD_READ_ONLY
121
122 case IRP_MJ_FLUSH_BUFFERS:
123 return RfsdFlush(IrpContext);
124
125 case IRP_MJ_QUERY_INFORMATION:
126 return RfsdQueryInformation(IrpContext);
127
128 case IRP_MJ_SET_INFORMATION:
129 return RfsdSetInformation(IrpContext);
130
131 case IRP_MJ_QUERY_VOLUME_INFORMATION:
132 return RfsdQueryVolumeInformation(IrpContext);
133
134 #if !RFSD_READ_ONLY
135 case IRP_MJ_SET_VOLUME_INFORMATION:
136 return RfsdSetVolumeInformation(IrpContext);
137 #endif // !RFSD_READ_ONLY
138
139 case IRP_MJ_DIRECTORY_CONTROL:
140 return RfsdDirectoryControl(IrpContext);
141
142 case IRP_MJ_FILE_SYSTEM_CONTROL:
143 return RfsdFileSystemControl(IrpContext);
144
145 case IRP_MJ_DEVICE_CONTROL:
146 return RfsdDeviceControl(IrpContext);
147
148 case IRP_MJ_LOCK_CONTROL:
149 return RfsdLockControl(IrpContext);
150
151 case IRP_MJ_CLEANUP:
152 return RfsdCleanup(IrpContext);
153
154 case IRP_MJ_SHUTDOWN:
155 return RfsdShutDown(IrpContext);
156
157 #if (_WIN32_WINNT >= 0x0500)
158 case IRP_MJ_PNP:
159 return RfsdPnp(IrpContext);
160 #endif //(_WIN32_WINNT >= 0x0500)
161 default:
162 {
163 NTSTATUS DefaultRC = STATUS_INVALID_DEVICE_REQUEST;
164
165 RfsdPrint((DBG_ERROR, "RfsdDispatchRequest: Unexpected major function: %xh\n",
166 IrpContext->MajorFunction));
167
168 RfsdCompleteIrpContext(IrpContext, DefaultRC);
169
170 return DefaultRC;
171 }
172 }
173 }
174
175 NTSTATUS NTAPI
176 RfsdBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
177 {
178 BOOLEAN AtIrqlPassiveLevel = FALSE;
179 BOOLEAN IsTopLevelIrp = FALSE;
180 PRFSD_IRP_CONTEXT IrpContext = NULL;
181 NTSTATUS Status = STATUS_UNSUCCESSFUL;
182
183 PAGED_CODE();
184
185 _SEH2_TRY {
186
187 _SEH2_TRY {
188
189 #if DBG
190 RfsdDbgPrintCall(DeviceObject, Irp);
191 #endif
192
193 AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);
194
195 if (AtIrqlPassiveLevel) {
196
197 FsRtlEnterFileSystem();
198 }
199
200 if (!IoGetTopLevelIrp()) {
201
202 IsTopLevelIrp = TRUE;
203 IoSetTopLevelIrp(Irp);
204 }
205
206 IrpContext = RfsdAllocateIrpContext(DeviceObject, Irp);
207
208 if (!IrpContext) {
209
210 Status = STATUS_INSUFFICIENT_RESOURCES;
211 Irp->IoStatus.Status = Status;
212
213 RfsdCompleteRequest(Irp, TRUE, IO_NO_INCREMENT);
214
215 } else {
216
217 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
218 !AtIrqlPassiveLevel) {
219
220 DbgBreak();
221 }
222
223 Status = RfsdDispatchRequest(IrpContext);
224 }
225 } _SEH2_EXCEPT (RfsdExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
226
227 Status = RfsdExceptionHandler(IrpContext);
228 } _SEH2_END;
229
230 } _SEH2_FINALLY {
231
232 if (IsTopLevelIrp) {
233 IoSetTopLevelIrp(NULL);
234 }
235
236 if (AtIrqlPassiveLevel) {
237 FsRtlExitFileSystem();
238 }
239 } _SEH2_END;
240
241 return Status;
242 }