2 * FFS File System Driver for Windows
8 * Lee Jae-Hong, http://www.pyrasis.com
18 extern PFFS_GLOBAL FFSGlobal
;
20 #if (_WIN32_WINNT >= 0x0500)
24 extern PFFS_GLOBAL FFSGlobal
;
28 #define DBG_PNP DBG_USER
31 IO_COMPLETION_ROUTINE FFSPnpCompletionRoutine
;
35 FFSPnpCompletionRoutine(
36 IN PDEVICE_OBJECT DeviceObject
,
42 #pragma alloc_text(PAGE, FFSPnp)
43 #pragma alloc_text(PAGE, FFSPnpQueryRemove)
44 #pragma alloc_text(PAGE, FFSPnpRemove)
45 #pragma alloc_text(PAGE, FFSPnpCancelRemove)
46 #pragma alloc_text(PAGE, FFSPnpSurpriseRemove)
52 FFSPnpCompletionRoutine(
53 IN PDEVICE_OBJECT DeviceObject
,
57 PKEVENT Event
= (PKEVENT
) Contxt
;
59 KeSetEvent(Event
, 0, FALSE
);
61 return STATUS_MORE_PROCESSING_REQUIRED
;
63 UNREFERENCED_PARAMETER(DeviceObject
);
64 UNREFERENCED_PARAMETER(Contxt
);
68 __drv_mustHoldCriticalRegion
71 IN PFFS_IRP_CONTEXT IrpContext
)
73 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
76 PIO_STACK_LOCATION IrpSp
;
78 PDEVICE_OBJECT DeviceObject
;
86 ASSERT((IrpContext
->Identifier
.Type
== FFSICX
) &&
87 (IrpContext
->Identifier
.Size
== sizeof(FFS_IRP_CONTEXT
)));
89 DeviceObject
= IrpContext
->DeviceObject
;
91 Vcb
= (PFFS_VCB
)DeviceObject
->DeviceExtension
;
95 if (!((Vcb
->Identifier
.Type
== FFSVCB
) &&
96 (Vcb
->Identifier
.Size
== sizeof(FFS_VCB
))))
98 _SEH2_LEAVE
; // Status = STATUS_INVALID_PARAMETER
101 Irp
= IrpContext
->Irp
;
102 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
104 SetFlag(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
);
106 switch (IrpSp
->MinorFunction
)
109 case IRP_MN_QUERY_REMOVE_DEVICE
:
111 FFSPrint((DBG_PNP
, "FFSPnp: FFSPnpQueryRemove...\n"));
112 Status
= FFSPnpQueryRemove(IrpContext
, Vcb
);
116 case IRP_MN_REMOVE_DEVICE
:
118 FFSPrint((DBG_PNP
, "FFSPnp: FFSPnpRemove...\n"));
119 Status
= FFSPnpRemove(IrpContext
, Vcb
);
122 case IRP_MN_CANCEL_REMOVE_DEVICE
:
124 FFSPrint((DBG_PNP
, "FFSPnp: FFSPnpCancelRemove...\n"));
125 Status
= FFSPnpCancelRemove(IrpContext
, Vcb
);
128 case IRP_MN_SURPRISE_REMOVAL
:
130 FFSPrint((DBG_PNP
, "FFSPnp: FFSPnpSupriseRemove...\n"));
131 Status
= FFSPnpSurpriseRemove(IrpContext
, Vcb
);
141 if (!IrpContext
->ExceptionInProgress
)
143 Irp
= IrpContext
->Irp
;
148 // Here we need pass the IRP to the disk driver.
151 IoSkipCurrentIrpStackLocation(Irp
);
153 Status
= IoCallDriver(Vcb
->TargetDeviceObject
, Irp
);
155 IrpContext
->Irp
= NULL
;
158 FFSCompleteIrpContext(IrpContext
, Status
);
166 __drv_mustHoldCriticalRegion
169 PFFS_IRP_CONTEXT IrpContext
,
174 BOOLEAN bDeleted
= FALSE
;
175 BOOLEAN VcbAcquired
= FALSE
;
181 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove by FFSPnp ...\n"));
183 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove: FFSFlushVolume ...\n"));
185 #if (_WIN32_WINNT >= 0x0500)
186 CcWaitForCurrentLazyWriterActivity();
189 ExAcquireResourceExclusiveLite(
190 &Vcb
->MainResource
, TRUE
);
193 FFSFlushFiles(Vcb
, FALSE
);
195 FFSFlushVolume(Vcb
, FALSE
);
197 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove: FFSLockVcb: Vcb=%xh FileObject=%xh ...\n", Vcb
, IrpContext
->FileObject
));
198 Status
= FFSLockVcb(Vcb
, IrpContext
->FileObject
);
200 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove: FFSPurgeVolume ...\n"));
201 FFSPurgeVolume(Vcb
, TRUE
);
203 if (!NT_SUCCESS(Status
))
208 ExReleaseResourceForThreadLite(
210 ExGetCurrentResourceThread());
213 IoCopyCurrentIrpStackLocationToNext(IrpContext
->Irp
);
215 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
216 IoSetCompletionRoutine(IrpContext
->Irp
,
217 FFSPnpCompletionRoutine
,
223 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove: Call lower level driver...\n"));
224 Status
= IoCallDriver(Vcb
->TargetDeviceObject
,
227 if (Status
== STATUS_PENDING
)
229 KeWaitForSingleObject(&Event
,
235 Status
= IrpContext
->Irp
->IoStatus
.Status
;
238 if (NT_SUCCESS(Status
))
240 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove: FFSCheckDismount ...\n"));
241 bDeleted
= FFSCheckDismount(IrpContext
, Vcb
, TRUE
);
242 FFSPrint((DBG_PNP
, "FFSPnpQueryRemove: FFSFlushVolume bDelted=%xh ...\n", bDeleted
));
245 ASSERT(!(NT_SUCCESS(Status
) && !bDeleted
));
252 ExReleaseResourceForThreadLite(
254 ExGetCurrentResourceThread());
258 IrpContext
->Irp
, FALSE
, (CCHAR
)(NT_SUCCESS(Status
) ?
259 IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
261 IrpContext
->Irp
= NULL
;
268 __drv_mustHoldCriticalRegion
271 PFFS_IRP_CONTEXT IrpContext
,
283 FFSPrint((DBG_PNP
, "FFSPnpRemove by FFSPnp ...\n"));
284 #if (_WIN32_WINNT >= 0x0500)
285 CcWaitForCurrentLazyWriterActivity();
287 ExAcquireResourceExclusiveLite(
288 &Vcb
->MainResource
, TRUE
);
290 Status
= FFSLockVcb(Vcb
, IrpContext
->FileObject
);
292 ExReleaseResourceForThreadLite(
294 ExGetCurrentResourceThread());
297 // Setup the Irp. We'll send it to the lower disk driver.
300 IoCopyCurrentIrpStackLocationToNext(IrpContext
->Irp
);
302 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
303 IoSetCompletionRoutine(IrpContext
->Irp
,
304 FFSPnpCompletionRoutine
,
310 Status
= IoCallDriver(Vcb
->TargetDeviceObject
,
313 if (Status
== STATUS_PENDING
)
316 KeWaitForSingleObject(&Event
,
322 Status
= IrpContext
->Irp
->IoStatus
.Status
;
325 ExAcquireResourceExclusiveLite(
326 &Vcb
->MainResource
, TRUE
);
328 FFSPurgeVolume(Vcb
, FALSE
);
330 ExReleaseResourceForThreadLite(
332 ExGetCurrentResourceThread());
334 bDeleted
= FFSCheckDismount(IrpContext
, Vcb
, TRUE
);
340 IrpContext
->Irp
, FALSE
, (CCHAR
)(NT_SUCCESS(Status
)?
341 IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
343 IrpContext
->Irp
= NULL
;
350 __drv_mustHoldCriticalRegion
352 FFSPnpSurpriseRemove(
353 PFFS_IRP_CONTEXT IrpContext
,
365 FFSPrint((DBG_PNP
, "FFSPnpSupriseRemove by FFSPnp ...\n"));
366 #if (_WIN32_WINNT >= 0x0500)
367 CcWaitForCurrentLazyWriterActivity();
369 ExAcquireResourceExclusiveLite(
370 &Vcb
->MainResource
, TRUE
);
372 Status
= FFSLockVcb(Vcb
, IrpContext
->FileObject
);
374 ExReleaseResourceForThreadLite(
376 ExGetCurrentResourceThread());
379 // Setup the Irp. We'll send it to the lower disk driver.
382 IoCopyCurrentIrpStackLocationToNext(IrpContext
->Irp
);
384 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
385 IoSetCompletionRoutine(IrpContext
->Irp
,
386 FFSPnpCompletionRoutine
,
392 Status
= IoCallDriver(Vcb
->TargetDeviceObject
,
395 if (Status
== STATUS_PENDING
)
398 KeWaitForSingleObject(&Event
,
404 Status
= IrpContext
->Irp
->IoStatus
.Status
;
407 ExAcquireResourceExclusiveLite(
408 &Vcb
->MainResource
, TRUE
);
410 FFSPurgeVolume(Vcb
, FALSE
);
412 ExReleaseResourceForThreadLite(
414 ExGetCurrentResourceThread());
416 bDeleted
= FFSCheckDismount(IrpContext
, Vcb
, TRUE
);
422 IrpContext
->Irp
, FALSE
, (CCHAR
)(NT_SUCCESS(Status
)?
423 IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
425 IrpContext
->Irp
= NULL
;
432 __drv_mustHoldCriticalRegion
435 PFFS_IRP_CONTEXT IrpContext
,
442 FFSPrint((DBG_PNP
, "FFSPnpCancelRemove by FFSPnp ...\n"));
444 ExAcquireResourceExclusiveLite(
445 &Vcb
->MainResource
, TRUE
);
447 Status
= FFSUnlockVcb(Vcb
, IrpContext
->FileObject
);
449 ExReleaseResourceForThreadLite(
451 ExGetCurrentResourceThread());
453 IoSkipCurrentIrpStackLocation(IrpContext
->Irp
);
455 Status
= IoCallDriver(Vcb
->TargetDeviceObject
, IrpContext
->Irp
);
457 IrpContext
->Irp
= NULL
;
463 #endif //(_WIN32_WINNT >= 0x0500)