ReactOS 0.4.15-dev-8348-gc1b9bb5
devctrl.c File Reference
#include "fatprocs.h"
Include dependency graph for devctrl.c:

Go to the source code of this file.

Macros

#define Dbg   (DEBUG_TRACE_DEVCTRL)
 

Functions

NTSTATUS NTAPI FatDeviceControlCompletionRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
 
 _Function_class_ (IRP_MJ_DEVICE_CONTROL)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
NTSTATUS NTAPI FatDeviceControlCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 

Variables

IO_COMPLETION_ROUTINE FatDeviceControlCompletionRoutine
 

Macro Definition Documentation

◆ Dbg

#define Dbg   (DEBUG_TRACE_DEVCTRL)

Definition at line 23 of file devctrl.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( IRP_MJ_DEVICE_CONTROL  )

Definition at line 48 of file devctrl.c.

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}
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define CanFsdWait(I)
Definition: cdprocs.h:2001
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
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
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define Dbg
Definition: devctrl.c:23
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 124 of file devctrl.c.

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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
@ 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 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 SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#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
#define FatReleaseVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1418
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
@ FlushWithoutPurge
Definition: fatprocs.h:1056
#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
IO_COMPLETION_ROUTINE FatDeviceControlCompletionRoutine
Definition: devctrl.c:32
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define KernelMode
Definition: asm.h:34
#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
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
_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
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
union _IO_STACK_LOCATION::@1565 Parameters
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _IO_STACK_LOCATION::@1565::@1566 DeviceIoControl
Definition: cdstruc.h:498
#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_ 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

◆ FatDeviceControlCompletionRoutine() [1/2]

NTSTATUS NTAPI FatDeviceControlCompletionRoutine ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  Contxt 
)

Definition at line 390 of file devctrl.c.

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}
#define PKEVENT
Definition: env_spec_w32.h:70
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ FatDeviceControlCompletionRoutine() [2/2]

NTSTATUS NTAPI FatDeviceControlCompletionRoutine ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Contxt 
)

Variable Documentation

◆ FatDeviceControlCompletionRoutine

IO_COMPLETION_ROUTINE FatDeviceControlCompletionRoutine

Definition at line 32 of file devctrl.c.

Referenced by _Requires_lock_held_().