2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS ***************************************************************/
17 extern PRFSD_GLOBAL RfsdGlobal
;
19 /* DEFINITIONS *************************************************************/
21 #define DBG_PNP DBG_USER
24 IO_COMPLETION_ROUTINE RfsdPnpCompletionRoutine
;
28 RfsdPnpCompletionRoutine (
29 IN PDEVICE_OBJECT DeviceObject
,
34 #pragma alloc_text(PAGE, RfsdPnp)
35 #pragma alloc_text(PAGE, RfsdPnpQueryRemove)
36 #pragma alloc_text(PAGE, RfsdPnpRemove)
37 #pragma alloc_text(PAGE, RfsdPnpCancelRemove)
38 #pragma alloc_text(PAGE, RfsdPnpSurpriseRemove)
41 /* FUNCTIONS *************************************************************/
43 #if (_WIN32_WINNT >= 0x0500)
46 RfsdPnpCompletionRoutine (
47 IN PDEVICE_OBJECT DeviceObject
,
52 PKEVENT Event
= (PKEVENT
) Contxt
;
54 KeSetEvent( Event
, 0, FALSE
);
56 return STATUS_MORE_PROCESSING_REQUIRED
;
58 UNREFERENCED_PARAMETER( DeviceObject
);
59 UNREFERENCED_PARAMETER( Contxt
);
62 __drv_mustHoldCriticalRegion
64 RfsdPnp (IN PRFSD_IRP_CONTEXT IrpContext
)
66 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
68 PIO_STACK_LOCATION IrpSp
;
70 PDEVICE_OBJECT DeviceObject
;
78 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
79 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
81 DeviceObject
= IrpContext
->DeviceObject
;
83 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
87 if ( !((Vcb
->Identifier
.Type
== RFSDVCB
) &&
88 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)))) {
89 _SEH2_LEAVE
; // Status = STATUS_INVALID_PARAMETER
92 Irp
= IrpContext
->Irp
;
93 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
95 SetFlag(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
);
97 switch ( IrpSp
->MinorFunction
) {
99 case IRP_MN_QUERY_REMOVE_DEVICE
:
101 RfsdPrint((DBG_PNP
, "RfsdPnp: RfsdPnpQueryRemove...\n"));
102 Status
= RfsdPnpQueryRemove(IrpContext
, Vcb
);
106 case IRP_MN_REMOVE_DEVICE
:
108 RfsdPrint((DBG_PNP
, "RfsdPnp: RfsdPnpRemove...\n"));
109 Status
= RfsdPnpRemove(IrpContext
, Vcb
);
112 case IRP_MN_CANCEL_REMOVE_DEVICE
:
114 RfsdPrint((DBG_PNP
, "RfsdPnp: RfsdPnpCancelRemove...\n"));
115 Status
= RfsdPnpCancelRemove(IrpContext
, Vcb
);
118 case IRP_MN_SURPRISE_REMOVAL
:
120 RfsdPrint((DBG_PNP
, "RfsdPnp: RfsdPnpSupriseRemove...\n"));
121 Status
= RfsdPnpSurpriseRemove(IrpContext
, Vcb
);
130 if (!IrpContext
->ExceptionInProgress
) {
131 Irp
= IrpContext
->Irp
;
136 // Here we need pass the IRP to the disk driver.
139 IoSkipCurrentIrpStackLocation( Irp
);
141 Status
= IoCallDriver(Vcb
->TargetDeviceObject
, Irp
);
143 IrpContext
->Irp
= NULL
;
146 RfsdCompleteIrpContext(IrpContext
, Status
);
153 __drv_mustHoldCriticalRegion
156 PRFSD_IRP_CONTEXT IrpContext
,
163 BOOLEAN bDeleted
= FALSE
;
164 BOOLEAN VcbAcquired
= FALSE
;
170 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove by RfsdPnp ...\n"));
172 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove: RfsdFlushVolume ...\n"));
174 #if (_WIN32_WINNT >= 0x0500)
175 CcWaitForCurrentLazyWriterActivity();
178 ExAcquireResourceExclusiveLite(
179 &Vcb
->MainResource
, TRUE
);
182 RfsdFlushFiles(Vcb
, FALSE
);
184 RfsdFlushVolume(Vcb
, FALSE
);
186 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove: RfsdLockVcb: Vcb=%xh FileObject=%xh ...\n",
187 Vcb
, IrpContext
->FileObject
));
188 Status
= RfsdLockVcb(Vcb
, IrpContext
->FileObject
);
190 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove: RfsdPurgeVolume ...\n"));
191 RfsdPurgeVolume(Vcb
, TRUE
);
193 if (!NT_SUCCESS(Status
)) {
197 ExReleaseResourceForThreadLite(
199 ExGetCurrentResourceThread() );
202 IoCopyCurrentIrpStackLocationToNext(IrpContext
->Irp
);
204 KeInitializeEvent( &Event
, NotificationEvent
, FALSE
);
205 IoSetCompletionRoutine( IrpContext
->Irp
,
206 RfsdPnpCompletionRoutine
,
212 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove: Call lower level driver...\n"));
213 Status
= IoCallDriver( Vcb
->TargetDeviceObject
,
216 if (Status
== STATUS_PENDING
) {
218 KeWaitForSingleObject( &Event
,
224 Status
= IrpContext
->Irp
->IoStatus
.Status
;
227 if (NT_SUCCESS(Status
)) {
228 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove: RfsdCheckDismount ...\n"));
229 bDeleted
= RfsdCheckDismount(IrpContext
, Vcb
, TRUE
);
230 RfsdPrint((DBG_PNP
, "RfsdPnpQueryRemove: RfsdFlushVolume bDelted=%xh ...\n", bDeleted
));
233 ASSERT( !(NT_SUCCESS(Status
) && !bDeleted
));
238 ExReleaseResourceForThreadLite(
240 ExGetCurrentResourceThread() );
244 IrpContext
->Irp
, FALSE
, (CCHAR
)(NT_SUCCESS(Status
)?
245 IO_DISK_INCREMENT
: IO_NO_INCREMENT
) );
247 IrpContext
->Irp
= NULL
;
253 __drv_mustHoldCriticalRegion
256 PRFSD_IRP_CONTEXT IrpContext
,
267 RfsdPrint((DBG_PNP
, "RfsdPnpRemove by RfsdPnp ...\n"));
268 #if (_WIN32_WINNT >= 0x0500)
269 CcWaitForCurrentLazyWriterActivity();
271 ExAcquireResourceExclusiveLite(
272 &Vcb
->MainResource
, TRUE
);
274 Status
= RfsdLockVcb(Vcb
, IrpContext
->FileObject
);
276 ExReleaseResourceForThreadLite(
278 ExGetCurrentResourceThread());
281 // Setup the Irp. We'll send it to the lower disk driver.
284 IoCopyCurrentIrpStackLocationToNext(IrpContext
->Irp
);
286 KeInitializeEvent( &Event
, NotificationEvent
, FALSE
);
287 IoSetCompletionRoutine( IrpContext
->Irp
,
288 RfsdPnpCompletionRoutine
,
294 Status
= IoCallDriver( Vcb
->TargetDeviceObject
,
297 if (Status
== STATUS_PENDING
) {
299 KeWaitForSingleObject( &Event
,
305 Status
= IrpContext
->Irp
->IoStatus
.Status
;
308 ExAcquireResourceExclusiveLite(
309 &Vcb
->MainResource
, TRUE
);
311 RfsdPurgeVolume(Vcb
, FALSE
);
313 ExReleaseResourceForThreadLite(
315 ExGetCurrentResourceThread() );
317 bDeleted
= RfsdCheckDismount(IrpContext
, Vcb
, TRUE
);
321 IrpContext
->Irp
, FALSE
, (CCHAR
)(NT_SUCCESS(Status
)?
322 IO_DISK_INCREMENT
: IO_NO_INCREMENT
) );
324 IrpContext
->Irp
= NULL
;
330 __drv_mustHoldCriticalRegion
332 RfsdPnpSurpriseRemove (
333 PRFSD_IRP_CONTEXT IrpContext
,
344 RfsdPrint((DBG_PNP
, "RfsdPnpSupriseRemove by RfsdPnp ...\n"));
345 #if (_WIN32_WINNT >= 0x0500)
346 CcWaitForCurrentLazyWriterActivity();
348 ExAcquireResourceExclusiveLite(
349 &Vcb
->MainResource
, TRUE
);
351 Status
= RfsdLockVcb(Vcb
, IrpContext
->FileObject
);
353 ExReleaseResourceForThreadLite(
355 ExGetCurrentResourceThread());
358 // Setup the Irp. We'll send it to the lower disk driver.
361 IoCopyCurrentIrpStackLocationToNext(IrpContext
->Irp
);
363 KeInitializeEvent( &Event
, NotificationEvent
, FALSE
);
364 IoSetCompletionRoutine( IrpContext
->Irp
,
365 RfsdPnpCompletionRoutine
,
371 Status
= IoCallDriver( Vcb
->TargetDeviceObject
,
374 if (Status
== STATUS_PENDING
) {
376 KeWaitForSingleObject( &Event
,
382 Status
= IrpContext
->Irp
->IoStatus
.Status
;
385 ExAcquireResourceExclusiveLite(
386 &Vcb
->MainResource
, TRUE
);
388 RfsdPurgeVolume(Vcb
, FALSE
);
390 ExReleaseResourceForThreadLite(
392 ExGetCurrentResourceThread() );
394 bDeleted
= RfsdCheckDismount(IrpContext
, Vcb
, TRUE
);
399 IrpContext
->Irp
, FALSE
, (CCHAR
)(NT_SUCCESS(Status
)?
400 IO_DISK_INCREMENT
: IO_NO_INCREMENT
) );
402 IrpContext
->Irp
= NULL
;
408 __drv_mustHoldCriticalRegion
410 RfsdPnpCancelRemove (
411 PRFSD_IRP_CONTEXT IrpContext
,
419 RfsdPrint((DBG_PNP
, "RfsdPnpCancelRemove by RfsdPnp ...\n"));
421 ExAcquireResourceExclusiveLite(
422 &Vcb
->MainResource
, TRUE
);
424 Status
= RfsdUnlockVcb(Vcb
, IrpContext
->FileObject
);
426 ExReleaseResourceForThreadLite(
428 ExGetCurrentResourceThread());
430 IoSkipCurrentIrpStackLocation(IrpContext
->Irp
);
432 Status
= IoCallDriver(Vcb
->TargetDeviceObject
, IrpContext
->Irp
);
434 IrpContext
->Irp
= NULL
;
439 #endif // (_WIN32_WINNT >= 0x0500)