ReactOS  0.4.14-dev-317-g96040ec
pnp.cpp File Reference
#include "udffs.h"
Include dependency graph for pnp.cpp:

Go to the source code of this file.

Macros

#define UDF_BUG_CHECK_ID   UDF_FILE_PNP
 

Functions

NTSTATUS UDFPnpQueryRemove (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
 
NTSTATUS UDFPnpRemove (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
 
NTSTATUS UDFPnpSurpriseRemove (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
 
NTSTATUS UDFPnpCancelRemove (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
 
NTSTATUS NTAPI UDFPnpCompletionRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
 
NTSTATUS UDFCommonPnp (PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
 
NTSTATUS UDFPnp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Macro Definition Documentation

◆ UDF_BUG_CHECK_ID

#define UDF_BUG_CHECK_ID   UDF_FILE_PNP

Definition at line 21 of file pnp.cpp.

Function Documentation

◆ UDFCommonPnp()

NTSTATUS UDFCommonPnp ( PtrUDFIrpContext  PtrIrpContext,
IN PIRP  Irp 
)

Definition at line 145 of file pnp.cpp.

149 {
150  NTSTATUS RC;
152  PVCB Vcb;
153  UDFPrint(("UDFCommonPnp\n"));
154 
155  _SEH2_TRY {
156  // Get the current Irp stack location.
158 
159  // Make sure this device object really is big enough to be a volume device
160  // object. If it isn't, we need to get out before we try to reference some
161  // field that takes us past the end of an ordinary device object.
163 
164  if (Vcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB) {
165  // We were called with something we don't understand.
166  if(Irp->Flags & IRP_INPUT_OPERATION) {
167  Irp->IoStatus.Information = 0;
168  }
169  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
170 
173  }
174 
175  // Force everything to wait.
176  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_CAN_BLOCK;
177 
178  // Case on the minor code.
179  switch ( IrpSp->MinorFunction ) {
180 
182  RC = UDFPnpQueryRemove( PtrIrpContext, Irp, Vcb );
183  break;
184 
186  RC = UDFPnpSurpriseRemove( PtrIrpContext, Irp, Vcb );
187  break;
188 
190  RC = UDFPnpRemove( PtrIrpContext, Irp, Vcb );
191  break;
192 
193 /* case IRP_MN_CANCEL_REMOVE_DEVICE:
194  RC = UDFPnpCancelRemove( PtrIrpContext, Irp, Vcb );
195  break;*/
196 
197  default:
198  UDFPrint(("UDFCommonPnp: pass through\n"));
199  // Just pass the IRP on. As we do not need to be in the
200  // way on return, ellide ourselves out of the stack.
202  RC = IoCallDriver(Vcb->TargetDeviceObject, Irp);
203  ASSERT(RC != STATUS_PENDING);
204 
205  break;
206  }
207 
208 try_exit: NOTHING;
209 
210  } _SEH2_FINALLY {
211  UDFReleaseIrpContext(PtrIrpContext);
212  } _SEH2_END;
213 
214  return RC;
215 }
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define UDFPrint(Args)
Definition: udffs.h:225
#define IRP_MN_REMOVE_DEVICE
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
LONG NTSTATUS
Definition: precomp.h:26
Definition: cdstruc.h:504
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
_SEH2_TRY
Definition: create.c:4250
NTSTATUS UDFPnpSurpriseRemove(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
Definition: pnp.cpp:504
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define IRP_MN_QUERY_REMOVE_DEVICE
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
uint32 IrpContextFlags
Definition: struct.h:364
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2189
#define Vcb
Definition: cdprocs.h:1425
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_SEH2_END
Definition: create.c:4424
#define IRP_INPUT_OPERATION
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
NTSTATUS UDFPnpQueryRemove(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
Definition: pnp.cpp:235
NTSTATUS UDFPnpRemove(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb)
Definition: pnp.cpp:380

Referenced by UDFPnp().

◆ UDFPnp()

NTSTATUS UDFPnp ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 81 of file pnp.cpp.

85 {
86  NTSTATUS RC;
87  PtrUDFIrpContext PtrIrpContext = NULL;
88  BOOLEAN AreWeTopLevel;
89 
90  UDFPrint(("UDFPnp\n"));
91  ASSERT(FALSE);
92 
95  ASSERT(Irp);
96 
97  // set the top level context
98  AreWeTopLevel = UDFIsIrpTopLevel(Irp);
99 
100  _SEH2_TRY {
101  // We expect there to never be a fileobject, in which case we will always
102  // wait. Since at the moment we don't have any concept of pending Pnp
103  // operations, this is a bit nitpicky.
104 
105  // get an IRP context structure and issue the request
106  PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
107  if(PtrIrpContext) {
108  RC = UDFCommonPnp(PtrIrpContext, Irp);
109  } else {
111  Irp->IoStatus.Status = RC;
112  Irp->IoStatus.Information = 0;
113  // complete the IRP
115  }
116 
118 
119  RC = UDFExceptionHandler(PtrIrpContext, Irp);
121  } _SEH2_END;
122 
123  if (AreWeTopLevel) {
125  }
126 
128 
129  return RC;
130 }
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
#define UDFPrint(Args)
Definition: udffs.h:225
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
_SEH2_TRY
Definition: create.c:4250
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
_SEH2_END
Definition: create.c:4424
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS UDFCommonPnp(PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: pnp.cpp:145

◆ UDFPnpCancelRemove()

NTSTATUS UDFPnpCancelRemove ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVCB  Vcb 
)

◆ UDFPnpCompletionRoutine()

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

Definition at line 731 of file pnp.cpp.

736 {
737  PKEVENT Event = (PKEVENT) Contxt;
738 
739  KeSetEvent( Event, 0, FALSE );
740 
742 
744  UNREFERENCED_PARAMETER( Contxt );
745 }
struct _KEVENT * PKEVENT
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560

Referenced by UDFPnpQueryRemove(), UDFPnpRemove(), and UDFPnpSurpriseRemove().

◆ UDFPnpQueryRemove()

NTSTATUS UDFPnpQueryRemove ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVCB  Vcb 
)

Definition at line 235 of file pnp.cpp.

240 {
241  NTSTATUS RC;
242  KEVENT Event;
243  BOOLEAN VcbDeleted = FALSE;
244  BOOLEAN GlobalHeld = FALSE;
245  BOOLEAN VcbAcquired = FALSE;
247 
248  // Having said yes to a QUERY, any communication with the
249  // underlying storage stack is undefined (and may block)
250  // until the bounding CANCEL or REMOVE is sent.
251 
252  _SEH2_TRY {
253 
254  // Acquire the global resource so that we can try to vaporize
255  // the volume, and the vcb resource itself.
256  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
257  GlobalHeld = TRUE;
258 
259  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
260  UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
261 #ifdef UDF_DELAYED_CLOSE
263 #endif //UDF_DELAYED_CLOSE
264 
265  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
266  VcbAcquired = TRUE;
267 
269  // With the volume held locked, note that we must finalize as much
270  // as possible right now.
272 
273  // disable Eject Request Waiter if any
274  UDFReleaseResource( &(Vcb->VCBResource) );
275  VcbAcquired = FALSE;
277  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
278  VcbAcquired = TRUE;
279 
280  // We need to pass this down before starting the dismount, which
281  // could disconnect us immediately from the stack.
282 
283  // Get the next stack location, and copy over the stack location
285 
286  // Set up the completion routine
290  &Event,
291  TRUE,
292  TRUE,
293  TRUE );
294  // Send the request and wait.
295  RC = IoCallDriver(Vcb->TargetDeviceObject, Irp);
296 
297  if (RC == STATUS_PENDING) {
299  Executive,
300  KernelMode,
301  FALSE,
302  NULL );
303 
304  RC = Irp->IoStatus.Status;
305  }
306 
307  // Now if no one below us failed already, initiate the dismount
308  // on this volume, make it go away. PnP needs to see our internal
309  // streams close and drop their references to the target device.
310 
311  // Since we were able to lock the volume, we are guaranteed to
312  // move this volume into dismount state and disconnect it from
313  // the underlying storage stack. The force on our part is actually
314  // unnecesary, though complete.
315 
316  // What is not strictly guaranteed, though, is that the closes
317  // for the metadata streams take effect synchronously underneath
318  // of this call. This would leave references on the target device
319  // even though we are disconnected!
320  if (NT_SUCCESS( RC )) {
321  VcbDeleted = !UDFCheckForDismount( PtrIrpContext, Vcb, TRUE );
322  ASSERT( VcbDeleted );
323  }
324 
325  // Release the Vcb if it could still remain.
326 
327  // Note: if everything else succeeded and the Vcb is persistent because the
328  // internal streams did not vaporize, we really need to pend this IRP off on
329  // the side until the dismount is completed. I can't think of a reasonable
330  // case (in UDF) where this would actually happen, though it might still need
331  // to be implemented.
332  //
333  // The reason this is the case is that handles/fileobjects place a reference
334  // on the device objects they overly. In the filesystem case, these references
335  // are on our target devices. PnP correcly thinks that if references remain
336  // on the device objects in the stack that someone has a handle, and that this
337  // counts as a reason to not succeed the query - even though every interrogated
338  // driver thinks that it is OK.
339  ASSERT( !(NT_SUCCESS( RC ) && !VcbDeleted ));
340 
341  } _SEH2_FINALLY {
342 
343  if (!VcbDeleted && VcbAcquired) {
344  UDFReleaseResource( &(Vcb->VCBResource) );
345  }
346 
347  if (GlobalHeld) {
348  UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
349  }
350 
351  if (!_SEH2_AbnormalTermination()) {
352  Irp->IoStatus.Status = RC;
353  // Free up the Irp Context
354  UDFReleaseIrpContext(PtrIrpContext);
355  // complete the IRP
357  }
358  } _SEH2_END;
359 
360  return RC;
361 } // end UDFPnpQueryRemove()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define TRUE
Definition: types.h:120
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
_In_ PIRP Irp
Definition: csq.h:116
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
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
struct _PREVENT_MEDIA_REMOVAL_USER_IN * PPREVENT_MEDIA_REMOVAL_USER_IN
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
NTSTATUS NTAPI UDFPnpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
Definition: pnp.cpp:731
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define IoCompleteRequest
Definition: irp.c:1240
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1425
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
UDFData UDFGlobalData
Definition: udfinit.cpp:25
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
OSSTATUS UDFDoDismountSequence(IN PVCB Vcb, IN PPREVENT_MEDIA_REMOVAL_USER_IN Buf, IN BOOLEAN Eject)
Definition: phys_eject.cpp:704

Referenced by UDFCommonPnp().

◆ UDFPnpRemove()

NTSTATUS UDFPnpRemove ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVCB  Vcb 
)

Definition at line 380 of file pnp.cpp.

385 {
386  NTSTATUS RC;
387  KEVENT Event;
388  BOOLEAN VcbDeleted;
389  BOOLEAN VcbAcquired;
391 
392  // REMOVE - a storage device is now gone. We either got
393  // QUERY'd and said yes OR got a SURPRISE OR a storage
394  // stack failed to spin back up from a sleep/stop state
395  // (the only case in which this will be the first warning).
396  //
397  // Note that it is entirely unlikely that we will be around
398  // for a REMOVE in the first two cases, as we try to intiate
399  // dismount.
400 
401  // Acquire the global resource so that we can try to vaporize
402  // the volume, and the vcb resource itself.
403  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
404 
405  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
406  UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
407 #ifdef UDF_DELAYED_CLOSE
409 #endif //UDF_DELAYED_CLOSE
410 
411  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
412  VcbAcquired = TRUE;
413 
414  // The device will be going away. Remove our lock (benign
415  // if we never had it).
416  if((Vcb->Vpb->Flags & VPB_LOCKED) ||
417  (Vcb->VolumeLockPID != (ULONG)-1) ) {
418  Vcb->Vpb->Flags &= ~VPB_LOCKED;
419  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_LOCKED;
420  Vcb->VolumeLockFileObject = NULL;
421  Vcb->VolumeLockPID = -1;
422  RC = STATUS_SUCCESS;
423  }
424 
425  // We need to pass this down before starting the dismount, which
426  // could disconnect us immediately from the stack.
427 
428  // Get the next stack location, and copy over the stack location
430 
431  // Set up the completion routine
435  &Event,
436  TRUE,
437  TRUE,
438  TRUE );
439 
440  // Send the request and wait.
441  RC = IoCallDriver(Vcb->TargetDeviceObject, Irp);
442 
443  if (RC == STATUS_PENDING) {
444 
446  Executive,
447  KernelMode,
448  FALSE,
449  NULL );
450 
451  RC = Irp->IoStatus.Status;
452  }
453 
454  _SEH2_TRY {
455 
456  // Knock as many files down for this volume as we can.
457 
458  // Now make our dismount happen. This may not vaporize the
459  // Vcb, of course, since there could be any number of handles
460  // outstanding if we were not preceeded by a QUERY.
461  //
462  // PnP will take care of disconnecting this stack if we
463  // couldn't get off of it immediately.
464  Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
468  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
469  Vcb->WriteSecurity = FALSE;
470  // disable Eject Request Waiter if any
471  UDFReleaseResource( &(Vcb->VCBResource) );
472  VcbAcquired = FALSE;
473 
475 
476  VcbDeleted = !UDFCheckForDismount( PtrIrpContext, Vcb, FALSE );
477 
478 try_exit: NOTHING;
479 
480  } _SEH2_FINALLY {
481  // Release the Vcb if it could still remain.
482  if (!VcbDeleted && VcbAcquired) {
483  UDFReleaseResource(&(Vcb->VCBResource));
484  }
485  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
486 
487  if(Buf)
488  MyFreePool__(Buf);
489 
490  if (!_SEH2_AbnormalTermination()) {
491  Irp->IoStatus.Status = RC;
492  // Free up the Irp Context
493  UDFReleaseIrpContext(PtrIrpContext);
494  // complete the IRP
496  }
497  } _SEH2_END;
498 
499  return RC;
500 }
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
_In_ PIRP Irp
Definition: csq.h:116
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
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
struct _PREVENT_MEDIA_REMOVAL_USER_IN * PPREVENT_MEDIA_REMOVAL_USER_IN
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
NTSTATUS NTAPI UDFPnpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
Definition: pnp.cpp:731
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define VPB_LOCKED
Definition: iotypes.h:1765
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define IoCompleteRequest
Definition: irp.c:1240
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2189
#define Vcb
Definition: cdprocs.h:1425
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define NOTHING
Definition: env_spec_w32.h:461
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
unsigned int ULONG
Definition: retypes.h:1
OSSTATUS UDFDoDismountSequence(IN PVCB Vcb, IN PPREVENT_MEDIA_REMOVAL_USER_IN Buf, IN BOOLEAN Eject)
Definition: phys_eject.cpp:704
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460

Referenced by UDFCommonPnp().

◆ UDFPnpSurpriseRemove()

NTSTATUS UDFPnpSurpriseRemove ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVCB  Vcb 
)

