Exemplo n.º 1
0
VOID DokanUnload(__in PDRIVER_OBJECT DriverObject)
/*++

Routine Description:

        This routine gets called to remove the driver from the system.

Arguments:

        DriverObject    - the system supplied driver object.

Return Value:

        NTSTATUS

--*/

{

  PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
  WCHAR symbolicLinkBuf[] = DOKAN_GLOBAL_SYMBOLIC_LINK_NAME;
  UNICODE_STRING symbolicLinkName;
  PDOKAN_GLOBAL dokanGlobal;

  DDbgPrint("==> DokanUnload\n");

  PAGED_CODE();

  dokanGlobal = deviceObject->DeviceExtension;
  if (GetIdentifierType(dokanGlobal) == DGL) {
    DDbgPrint("  Delete Global DeviceObject\n");

    KeSetEvent(&dokanGlobal->KillDeleteDeviceEvent, 0, FALSE);
    RtlInitUnicodeString(&symbolicLinkName, symbolicLinkBuf);
    IoDeleteSymbolicLink(&symbolicLinkName);

    IoUnregisterFileSystem(dokanGlobal->FsDiskDeviceObject);
    IoUnregisterFileSystem(dokanGlobal->FsCdDeviceObject);

    IoDeleteDevice(dokanGlobal->FsDiskDeviceObject);
    IoDeleteDevice(dokanGlobal->FsCdDeviceObject);
    IoDeleteDevice(deviceObject);
  }

  ExDeleteNPagedLookasideList(&DokanIrpEntryLookasideList);

  ExDeleteLookasideListEx(&g_DokanCCBLookasideList);
  ExDeleteLookasideListEx(&g_DokanFCBLookasideList);
  ExDeleteLookasideListEx(&g_DokanEResourceLookasideList);

  DDbgPrint("<== DokanUnload\n");
}
Exemplo n.º 2
0
//
//	IOCTL_PREPARE_TO_UNLOAD
//
NTSTATUS LklPrepareToUnload(PDEVICE_OBJECT device,PIRP irp)
{
	NTSTATUS status = STATUS_SUCCESS;
	BOOLEAN acq_resource = FALSE;

	CHECK_OUT(device != lklfsd.device, STATUS_INVALID_DEVICE_REQUEST);

	ExAcquireResourceExclusiveLite(&lklfsd.global_resource, TRUE);
	acq_resource = TRUE;

	CHECK_OUT_MSG(FLAG_ON(lklfsd.flags, VFS_UNLOAD_PENDING), STATUS_ACCESS_DENIED,
		"Aldready ready to unload");
	CHECK_OUT_MSG(!IsListEmpty(&lklfsd.vcb_list), STATUS_ACCESS_DENIED,
		"Mounted volumes exists");
    	DbgPrint("Unloading LklVfs");
	IoUnregisterFileSystem(lklfsd.device);

	//unload_linux_kernel();
    
	IoDeleteDevice(lklfsd.device);
     
        lklfsd.driver->DriverUnload = DriverUnload;
	SET_FLAG(lklfsd.flags, VFS_UNLOAD_PENDING);

try_exit:

	if (acq_resource)
		RELEASE(&lklfsd.global_resource);

	return status;
}
Exemplo n.º 3
0
VOID CleanupGlobalDiskDevice(PDOKAN_GLOBAL dokanGlobal) {
  WCHAR symbolicLinkBuf[] = DOKAN_GLOBAL_SYMBOLIC_LINK_NAME;
  UNICODE_STRING symbolicLinkName;

  KeSetEvent(&dokanGlobal->KillDeleteDeviceEvent, 0, FALSE);

  RtlInitUnicodeString(&symbolicLinkName, symbolicLinkBuf);
  IoDeleteSymbolicLink(&symbolicLinkName);

  IoUnregisterFileSystem(dokanGlobal->FsDiskDeviceObject);
  IoUnregisterFileSystem(dokanGlobal->FsCdDeviceObject);

  IoDeleteDevice(dokanGlobal->FsDiskDeviceObject);
  IoDeleteDevice(dokanGlobal->FsCdDeviceObject);
  IoDeleteDevice(dokanGlobal->DeviceObject);
  ExDeleteResourceLite(&dokanGlobal->Resource);
}
Exemplo n.º 4
0
NTSTATUS
NTAPI
FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject,
                    IN PWCHAR DriverServiceName)
{
    UNICODE_STRING DriverName;
    PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS Status = STATUS_IMAGE_ALREADY_LOADED;
    PAGED_CODE();

    /* Make sure we haven't already been called */
    if (DeviceExtension->State != Loaded)
    {
        /* Acquire the load lock */
        KeWaitForSingleObject(FsRecLoadSync,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        KeEnterCriticalRegion();

        /* Make sure we're active */
        if (DeviceExtension->State == Pending)
        {
            /* Load the FS driver */
            RtlInitUnicodeString(&DriverName, DriverServiceName);
            Status = ZwLoadDriver(&DriverName);

            /* Loop all the linked recognizer objects */
            while (DeviceExtension->State != Unloading)
            {
                /* Set them to the unload state */
                DeviceExtension->State = Unloading;

                /* Go to the next one */
                DeviceObject = DeviceExtension->Alternate;
                DeviceExtension = DeviceObject->DeviceExtension;
            }
        }

        /* Make sure that we haven't already loaded the FS */
        if (DeviceExtension->State != Loaded)
        {
            /* Unregiser us, and set us as loaded */
            IoUnregisterFileSystem(DeviceObject);
            DeviceExtension->State = Loaded;
        }

        /* Release the lock */
        KeSetEvent(FsRecLoadSync, 0, FALSE);
        KeLeaveCriticalRegion();
    }

    /* Return */
    return Status;
}
Exemplo n.º 5
0
__drv_mustHoldCriticalRegion    
NTSTATUS
FatCommonShutdown (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for shutdown called by both the fsd and
    fsp threads.

Arguments:

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    KEVENT Event;
    PLIST_ENTRY Links;
    PVCB Vcb;
    PIRP NewIrp;
    IO_STATUS_BLOCK Iosb;
    BOOLEAN VcbDeleted;

    PAGED_CODE();

    //
    //  Make sure we don't get any pop-ups, and write everything through.
    //

    SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS |
                               IRP_CONTEXT_FLAG_WRITE_THROUGH);

    //
    //  Initialize an event for doing calls down to
    //  our target device objects.
    //

    KeInitializeEvent( &Event, NotificationEvent, FALSE );

    //
    //  Indicate that shutdown has started.  This is used in FatFspClose.
    //

    FatData.ShutdownStarted = TRUE;    

    //
    //  Get everyone else out of the way
    //
    
    ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

#pragma prefast( push )
#pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
#pragma prefast( disable: 28193, "this will always wait" )

    (VOID) FatAcquireExclusiveGlobal( IrpContext );

#pragma prefast( pop )

    try {

        //
        //  For every volume that is mounted we will flush the
        //  volume and then shutdown the target device objects.
        //

        Links = FatData.VcbQueue.Flink;
        while (Links != &FatData.VcbQueue) {

            Vcb = CONTAINING_RECORD(Links, VCB, VcbLinks);

            Links = Links->Flink;

            //
            //  If we have already been called before for this volume
            //  (and yes this does happen), skip this volume as no writes
            //  have been allowed since the first shutdown.
            //

            if ( FlagOn( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN) ||
                 (Vcb->VcbCondition != VcbGood) ) {

                continue;
            }

            FatAcquireExclusiveVolume( IrpContext, Vcb );

            try {

                (VOID)FatFlushVolume( IrpContext, Vcb, Flush );

                //
                //  The volume is now clean, note it.  We purge the
                //  volume file cache map before marking the volume
                //  clean incase there is a stale Bpb in the cache.
                //

                if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {

                    CcPurgeCacheSection( &Vcb->SectionObjectPointers,
                                         NULL,
                                         0,
                                         FALSE );

                    FatMarkVolume( IrpContext, Vcb, VolumeClean );
                }

            } except( EXCEPTION_EXECUTE_HANDLER ) {

                  FatResetExceptionState( IrpContext );
            }

            //
            //  Sometimes we take an excepion while flushing the volume, such
            //  as when autoconv has converted the volume and is rebooting.
            //  Even in that case we want to send the shutdown irp to the
            //  target device so it can know to flush its cache, if it has one.
            //

            try {

                NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN,
                                                       Vcb->TargetDeviceObject,
                                                       NULL,
                                                       0,
                                                       NULL,
                                                       &Event,
                                                       &Iosb );

                if (NewIrp != NULL) {

                    if (NT_SUCCESS(IoCallDriver( Vcb->TargetDeviceObject, NewIrp ))) {

                        (VOID) KeWaitForSingleObject( &Event,
                                                      Executive,
                                                      KernelMode,
                                                      FALSE,
                                                      NULL );

                        KeClearEvent( &Event );
                    }
                }

            } except( EXCEPTION_EXECUTE_HANDLER ) {

                  FatResetExceptionState( IrpContext );
            }

            SetFlag( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN );

            //
            //  Attempt to punch the volume down.
            //

            VcbDeleted = FatCheckForDismount( IrpContext,
                                              Vcb,
                                              FALSE );

            if (!VcbDeleted) {
                
#pragma prefast( suppress:28107, "prefast is having trouble figuring out that Vcb is acquired" )
                FatReleaseVolume( IrpContext, Vcb );
            }
        }

    } finally {

        FatReleaseGlobal( IrpContext );

        //
        //  Unregister the file system.
        //
        
        IoUnregisterFileSystem( FatDiskFileSystemDeviceObject);
        IoUnregisterFileSystem( FatCdromFileSystemDeviceObject);
        IoDeleteDevice( FatDiskFileSystemDeviceObject);
        IoDeleteDevice( FatCdromFileSystemDeviceObject);

        FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
    }

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdShutdown -> STATUS_SUCCESS\n", 0);

    return STATUS_SUCCESS;
}
Exemplo n.º 6
0
NTSTATUS
CdCommonShutdown (
    _Inout_ PIRP_CONTEXT IrpContext,
    _Inout_ PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for handling shutdown operation called
    by both the fsd and fsp threads

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    KEVENT Event;
    PLIST_ENTRY Links;
    PVCB Vcb;
    PIRP NewIrp;
    IO_STATUS_BLOCK Iosb;
    BOOLEAN VcbPresent;
    NTSTATUS Status;

    PAGED_CODE();

    //
    //  Make sure we don't get any pop-ups.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS );

    //
    //  Initialize an event for doing calls down to
    //  our target device objects.
    //

    KeInitializeEvent( &Event, NotificationEvent, FALSE );

    //
    //  Indicate that shutdown has started.
    //

    SetFlag( CdData.Flags, CD_FLAGS_SHUTDOWN );

    //
    //  Get everyone else out of the way
    //

    CdAcquireCdData( IrpContext );

    //
    //  Now walk through all the mounted Vcb's and shutdown the target
    //  device objects.
    //

    Links = CdData.VcbQueue.Flink;

    while (Links != &CdData.VcbQueue) {

        Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks );

        //
        //  Move to the next link now since the current Vcb may be deleted.
        //

        Links = Links->Flink;

        //
        //  If we have already been called before for this volume
        //  (and yes this does happen), skip this volume as no writes
        //  have been allowed since the first shutdown.
        //

        if (FlagOn( Vcb->VcbState, VCB_STATE_SHUTDOWN ) ||
            (Vcb->VcbCondition != VcbMounted)) {

            continue;
        }

	#pragma prefast(suppress: 28103)
        CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );

        CdPurgeVolume( IrpContext, Vcb, FALSE );

        //
        //  Build an irp for this volume stack - our own irp is probably too small and
        //  each stack may have a different stack size.
        //

        NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN,
                                               Vcb->TargetDeviceObject,
                                               NULL,
                                               0,
                                               NULL,
                                               &Event,
                                               &Iosb );

        if (NewIrp != NULL) {

            Status = IoCallDriver( Vcb->TargetDeviceObject, NewIrp );

            if (Status == STATUS_PENDING) {

                (VOID)KeWaitForSingleObject( &Event,
                                             Executive,
                                             KernelMode,
                                             FALSE,
                                             NULL );
            }

            KeClearEvent( &Event );
        }

        SetFlag( Vcb->VcbState, VCB_STATE_SHUTDOWN );

        //
        //  Attempt to punch the volume down.
        //

        VcbPresent = CdCheckForDismount( IrpContext, Vcb, FALSE );

        if (VcbPresent) {

            CdReleaseVcb( IrpContext, Vcb );
        }
    }


    CdReleaseCdData( IrpContext );

    IoUnregisterFileSystem( CdData.FileSystemDeviceObject );
    IoDeleteDevice( CdData.FileSystemDeviceObject );

    CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
    return STATUS_SUCCESS;
}
Exemplo n.º 7
0
NTSTATUS
Ext2PrepareToUnload (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    BOOLEAN         GlobalDataResourceAcquired = FALSE;

    __try {

        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        if (IsExt2FsDevice(DeviceObject)) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        ExAcquireResourceExclusiveLite(
            &Ext2Global->Resource,
            TRUE );

        GlobalDataResourceAcquired = TRUE;

        if (FlagOn(Ext2Global->Flags, EXT2_UNLOAD_PENDING)) {
            DEBUG(DL_ERR, ( "Ext2PrepareUnload:  Already ready to unload.\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

        {
            PEXT2_VCB               Vcb;
            PLIST_ENTRY             ListEntry;

            ListEntry = Ext2Global->VcbList.Flink;

            while (ListEntry != &(Ext2Global->VcbList)) {

                Vcb = CONTAINING_RECORD(ListEntry, EXT2_VCB, Next);
                ListEntry = ListEntry->Flink;

                if (Vcb && (!Vcb->ReferenceCount) &&
                        IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
                    Ext2RemoveVcb(Vcb);
                    Ext2ClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);

                    Ext2DestroyVcb(Vcb);
                }
            }
        }

        if (!IsListEmpty(&(Ext2Global->VcbList))) {

            DEBUG(DL_ERR, ( "Ext2PrepareUnload:  Mounted volumes exists.\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

        IoUnregisterFileSystem(Ext2Global->DiskdevObject);
        IoUnregisterFileSystem(Ext2Global->CdromdevObject);
        Ext2Global->DriverObject->DriverUnload = DriverUnload;
        SetLongFlag(Ext2Global->Flags ,EXT2_UNLOAD_PENDING);
        Status = STATUS_SUCCESS;

        DEBUG(DL_INF, ( "Ext2PrepareToUnload: Driver is ready to unload.\n"));

    } __finally {

        if (GlobalDataResourceAcquired) {
            ExReleaseResourceLite(&Ext2Global->Resource);
        }

        if (!IrpContext->ExceptionInProgress) {
            Ext2CompleteIrpContext(IrpContext, Status);
        }
    }

    return Status;
}