ReactOS  0.4.13-dev-544-gede3fdd
pnp.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1997-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  Pnp.c
8 
9 Abstract:
10 
11  This module implements the Plug and Play routines for CDFS called by
12  the dispatch driver.
13 
14 
15 --*/
16 
17 #include "cdprocs.h"
18 
19 //
20 // The Bug check file id for this module
21 //
22 
23 #define BugCheckFileId (CDFS_BUG_CHECK_PNP)
24 
25 _Requires_lock_held_(_Global_critical_region_)
28 CdPnpQueryRemove (
29  _Inout_ PIRP_CONTEXT IrpContext,
32  );
33 
34 _Requires_lock_held_(_Global_critical_region_)
37 CdPnpRemove (
38  _Inout_ PIRP_CONTEXT IrpContext,
41  );
42 
43 _Requires_lock_held_(_Global_critical_region_)
46 CdPnpSurpriseRemove (
47  _Inout_ PIRP_CONTEXT IrpContext,
50  );
51 
52 _Requires_lock_held_(_Global_critical_region_)
55 CdPnpCancelRemove (
56  _Inout_ PIRP_CONTEXT IrpContext,
59  );
60 
61 // Tell prefast this is a completion routine.
62 IO_COMPLETION_ROUTINE CdPnpCompletionRoutine;
63 
65 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
68  _In_ PIRP Irp,
69  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
70  );
71 
72 #ifdef ALLOC_PRAGMA
73 #pragma alloc_text(PAGE, CdCommonPnp)
74 #pragma alloc_text(PAGE, CdPnpCancelRemove)
75 #pragma alloc_text(PAGE, CdPnpQueryRemove)
76 #pragma alloc_text(PAGE, CdPnpRemove)
77 #pragma alloc_text(PAGE, CdPnpSurpriseRemove)
78 #endif
79 
80 _Requires_lock_held_(_Global_critical_region_)
82 CdCommonPnp (
83  _Inout_ PIRP_CONTEXT IrpContext,
85  )
86 
87 /*++
88 
89 Routine Description:
90 
91  This is the common routine for doing PnP operations called
92  by both the fsd and fsp threads
93 
94 Arguments:
95 
96  Irp - Supplies the Irp to process
97 
98 Return Value:
99 
100  NTSTATUS - The return status for the operation
101 
102 --*/
103 
104 {
106  BOOLEAN PassThrough = FALSE;
107 
109 
110  PVOLUME_DEVICE_OBJECT OurDeviceObject;
111  PVCB Vcb;
112 
113  PAGED_CODE();
114 
115  // Global lock object is acquired based on internal book-keeping
117 
118  //
119  // Get the current Irp stack location.
120  //
121 
123 
124  //
125  // Find our Vcb. This is tricky since we have no file object in the Irp.
126  //
127 
128  OurDeviceObject = (PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject;
129 
130  //
131  // IO holds a handle reference on our VDO and holds the device lock, which
132  // syncs us against mounts/verifies. However we hold no reference on the
133  // volume, which may already have been torn down (and the Vpb freed), for
134  // example by a force dismount. Check for this condition. We must hold this
135  // lock until the pnp worker functions take additional locks/refs on the Vcb.
136  //
137 
138  CdAcquireCdData( IrpContext);
139 
140  //
141  // Make sure this device object really is big enough to be a volume device
142  // object. If it isn't, we need to get out before we try to reference some
143  // field that takes us past the end of an ordinary device object.
144  //
145 
146 #ifdef _MSC_VER
147 #pragma prefast(suppress: 28175, "this is a filesystem driver, touching the size member is allowed")
148 #endif
149  if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) ||
150  NodeType( &OurDeviceObject->Vcb ) != CDFS_NTC_VCB) {
151 
152  //
153  // We were called with something we don't understand.
154  //
155 
157  CdReleaseCdData( IrpContext);
158  CdCompleteRequest( IrpContext, Irp, Status );
159  return Status;
160  }
161 
162  //
163  // Force all PnP operations to be synchronous.
164  //
165 
166  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
167 
168  Vcb = &OurDeviceObject->Vcb;
169 
170  //
171  // Check that the Vcb hasn't already been deleted. If so, just pass the
172  // request through to the driver below, we don't need to do anything.
173  //
174 
175  if (NULL == Vcb->Vpb) {
176 
177  PassThrough = TRUE;
178  }
179  else {
180 
181  //
182  // Case on the minor code.
183  //
184 
185  switch ( IrpSp->MinorFunction ) {
186 
188 
189  Status = CdPnpQueryRemove( IrpContext, Irp, Vcb );
190  break;
191 
193 
194  Status = CdPnpSurpriseRemove( IrpContext, Irp, Vcb );
195  break;
196 
198 
199  Status = CdPnpRemove( IrpContext, Irp, Vcb );
200  break;
201 
203 
204  Status = CdPnpCancelRemove( IrpContext, Irp, Vcb );
205  break;
206 
207  default:
208 
209  PassThrough = TRUE;
210  break;
211  }
212  }
213 
214  if (PassThrough) {
215 
216  CdReleaseCdData( IrpContext);
217 
218  //
219  // Just pass the IRP on. As we do not need to be in the
220  // way on return, ellide ourselves out of the stack.
221  //
222 
224 
225  Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
226 
227  //
228  // Cleanup our Irp Context. The driver has completed the Irp.
229  //
230 
231  CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
232  }
233 
234  return Status;
235 }
236 
237 _Requires_lock_held_(_Global_critical_region_)
239 NTSTATUS
240 CdPnpQueryRemove (
241  _Inout_ PIRP_CONTEXT IrpContext,
242  _Inout_ PIRP Irp,
244  )
245 
246 /*++
247 
248 Routine Description:
249 
250  This routine handles the PnP query remove operation. The filesystem
251  is responsible for answering whether there are any reasons it sees
252  that the volume can not go away (and the device removed). Initiation
253  of the dismount begins when we answer yes to this question.
254 
255  Query will be followed by a Cancel or Remove.
256 
257 Arguments:
258 
259  Irp - Supplies the Irp to process
260 
261  Vcb - Supplies the volume being queried.
262 
263 Return Value:
264 
265  NTSTATUS - The return status for the operation
266 
267 --*/
268 
269 {
271  KEVENT Event;
272  BOOLEAN VcbPresent = TRUE;
273 
274  PAGED_CODE();
275 
277 
278  //
279  // Having said yes to a QUERY, any communication with the
280  // underlying storage stack is undefined (and may block)
281  // until the bounding CANCEL or REMOVE is sent.
282  //
283  // Acquire the global resource so that we can try to vaporize the volume,
284  // and the vcb resource itself.
285  //
286 
287  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
288 
289  //
290  // Drop a reference on the Vcb to keep it around after we drop the locks.
291  //
292 
293  CdLockVcb( IrpContext, Vcb);
294  Vcb->VcbReference += 1;
295  CdUnlockVcb( IrpContext, Vcb);
296 
297  CdReleaseCdData( IrpContext);
298 
299  Status = CdLockVolumeInternal( IrpContext, Vcb, NULL );
300 
301  //
302  // Reacquire the global lock, which means dropping the Vcb resource.
303  //
304 
305  CdReleaseVcb( IrpContext, Vcb );
306 
307  CdAcquireCdData( IrpContext );
308  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
309 
310  //
311  // Remove our extra reference.
312  //
313 
314  CdLockVcb( IrpContext, Vcb);
315  Vcb->VcbReference -= 1;
316  CdUnlockVcb( IrpContext, Vcb);
317 
318  if (NT_SUCCESS( Status )) {
319 
320  //
321  // We need to pass this down before starting the dismount, which
322  // could disconnect us immediately from the stack.
323  //
324 
325  //
326  // Get the next stack location, and copy over the stack location
327  //
328 
330 
331  //
332  // Set up the completion routine
333  //
334 
338  &Event,
339  TRUE,
340  TRUE,
341  TRUE );
342 
343  //
344  // Send the request and wait.
345  //
346 
347  Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
348 
349  if (Status == STATUS_PENDING) {
350 
352  Executive,
353  KernelMode,
354  FALSE,
355  NULL );
356 
357  Status = Irp->IoStatus.Status;
358  }
359 
360  //
361  // Now if no one below us failed already, initiate the dismount
362  // on this volume, make it go away. PnP needs to see our internal
363  // streams close and drop their references to the target device.
364  //
365  // Since we were able to lock the volume, we are guaranteed to
366  // move this volume into dismount state and disconnect it from
367  // the underlying storage stack. The force on our part is actually
368  // unnecesary, though complete.
369  //
370  // What is not strictly guaranteed, though, is that the closes
371  // for the metadata streams take effect synchronously underneath
372  // of this call. This would leave references on the target device
373  // even though we are disconnected!
374  //
375 
376  if (NT_SUCCESS( Status )) {
377 
378  VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE );
379 
380  NT_ASSERT( !VcbPresent || Vcb->VcbCondition == VcbDismountInProgress );
381  }
382 
383  //
384  // Note: Normally everything will complete and the internal streams will
385  // vaporise. However there is some code in the system which drops additional
386  // references on fileobjects, including our internal stream file objects,
387  // for (WMI) tracing purposes. If that happens to run concurrently with our
388  // teardown, our internal streams will not vaporise until those references
389  // are removed. So it's possible that the volume still remains at this
390  // point. The pnp query remove will fail due to our references on the device.
391  // To be cleaner we will return an error here. We could pend the pnp
392  // IRP until the volume goes away, but since we don't know when that will
393  // be, and this is a very rare case, we'll just fail the query.
394  //
395  // The reason this is the case is that handles/fileobjects place a reference
396  // on the device objects they overly. In the filesystem case, these references
397  // are on our target devices. PnP correcly thinks that if references remain
398  // on the device objects in the stack that someone has a handle, and that this
399  // counts as a reason to not succeed the query - even though every interrogated
400  // driver thinks that it is OK.
401  //
402 
403  if (NT_SUCCESS( Status) && VcbPresent && (Vcb->VcbReference != 0)) {
404 
406  }
407  }
408 
409  //
410  // Release the Vcb if it could still remain.
411  //
412 
413  if (VcbPresent) {
414 
415  CdReleaseVcb( IrpContext, Vcb );
416  }
417  else {
418  _Analysis_assume_lock_not_held_(Vcb->VcbResource);
419  }
420 
421  CdReleaseCdData( IrpContext );
422 
423  //
424  // Cleanup our IrpContext and complete the IRP if neccesary.
425  //
426 
427  CdCompleteRequest( IrpContext, Irp, Status );
428 
429  return Status;
430 }
431 
432 _Requires_lock_held_(_Global_critical_region_)
434 NTSTATUS
435 CdPnpRemove (
436  _Inout_ PIRP_CONTEXT IrpContext,
437  _Inout_ PIRP Irp,
439  )
440 
441 /*++
442 
443 Routine Description:
444 
445  This routine handles the PnP remove operation. This is our notification
446  that the underlying storage device for the volume we have is gone, and
447  an excellent indication that the volume will never reappear. The filesystem
448  is responsible for initiation or completion the dismount.
449 
450 Arguments:
451 
452  Irp - Supplies the Irp to process
453 
454  Vcb - Supplies the volume being removed.
455 
456 Return Value:
457 
458  NTSTATUS - The return status for the operation
459 
460 --*/
461 
462 {
464  KEVENT Event;
465  BOOLEAN VcbPresent = TRUE;
466 
467  PAGED_CODE();
468 
470 
471  //
472  // REMOVE - a storage device is now gone. We either got
473  // QUERY'd and said yes OR got a SURPRISE OR a storage
474  // stack failed to spin back up from a sleep/stop state
475  // (the only case in which this will be the first warning).
476  //
477  // Note that it is entirely unlikely that we will be around
478  // for a REMOVE in the first two cases, as we try to intiate
479  // dismount.
480  //
481 
482  //
483  // Acquire the global resource so that we can try to vaporize
484  // the volume, and the vcb resource itself.
485  //
486 
487  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
488 
489  //
490  // The device will be going away. Remove our lock and find
491  // out if we ever had one in the first place.
492  //
493 
494  Status = CdUnlockVolumeInternal( IrpContext, Vcb, NULL );
495 
496  //
497  // If the volume had not been locked, we must invalidate the
498  // volume to ensure it goes away properly. The remove will
499  // succeed.
500  //
501 
502  if (!NT_SUCCESS( Status )) {
503 
504  CdLockVcb( IrpContext, Vcb );
505 
506  if (Vcb->VcbCondition != VcbDismountInProgress) {
507 
509  }
510 
511  CdUnlockVcb( IrpContext, Vcb );
512 
514  }
515 
516  //
517  // We need to pass this down before starting the dismount, which
518  // could disconnect us immediately from the stack.
519  //
520 
521  //
522  // Get the next stack location, and copy over the stack location
523  //
524 
526 
527  //
528  // Set up the completion routine
529  //
530 
534  &Event,
535  TRUE,
536  TRUE,
537  TRUE );
538 
539  //
540  // Send the request and wait.
541  //
542 
543  Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
544 
545  if (Status == STATUS_PENDING) {
546 
548  Executive,
549  KernelMode,
550  FALSE,
551  NULL );
552 
553  Status = Irp->IoStatus.Status;
554  }
555 
556  //
557  // Now make our dismount happen. This may not vaporize the
558  // Vcb, of course, since there could be any number of handles
559  // outstanding if we were not preceeded by a QUERY.
560  //
561  // PnP will take care of disconnecting this stack if we
562  // couldn't get off of it immediately.
563  //
564 
565 
566  VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE );
567 
568  //
569  // Release the Vcb if it could still remain.
570  //
571 
572  if (VcbPresent) {
573 
574  CdReleaseVcb( IrpContext, Vcb );
575  }
576  else {
577  _Analysis_assume_lock_not_held_(Vcb->VcbResource);
578  }
579 
580  CdReleaseCdData( IrpContext );
581 
582  //
583  // Cleanup our IrpContext and complete the IRP.
584  //
585 
586  CdCompleteRequest( IrpContext, Irp, Status );
587 
588  return Status;
589 }
590 
591 _Requires_lock_held_(_Global_critical_region_)
593 NTSTATUS
594 CdPnpSurpriseRemove (
595  _Inout_ PIRP_CONTEXT IrpContext,
596  _Inout_ PIRP Irp,
598  )
599 
600 /*++
601 
602 Routine Description:
603 
604  This routine handles the PnP surprise remove operation. This is another
605  type of notification that the underlying storage device for the volume we
606  have is gone, and is excellent indication that the volume will never reappear.
607  The filesystem is responsible for initiation or completion the dismount.
608 
609  For the most part, only "real" drivers care about the distinction of a
610  surprise remove, which is a result of our noticing that a user (usually)
611  physically reached into the machine and pulled something out.
612 
613  Surprise will be followed by a Remove when all references have been shut down.
614 
615 Arguments:
616 
617  Irp - Supplies the Irp to process
618 
619  Vcb - Supplies the volume being removed.
620 
621 Return Value:
622 
623  NTSTATUS - The return status for the operation
624 
625 --*/
626 
627 {
629  KEVENT Event;
630  BOOLEAN VcbPresent = TRUE;
631 
632  PAGED_CODE();
633 
635 
636  //
637  // SURPRISE - a device was physically yanked away without
638  // any warning. This means external forces.
639  //
640 
641  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
642 
643  //
644  // Invalidate the volume right now.
645  //
646  // The intent here is to make every subsequent operation
647  // on the volume fail and grease the rails toward dismount.
648  // By definition there is no going back from a SURPRISE.
649  //
650 
651  CdLockVcb( IrpContext, Vcb );
652 
653  if (Vcb->VcbCondition != VcbDismountInProgress) {
654 
656  }
657 
658  CdUnlockVcb( IrpContext, Vcb );
659 
660  //
661  // We need to pass this down before starting the dismount, which
662  // could disconnect us immediately from the stack.
663  //
664 
665  //
666  // Get the next stack location, and copy over the stack location
667  //
668 
670 
671  //
672  // Set up the completion routine
673  //
674 
678  &Event,
679  TRUE,
680  TRUE,
681  TRUE );
682 
683  //
684  // Send the request and wait.
685  //
686 
687  Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
688 
689  if (Status == STATUS_PENDING) {
690 
692  Executive,
693  KernelMode,
694  FALSE,
695  NULL );
696 
697  Status = Irp->IoStatus.Status;
698  }
699 
700  //
701  // Now make our dismount happen. This may not vaporize the
702  // Vcb, of course, since there could be any number of handles
703  // outstanding since this is an out of band notification.
704  //
705 
706 
707  VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE );
708 
709  //
710  // Release the Vcb if it could still remain.
711  //
712 
713  if (VcbPresent) {
714 
715  CdReleaseVcb( IrpContext, Vcb );
716  }
717  else {
718  _Analysis_assume_lock_not_held_(Vcb->VcbResource);
719  }
720 
721  CdReleaseCdData( IrpContext );
722 
723  //
724  // Cleanup our IrpContext and complete the IRP.
725  //
726 
727  CdCompleteRequest( IrpContext, Irp, Status );
728 
729  return Status;
730 }
731 
732 _Requires_lock_held_(_Global_critical_region_)
734 NTSTATUS
735 CdPnpCancelRemove (
736  _Inout_ PIRP_CONTEXT IrpContext,
737  _Inout_ PIRP Irp,
739  )
740 
741 /*++
742 
743 Routine Description:
744 
745  This routine handles the PnP cancel remove operation. This is our
746  notification that a previously proposed remove (query) was eventually
747  vetoed by a component. The filesystem is responsible for cleaning up
748  and getting ready for more IO.
749 
750 Arguments:
751 
752  Irp - Supplies the Irp to process
753 
754  Vcb - Supplies the volume being removed.
755 
756 Return Value:
757 
758  NTSTATUS - The return status for the operation
759 
760 --*/
761 
762 {
764 
765  PAGED_CODE();
766 
768 
769  //
770  // CANCEL - a previous QUERY has been rescinded as a result
771  // of someone vetoing. Since PnP cannot figure out who may
772  // have gotten the QUERY (think about it: stacked drivers),
773  // we must expect to deal with getting a CANCEL without having
774  // seen the QUERY.
775  //
776  // For CDFS, this is quite easy. In fact, we can't get a
777  // CANCEL if the underlying drivers succeeded the QUERY since
778  // we disconnect the Vpb on our dismount initiation. This is
779  // actually pretty important because if PnP could get to us
780  // after the disconnect we'd be thoroughly unsynchronized
781  // with respect to the Vcb getting torn apart - merely referencing
782  // the volume device object is insufficient to keep us intact.
783  //
784 
785  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
786  CdReleaseCdData( IrpContext);
787 
788  //
789  // Unlock the volume. This is benign if we never had seen
790  // a QUERY.
791  //
792 
793  (VOID) CdUnlockVolumeInternal( IrpContext, Vcb, NULL );
794 
795  CdReleaseVcb( IrpContext, Vcb );
796 
797  //
798  // Send the request. The underlying driver will complete the
799  // IRP. Since we don't need to be in the way, simply ellide
800  // ourselves out of the IRP stack.
801  //
802 
804 
805  Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
806 
807  CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
808 
809  return Status;
810 }
811 
812 
813 //
814 // Local support routine
815 //
816 
817 NTSTATUS
818 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
821  _In_ PIRP Irp,
822  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
823  )
824 {
825  PKEVENT Event = (PKEVENT) Contxt;
826  _Analysis_assume_(Contxt != NULL);
827 
828  KeSetEvent( Event, 0, FALSE );
829 
831 
834  UNREFERENCED_PARAMETER( Contxt );
835 }
836 
837 
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define ASSERT_EXCLUSIVE_CDDATA
Definition: cddata.h:258
#define _Analysis_suppress_lock_checking_(lock)
Definition: no_sal2.h:685
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
struct _KEVENT * PKEVENT
#define IRP_MN_REMOVE_DEVICE
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
Definition: cdstruc.h:504
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:775
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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
#define PAGED_CODE()
Definition: video.h:57
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IRP_MN_QUERY_REMOVE_DEVICE
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
ERESOURCE DataResource
Definition: cdstruc.h:408
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NodeType
Definition: Node.h:5
DEVICE_OBJECT DeviceObject
Definition: cdstruc.h:735
#define CdAcquireVcbExclusive(IC, V, I)
Definition: cdprocs.h:984
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
CD_DATA CdData
Definition: cddata.c:42
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:990
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define CdUnlockVcb(IC, V)
Definition: cdprocs.h:1033
#define Vcb
Definition: cdprocs.h:1425
#define CDFS_NTC_VCB
Definition: nodetype.h:28
NTSTATUS NTAPI CdPnpCompletionRoutine(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
Definition: pnp.c:819
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2866
#define _Inout_
Definition: no_sal2.h:244
_Requires_lock_held_(_Requires_lock_held_() _Releases_nonreentrant_lock_(CdData.DataResource) NTSTATUSCdPnpRemove(_Inout_ PIRP_CONTEXT IrpContext _Global_critical_region_)
Definition: pnp.c:25
#define CdLockVcb(IC, V)
Definition: cdprocs.h:1028
#define VOID
Definition: acefi.h:82
#define CdAcquireCdData(IC)
Definition: cdprocs.h:978
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define CdReleaseCdData(IC)
Definition: cdprocs.h:981
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define _In_reads_opt_(size)
Definition: no_sal2.h:231
#define _Analysis_assume_lock_not_held_(lock)
Definition: no_sal2.h:683
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define _Releases_nonreentrant_lock_(lock)
Definition: no_sal2.h:700
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define CdUpdateVcbCondition(V, C)
Definition: cdprocs.h:1459
NTSTATUS CdUnlockVolumeInternal(_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb, _In_opt_ PFILE_OBJECT FileObject)
Definition: fsctrl.c:288
#define NT_ASSERT
Definition: rtlfuncs.h:3312