Definition at line 504 of file pnp.cpp.

537 {
538  NTSTATUS RC;
539  KEVENT Event;
540  BOOLEAN VcbDeleted;
541  BOOLEAN VcbAcquired;
543 
544  // SURPRISE - a device was physically yanked away without
545  // any warning. This means external forces.
546 
547  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
548 
549  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
550  UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
551 #ifdef UDF_DELAYED_CLOSE
553 #endif //UDF_DELAYED_CLOSE
554 
555  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
556  VcbAcquired = TRUE;
557 
558  // We need to pass this down before starting the dismount, which
559  // could disconnect us immediately from the stack.
560 
561  // Get the next stack location, and copy over the stack location
563 
564  // Set up the completion routine
568  &Event,
569  TRUE,
570  TRUE,
571  TRUE );
572 
573  // Send the request and wait.
574  RC = IoCallDriver(Vcb->TargetDeviceObject, Irp);
575 
576  if (RC == STATUS_PENDING) {
577 
579  Executive,
580  KernelMode,
581  FALSE,
582  NULL );
583 
584  RC = Irp->IoStatus.Status;
585  }
586 
587  _SEH2_TRY {
588  // Knock as many files down for this volume as we can.
589  Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
591  if(!Buf) {
592  VcbAcquired = FALSE;
593  VcbDeleted = FALSE;
595  }
596 
598  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
599  Vcb->WriteSecurity = FALSE;
600 
601  UDFReleaseResource(&(Vcb->VCBResource));
602  VcbAcquired = FALSE;
603 
605 
606  // Now make our dismount happen. This may not vaporize the
607  // Vcb, of course, since there could be any number of handles
608  // outstanding since this is an out of band notification.
609  VcbDeleted = !UDFCheckForDismount( PtrIrpContext, Vcb, FALSE );
610 
611 try_exit: NOTHING;
612 
613  } _SEH2_FINALLY {
614 
615  // Release the Vcb if it could still remain.
616  if (!VcbDeleted && VcbAcquired) {
617  UDFReleaseResource(&(Vcb->VCBResource));
618  }
619  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
620 
621  if(Buf)
622  MyFreePool__(Buf);
623 
624  if (!_SEH2_AbnormalTermination()) {
625  Irp->IoStatus.Status = RC;
626  // Free up the Irp Context
627  UDFReleaseIrpContext(PtrIrpContext);
628  // complete the IRP
630  }
631  } _SEH2_END;
632 
633  return RC;
634 }
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
_In_ PIRP Irp
Definition: csq.h:116
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
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
struct _PREVENT_MEDIA_REMOVAL_USER_IN * PPREVENT_MEDIA_REMOVAL_USER_IN
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
NTSTATUS NTAPI UDFPnpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
Definition: pnp.cpp:731
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define IoCompleteRequest
Definition: irp.c:1240
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2189
#define Vcb
Definition: cdprocs.h:1425
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define NOTHING
Definition: env_spec_w32.h:461
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
OSSTATUS UDFDoDismountSequence(IN PVCB Vcb, IN PPREVENT_MEDIA_REMOVAL_USER_IN Buf, IN BOOLEAN Eject)
Definition: phys_eject.cpp:704

Referenced by UDFCommonPnp().