ReactOS 0.4.15-dev-8096-ga0eec98
devctrl.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 DevCtrl.c
8
9Abstract:
10
11 This module implements the File System Device Control routines for Fat
12 called by the dispatch driver.
13
14
15--*/
16
17#include "fatprocs.h"
18
19//
20// The local debug trace level
21//
22
23#define Dbg (DEBUG_TRACE_DEVCTRL)
24
25//
26// Local procedure prototypes
27//
28
29//
30// Tell prefast this is an IO_COMPLETION_ROUTINE
31//
33
38 IN PIRP Irp,
39 IN PVOID Contxt
40 );
41
42#ifdef ALLOC_PRAGMA
43#pragma alloc_text(PAGE, FatCommonDeviceControl)
44#pragma alloc_text(PAGE, FatFsdDeviceControl)
45#endif
46
47
52FatFsdDeviceControl (
53 _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
55 )
56
57/*++
58
59Routine Description:
60
61 This routine implements the FSD part of Device control operations
62
63Arguments:
64
65 VolumeDeviceObject - Supplies the volume device object where the
66 file exists
67
68 Irp - Supplies the Irp being processed
69
70Return Value:
71
72 NTSTATUS - The FSD status for the IRP
73
74--*/
75
76{
78 PIRP_CONTEXT IrpContext = NULL;
79
81
82 PAGED_CODE();
83
84 DebugTrace(+1, Dbg, "FatFsdDeviceControl\n", 0);
85
87
89
90 _SEH2_TRY {
91
92 IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ));
93
94 Status = FatCommonDeviceControl( IrpContext, Irp );
95
97
98 //
99 // We had some trouble trying to perform the requested
100 // operation, so we'll abort the I/O request with
101 // the error status that we get back from the
102 // exception code
103 //
104
105 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
106 } _SEH2_END;
107
108 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
109
111
112 //
113 // And return to our caller
114 //
115
116 DebugTrace(-1, Dbg, "FatFsdDeviceControl -> %08lx\n", Status);
117
118 UNREFERENCED_PARAMETER( VolumeDeviceObject );
119
120 return Status;
121}
122
123
124_Requires_lock_held_(_Global_critical_region_)
126FatCommonDeviceControl (
127 IN PIRP_CONTEXT IrpContext,
128 IN PIRP Irp
129 )
130
131/*++
132
133Routine Description:
134
135 This is the common routine for doing Device control operations called
136 by both the fsd and fsp threads
137
138Arguments:
139
140 Irp - Supplies the Irp to process
141
142 InFsp - Indicates if this is the fsp thread or someother thread
143
144Return Value:
145
146 NTSTATUS - The return status for the operation
147
148--*/
149
150{
153 KEVENT WaitEvent;
155
156 PVCB Vcb;
157 PFCB Fcb;
158 PCCB Ccb;
159
160 PAGED_CODE();
161
162 //
163 // Get a pointer to the current Irp stack location
164 //
165
167
168 DebugTrace(+1, Dbg, "FatCommonDeviceControl\n", 0);
169 DebugTrace( 0, Dbg, "Irp = %p\n", Irp);
170 DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction);
171
172 //
173 // Decode the file object, the only type of opens we accept are
174 // user volume opens.
175 //
176
178
180
181 DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER);
183 }
184
185 //
186 // A few IOCTLs actually require some intervention on our part
187 //
188
189 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
190
192
193 //
194 // This is sent by the Volume Snapshot driver (Lovelace).
195 // We flush the volume, and hold all file resources
196 // to make sure that nothing more gets dirty. Then we wait
197 // for the IRP to complete or cancel.
198 //
199
200 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
201 FatAcquireExclusiveVolume( IrpContext, Vcb );
202
203 FatFlushAndCleanVolume( IrpContext,
204 Irp,
205 Vcb,
207
209 CompletionContext = &WaitEvent;
210
211 //
212 // Get the next stack location, and copy over the stack location
213 //
214
216
217 //
218 // Set up the completion routine
219 //
220
224 TRUE,
225 TRUE,
226 TRUE );
227 break;
228
230
231 //
232 // We cannot allow this IOCTL to be sent unless the volume is locked,
233 // since this IOCTL allows direct writing of data to the volume.
234 // We do allow kernel callers to force access via a flag. A handle that
235 // issued a dismount can send this IOCTL as well.
236 //
237
238 if (!FlagOn( Vcb->VcbState, VCB_STATE_FLAG_LOCKED ) &&
241
242 FatCompleteRequest( IrpContext,
243 Irp,
245
246 DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", STATUS_ACCESS_DENIED);
248 }
249
250 break;
251
256
257 //
258 // If someone is issuing a format unit command underneath us, then make
259 // sure we mark the device as needing verification when they close their
260 // handle.
261 //
262
263 if ((!FlagOn( IrpSp->FileObject->Flags, FO_FILE_MODIFIED ) ||
265 (Irp->AssociatedIrp.SystemBuffer != NULL)) {
266
267 PCDB Cdb = NULL;
268
269 //
270 // If this is a 32 bit application running on 64 bit then thunk the
271 // input structures to grab the Cdb.
272 //
273
274#if defined (_WIN64) && defined(BUILD_WOW64_ENABLED)
275 if (IoIs32bitProcess(Irp)) {
276
277 if ( (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH) ||
279
280 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( SCSI_PASS_THROUGH32 )) {
281
282 Cdb = (PCDB)((PSCSI_PASS_THROUGH32)(Irp->AssociatedIrp.SystemBuffer))->Cdb;
283 }
284 } else {
285
286 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( SCSI_PASS_THROUGH32_EX )) {
287
288 Cdb = (PCDB)((PSCSI_PASS_THROUGH32_EX)(Irp->AssociatedIrp.SystemBuffer))->Cdb;
289 }
290 }
291
292 } else {
293#endif
294 if ( (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH) ||
296
297 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( SCSI_PASS_THROUGH )) {
298
299 Cdb = (PCDB)((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->Cdb;
300 }
301 } else {
302
303 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( SCSI_PASS_THROUGH_EX )) {
304
305 Cdb = (PCDB)((PSCSI_PASS_THROUGH_EX)(Irp->AssociatedIrp.SystemBuffer))->Cdb;
306 }
307 }
308
309#if defined (_WIN64) && defined(BUILD_WOW64_ENABLED)
310 }
311#endif
312
313 if ((Cdb != NULL) && (Cdb->AsByte[0] == SCSIOP_FORMAT_UNIT)) {
314
317 }
318 }
319
320 //
321 // Fall through as we do not need to know the outcome of this operation.
322 //
323
324 default:
325
326 //
327 // FAT doesn't need to see this on the way back, so skip ourselves.
328 //
329
331 break;
332 }
333
334 //
335 // Send the request.
336 //
337
338 Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
339
341
342 KeWaitForSingleObject( &WaitEvent,
343 Executive,
345 FALSE,
346 NULL );
347
348 Status = Irp->IoStatus.Status;
349 }
350
351 //
352 // If we had a context, the IRP remains for us and we will complete it.
353 // Handle it appropriately.
354 //
355
356 if (CompletionContext) {
357
358 //
359 // Release all the resources that we held because of a
360 // VOLSNAP_FLUSH_AND_HOLD.
361 //
362
364
365 FatReleaseVolume( IrpContext, Vcb );
366
367 //
368 // If we had no context, the IRP will complete asynchronously.
369 //
370
371 } else {
372
373 Irp = NULL;
374 }
375
376 FatCompleteRequest( IrpContext, Irp, Status );
377
378 DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", Status);
379
380 return Status;
381}
382
383
384//
385// Local support routine
386//
387
389NTAPI
392 _In_ PIRP Irp,
393 _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
394 )
395
396{
397 PKEVENT Event = (PKEVENT) Contxt;
398
399 //
400 // If there is an event, this is a synch request. Signal and
401 // let I/O know this isn't done yet.
402 //
403
404 if (Event) {
405
406 KeSetEvent( Event, 0, FALSE );
408 }
409
412
413 return STATUS_SUCCESS;
414}
415
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define CanFsdWait(I)
Definition: cdprocs.h:2001
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define SCSIOP_FORMAT_UNIT
Definition: cdrw_hw.h:871
union _CDB * PCDB
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define _Requires_lock_held_(lock)
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#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 PKEVENT
Definition: env_spec_w32.h:70
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define FatAcquireExclusiveVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1409
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
#define FatReleaseVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1418
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
@ FlushWithoutPurge
Definition: fatprocs.h:1056
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define VCB_STATE_FLAG_LOCKED
Definition: fatstruc.h:559
#define CCB_FLAG_SENT_FORMAT_UNIT
Definition: fatstruc.h:1345
#define CCB_FLAG_COMPLETE_DISMOUNT
Definition: fatstruc.h:1331
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
IO_COMPLETION_ROUTINE FatDeviceControlCompletionRoutine
Definition: devctrl.c:32
#define Dbg
Definition: devctrl.c:23
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define _Inout_
Definition: ms_sal.h:378
#define _In_reads_opt_(size)
Definition: ms_sal.h:320
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IOCTL_DISK_COPY_DATA
Definition: ntdddisk.h:251
@ NotificationEvent
#define IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define IOCTL_SCSI_PASS_THROUGH_DIRECT_EX
Definition: ntddscsi.h:38
#define IOCTL_SCSI_PASS_THROUGH_EX
Definition: ntddscsi.h:37
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1567 Parameters
struct _IO_STACK_LOCATION::@1567::@1568 DeviceIoControl
Definition: cdstruc.h:498
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: cdrw_hw.h:28
UCHAR AsByte[16]
Definition: scsi.h:1988
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:898
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define SL_FORCE_DIRECT_WRITE
Definition: iotypes.h:1826
@ Executive
Definition: ketypes.h:415
#define NT_ASSERT
Definition: rtlfuncs.h:3310