ReactOS  0.4.15-dev-499-g1f31905
pnp.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYRIGHT.TXT
3  * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4  * FILE: pnp.c
5  * PROGRAMMER: Matt Wu <mattwu@163.com>
6  * HOMEPAGE: http://www.ext2fsd.com
7  * UPDATE HISTORY:
8  */
9 
10 #if (_WIN32_WINNT >= 0x0500)
11 
12 /* INCLUDES *****************************************************************/
13 
14 #include "ext2fs.h"
15 
16 /* GLOBALS ***************************************************************/
17 
19 
20 /* DEFINITIONS *************************************************************/
21 
23 Ext2PnpCompletionRoutine (
25  IN PIRP Irp,
26  IN PVOID Contxt );
27 
28 
29 #ifdef ALLOC_PRAGMA
30 #pragma alloc_text(PAGE, Ext2Pnp)
31 #pragma alloc_text(PAGE, Ext2PnpQueryRemove)
32 #pragma alloc_text(PAGE, Ext2PnpRemove)
33 #pragma alloc_text(PAGE, Ext2PnpCancelRemove)
34 #pragma alloc_text(PAGE, Ext2PnpSurpriseRemove)
35 #endif
36 
37 
38 /* FUNCTIONS *************************************************************/
39 
40 
42 Ext2PnpCompletionRoutine (
44  IN PIRP Irp,
45  IN PVOID Contxt
46 )
47 {
48  PKEVENT Event = (PKEVENT) Contxt;
49 
50  KeSetEvent( Event, 0, FALSE );
51 
53 
55  UNREFERENCED_PARAMETER( Contxt );
56 }
57 
58 
60 Ext2Pnp (IN PEXT2_IRP_CONTEXT IrpContext)
61 {
63 
64  PIRP Irp;
66  PEXT2_VCB Vcb = NULL;
68 
69  _SEH2_TRY {
70 
71  ASSERT(IrpContext);
72 
73  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
74  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
75 
76  DeviceObject = IrpContext->DeviceObject;
77 
79 
80  ASSERT(Vcb != NULL);
81 
82  if ( !((Vcb->Identifier.Type == EXT2VCB) &&
83  (Vcb->Identifier.Size == sizeof(EXT2_VCB)))) {
84  _SEH2_LEAVE; // Status = STATUS_INVALID_PARAMETER
85  }
86 
87  Irp = IrpContext->Irp;
89 
90  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
91 
92  switch ( IrpSp->MinorFunction ) {
93 
95 
96  DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpQueryRemove...\n"));
97  Status = Ext2PnpQueryRemove(IrpContext, Vcb);
98 
99  break;
100 
102 
103  DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpRemove...\n"));
104  Status = Ext2PnpRemove(IrpContext, Vcb);
105  break;
106 
108 
109  DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpCancelRemove...\n"));
110  Status = Ext2PnpCancelRemove(IrpContext, Vcb);
111  break;
112 
114 
115  DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpSupriseRemove...\n"));
116  Status = Ext2PnpSurpriseRemove(IrpContext, Vcb);
117  break;
118 
119  default:
120  break;
121  }
122 
123  } _SEH2_FINALLY {
124 
125  if (!IrpContext->ExceptionInProgress) {
126  Irp = IrpContext->Irp;
127 
128  if (Irp) {
129 
130  //
131  // Here we need pass the IRP to the disk driver.
132  //
133 
135 
136  Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
137 
138  IrpContext->Irp = NULL;
139  }
140 
141  Ext2CompleteIrpContext(IrpContext, Status);
142  }
143  } _SEH2_END;
144 
145  return Status;
146 }
147 
148 
149 NTSTATUS
151  PEXT2_IRP_CONTEXT IrpContext,
152  PEXT2_VCB Vcb
153 )
154 {
156  KEVENT Event;
157  BOOLEAN bDeleted = FALSE;
158  BOOLEAN VcbAcquired = FALSE;
159 
160  _SEH2_TRY {
161 
163 
164  VcbAcquired = ExAcquireResourceExclusiveLite(
165  &Vcb->MainResource, TRUE );
166 
167  Ext2FlushFiles(IrpContext, Vcb, FALSE);
168  Ext2FlushVolume(IrpContext, Vcb, FALSE);
169 
170  DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2LockVcb: Vcb=%xh FileObject=%xh ...\n",
171  Vcb, IrpContext->FileObject));
172  Status = Ext2LockVcb(Vcb, IrpContext->FileObject);
173 
174  if (VcbAcquired) {
175  ExReleaseResourceLite(&Vcb->MainResource);
176  VcbAcquired = FALSE;
177  }
178 
179  DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2PurgeVolume ...\n"));
181 
182  if (!NT_SUCCESS(Status)) {
183  _SEH2_LEAVE;
184  }
185 
187 
189  IoSetCompletionRoutine( IrpContext->Irp,
190  Ext2PnpCompletionRoutine,
191  &Event,
192  TRUE,
193  TRUE,
194  TRUE );
195 
196  DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Call lower level driver...\n"));
197  Status = IoCallDriver( Vcb->TargetDeviceObject,
198  IrpContext->Irp);
199 
200  if (Status == STATUS_PENDING) {
202  Executive,
203  KernelMode,
204  FALSE,
205  NULL );
206  Status = IrpContext->Irp->IoStatus.Status;
207  }
208 
209  if (NT_SUCCESS(Status)) {
210  ASSERT(!VcbAcquired);
211  DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2CheckDismount ...\n"));
212  bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE);
213  DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2FlushVolume bDelted=%xh ...\n", bDeleted));
214  }
215 
216  } _SEH2_FINALLY {
217 
218  if (VcbAcquired) {
219  ExReleaseResourceLite(&Vcb->MainResource);
220  }
221 
222  IrpContext->Irp->IoStatus.Status = Status;
224  IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
226 
227  IrpContext->Irp = NULL;
228  } _SEH2_END;
229 
230  return Status;
231 }
232 
233 NTSTATUS
235  PEXT2_IRP_CONTEXT IrpContext,
236  PEXT2_VCB Vcb )
237 {
239  KEVENT Event;
240  BOOLEAN bDeleted;
241 
242  _SEH2_TRY {
243 
244  DEBUG(DL_PNP, ("Ext2PnpRemove by Ext2Pnp ...\n"));
245 
248  &Vcb->MainResource, TRUE );
249  Status = Ext2LockVcb(Vcb, IrpContext->FileObject);
250  ExReleaseResourceLite(&Vcb->MainResource);
251 
252  //
253  // Setup the Irp. We'll send it to the lower disk driver.
254  //
255 
257 
259  IoSetCompletionRoutine( IrpContext->Irp,
260  Ext2PnpCompletionRoutine,
261  &Event,
262  TRUE,
263  TRUE,
264  TRUE );
265 
266  Status = IoCallDriver( Vcb->TargetDeviceObject,
267  IrpContext->Irp);
268 
269  if (Status == STATUS_PENDING) {
270 
272  Executive,
273  KernelMode,
274  FALSE,
275  NULL );
276 
277  Status = IrpContext->Irp->IoStatus.Status;
278  }
279 
280  /* purge volume cache */
282 
283  /* dismount volume */
284  bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE);
286 
287  } _SEH2_FINALLY {
288 
289  IrpContext->Irp->IoStatus.Status = Status;
291  IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
293 
294  IrpContext->Irp = NULL;
295  } _SEH2_END;
296 
297  return Status;
298 }
299 
300 
301 NTSTATUS
303  PEXT2_IRP_CONTEXT IrpContext,
304  PEXT2_VCB Vcb )
305 {
307  KEVENT Event;
308  BOOLEAN bDeleted;
309 
310  _SEH2_TRY {
311 
312  DEBUG(DL_PNP, ("Ext2PnpSupriseRemove by Ext2Pnp ...\n"));
313 
316  &Vcb->MainResource, TRUE );
317 
318  Status = Ext2LockVcb(Vcb, IrpContext->FileObject);
319 
320  ExReleaseResourceLite(&Vcb->MainResource);
321 
322  //
323  // Setup the Irp. We'll send it to the lower disk driver.
324  //
325 
327 
329  IoSetCompletionRoutine( IrpContext->Irp,
330  Ext2PnpCompletionRoutine,
331  &Event,
332  TRUE,
333  TRUE,
334  TRUE );
335 
336  Status = IoCallDriver( Vcb->TargetDeviceObject,
337  IrpContext->Irp);
338 
339  if (Status == STATUS_PENDING) {
340 
342  Executive,
343  KernelMode,
344  FALSE,
345  NULL );
346 
347  Status = IrpContext->Irp->IoStatus.Status;
348  }
349 
350  /* purge volume cache */
352 
353  /* dismount volume */
354  bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE);
356 
357  } _SEH2_FINALLY {
358 
359  IrpContext->Irp->IoStatus.Status = Status;
361  IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
363 
364  IrpContext->Irp = NULL;
365  } _SEH2_END;
366 
367  return Status;
368 }
369 
370 
371 NTSTATUS
373  PEXT2_IRP_CONTEXT IrpContext,
374  PEXT2_VCB Vcb
375 )
376 {
378 
379  DEBUG(DL_PNP, ("Ext2PnpCancelRemove by Ext2Pnp ...\n"));
380 
382  &Vcb->MainResource, TRUE );
383 
384  Status = Ext2UnlockVcb(Vcb, IrpContext->FileObject);
385 
386  ExReleaseResourceLite(&Vcb->MainResource);
387 
388  IoSkipCurrentIrpStackLocation(IrpContext->Irp);
389 
390  Status = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);
391 
392  IrpContext->Irp = NULL;
393 
394  return Status;
395 }
396 
397 #endif //(_WIN32_WINNT >= 0x0500)
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IN
Definition: typedefs.h:39
#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:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define VCB_DEVICE_REMOVED
Definition: ext2fs.h:791
LONG NTSTATUS
Definition: precomp.h:26
PIRP Irp
Definition: ext2fs.h:1041
NTSTATUS Ext2FlushVolume(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:39
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
IO_STATUS_BLOCK IoStatus
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
_SEH2_TRY
Definition: create.c:4226
NTSTATUS Ext2LockVcb(IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject)
Definition: fsctl.c:94
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
BOOLEAN Ext2CheckDismount(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bForce)
Definition: fsctl.c:2592
#define IO_DISK_INCREMENT
Definition: iotypes.h:570
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IRP_MN_QUERY_REMOVE_DEVICE
#define DL_PNP
Definition: ext2fs.h:1412
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:437
NTSTATUS Ext2PnpRemove(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS Ext2UnlockVcb(IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject)
Definition: fsctl.c:206
NTSTATUS NTAPI CcWaitForCurrentLazyWriterActivity(VOID)
Definition: lazyrite.c:30
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
char CCHAR
Definition: typedefs.h:51
#define Vcb
Definition: cdprocs.h:1415
NTSTATUS Ext2PnpCancelRemove(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost)
Definition: ext2fs.h:1438
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PFILE_OBJECT FileObject
Definition: ext2fs.h:1057
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
NTSTATUS Ext2PurgeVolume(IN PEXT2_VCB Vcb, IN BOOLEAN FlushBeforePurge)
Definition: fsctl.c:2704
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS Ext2FlushFiles(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:108
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define SetLongFlag(_F, _SF)
Definition: ext2fs.h:253
_SEH2_FINALLY
Definition: create.c:4371
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IO_NO_INCREMENT
Definition: iotypes.h:568
NTSTATUS Ext2PnpQueryRemove(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
struct _EXT2_VCB * PEXT2_VCB
#define DEBUG(args)
Definition: rdesktop.h:129
NTSTATUS Ext2Pnp(IN PEXT2_IRP_CONTEXT IrpContext)
#define _SEH2_LEAVE
Definition: filesup.c:20
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSTATUS Ext2PnpSurpriseRemove(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)