Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: pnp.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
#if (_WIN32_WINNT >= 0x0500)
/* INCLUDES *****************************************************************/
#include "ext2fs.h"
/* GLOBALS ***************************************************************/
extern PEXT2_GLOBAL Ext2Global;
/* DEFINITIONS *************************************************************/
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifExt2PnpCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt );
#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, Ext2Pnp)#pragma alloc_text(PAGE, Ext2PnpQueryRemove)#pragma alloc_text(PAGE, Ext2PnpRemove)#pragma alloc_text(PAGE, Ext2PnpCancelRemove)#pragma alloc_text(PAGE, Ext2PnpSurpriseRemove)#endif
/* FUNCTIONS *************************************************************/
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifExt2PnpCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt){ PKEVENT Event = (PKEVENT) Contxt;
KeSetEvent( Event, 0, FALSE );
return STATUS_MORE_PROCESSING_REQUIRED;
UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Contxt );}
NTSTATUSExt2Pnp (IN PEXT2_IRP_CONTEXT IrpContext){ NTSTATUS Status = STATUS_INVALID_PARAMETER;
PIRP Irp; PIO_STACK_LOCATION IrpSp; PEXT2_VCB Vcb = NULL; PDEVICE_OBJECT DeviceObject;
_SEH2_TRY {
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
if ( !((Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB)))) { _SEH2_LEAVE; // Status = STATUS_INVALID_PARAMETER }
Irp = IrpContext->Irp; IrpSp = IoGetCurrentIrpStackLocation(Irp);
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
switch ( IrpSp->MinorFunction ) {
case IRP_MN_QUERY_REMOVE_DEVICE:
DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpQueryRemove...\n")); Status = Ext2PnpQueryRemove(IrpContext, Vcb);
break;
case IRP_MN_REMOVE_DEVICE:
DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpRemove...\n")); Status = Ext2PnpRemove(IrpContext, Vcb); break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpCancelRemove...\n")); Status = Ext2PnpCancelRemove(IrpContext, Vcb); break;
case IRP_MN_SURPRISE_REMOVAL:
DEBUG(DL_PNP, ("Ext2Pnp: Ext2PnpSupriseRemove...\n")); Status = Ext2PnpSurpriseRemove(IrpContext, Vcb); break;
default: break; }
} _SEH2_FINALLY {
if (!IrpContext->ExceptionInProgress) { Irp = IrpContext->Irp;
if (Irp) {
// // Here we need pass the IRP to the disk driver. //
IoSkipCurrentIrpStackLocation( Irp );
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
IrpContext->Irp = NULL; }
Ext2CompleteIrpContext(IrpContext, Status); } } _SEH2_END;
return Status;}
NTSTATUSExt2PnpQueryRemove ( PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb){ NTSTATUS Status = STATUS_SUCCESS; KEVENT Event; BOOLEAN bDeleted = FALSE; BOOLEAN VcbAcquired = FALSE;
_SEH2_TRY {
CcWaitForCurrentLazyWriterActivity();
VcbAcquired = ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE );
Ext2FlushFiles(IrpContext, Vcb, FALSE); Ext2FlushVolume(IrpContext, Vcb, FALSE);
DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2LockVcb: Vcb=%xh FileObject=%xh ...\n", Vcb, IrpContext->FileObject)); Status = Ext2LockVcb(Vcb, IrpContext->FileObject);
if (VcbAcquired) { ExReleaseResourceLite(&Vcb->MainResource); VcbAcquired = FALSE; }
DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2PurgeVolume ...\n")); Ext2PurgeVolume(Vcb, TRUE);
if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; }
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
KeInitializeEvent( &Event, NotificationEvent, FALSE ); IoSetCompletionRoutine( IrpContext->Irp, Ext2PnpCompletionRoutine, &Event, TRUE, TRUE, TRUE );
DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Call lower level driver...\n")); Status = IoCallDriver( Vcb->TargetDeviceObject, IrpContext->Irp);
if (Status == STATUS_PENDING) { KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); Status = IrpContext->Irp->IoStatus.Status; }
if (NT_SUCCESS(Status)) { ASSERT(!VcbAcquired); DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2CheckDismount ...\n")); bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE); DEBUG(DL_PNP, ("Ext2PnpQueryRemove: Ext2FlushVolume bDelted=%xh ...\n", bDeleted)); }
} _SEH2_FINALLY {
if (VcbAcquired) { ExReleaseResourceLite(&Vcb->MainResource); }
IrpContext->Irp->IoStatus.Status = Status; Ext2CompleteRequest( IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT) );
IrpContext->Irp = NULL; } _SEH2_END;
return Status;}
NTSTATUSExt2PnpRemove ( PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb ){ NTSTATUS Status = STATUS_SUCCESS; KEVENT Event; BOOLEAN bDeleted;
_SEH2_TRY {
DEBUG(DL_PNP, ("Ext2PnpRemove by Ext2Pnp ...\n"));
CcWaitForCurrentLazyWriterActivity(); ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE ); Status = Ext2LockVcb(Vcb, IrpContext->FileObject); ExReleaseResourceLite(&Vcb->MainResource);
// // Setup the Irp. We'll send it to the lower disk driver. //
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
KeInitializeEvent( &Event, NotificationEvent, FALSE ); IoSetCompletionRoutine( IrpContext->Irp, Ext2PnpCompletionRoutine, &Event, TRUE, TRUE, TRUE );
Status = IoCallDriver( Vcb->TargetDeviceObject, IrpContext->Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
Status = IrpContext->Irp->IoStatus.Status; }
/* purge volume cache */ Ext2PurgeVolume(Vcb, FALSE);
/* dismount volume */ bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE); SetLongFlag(Vcb->Flags, VCB_DEVICE_REMOVED);
} _SEH2_FINALLY {
IrpContext->Irp->IoStatus.Status = Status; Ext2CompleteRequest( IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT) );
IrpContext->Irp = NULL; } _SEH2_END;
return Status;}
NTSTATUSExt2PnpSurpriseRemove ( PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb ){ NTSTATUS Status; KEVENT Event; BOOLEAN bDeleted;
_SEH2_TRY {
DEBUG(DL_PNP, ("Ext2PnpSupriseRemove by Ext2Pnp ...\n"));
CcWaitForCurrentLazyWriterActivity(); ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE );
Status = Ext2LockVcb(Vcb, IrpContext->FileObject);
ExReleaseResourceLite(&Vcb->MainResource);
// // Setup the Irp. We'll send it to the lower disk driver. //
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
KeInitializeEvent( &Event, NotificationEvent, FALSE ); IoSetCompletionRoutine( IrpContext->Irp, Ext2PnpCompletionRoutine, &Event, TRUE, TRUE, TRUE );
Status = IoCallDriver( Vcb->TargetDeviceObject, IrpContext->Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
Status = IrpContext->Irp->IoStatus.Status; }
/* purge volume cache */ Ext2PurgeVolume(Vcb, FALSE);
/* dismount volume */ bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE); SetLongFlag(Vcb->Flags, VCB_DEVICE_REMOVED);
} _SEH2_FINALLY {
IrpContext->Irp->IoStatus.Status = Status; Ext2CompleteRequest( IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT) );
IrpContext->Irp = NULL; } _SEH2_END;
return Status;}
NTSTATUSExt2PnpCancelRemove ( PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb){ NTSTATUS Status;
DEBUG(DL_PNP, ("Ext2PnpCancelRemove by Ext2Pnp ...\n"));
ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE );
Status = Ext2UnlockVcb(Vcb, IrpContext->FileObject);
ExReleaseResourceLite(&Vcb->MainResource);
IoSkipCurrentIrpStackLocation(IrpContext->Irp);
Status = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);
IrpContext->Irp = NULL;
return Status;}
#endif //(_WIN32_WINNT >= 0x0500)