⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fs_rec.c

📁 微软win2k的fsrec源码,驱动中展示了如何启动文件系统驱动程序,如何根据硬盘和光盘上的文件系统类型调用不同的文件系统驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1992  Microsoft Corporation

Module Name:

    fs_rec.c

Abstract:

    This module contains the main functions for the mini-file system recognizer
    driver.

Author:

    Darryl E. Havens (darrylh) 22-nov-1993

Environment:

    Kernel mode, local to I/O system

Revision History:


--*/

#include "fs_rec.h"

//
//  The local debug trace level
//

#define Dbg                              (FSREC_DEBUG_LEVEL_FSREC)

#if DBG

#include <stdarg.h>
#include <stdio.h>

LONG FsRecDebugTraceLevel = 0;
LONG FsRecDebugTraceIndent = 0;

#endif

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(INIT,FsRecCreateAndRegisterDO)

#pragma alloc_text(PAGE,FsRecCleanupClose)
#pragma alloc_text(PAGE,FsRecCreate)
#pragma alloc_text(PAGE,FsRecFsControl)
#pragma alloc_text(PAGE,FsRecGetDeviceSectorSize)
#pragma alloc_text(PAGE,FsRecGetDeviceSectors)
#pragma alloc_text(PAGE,FsRecLoadFileSystem)
#pragma alloc_text(PAGE,FsRecReadBlock)
#pragma alloc_text(PAGE,FsRecUnload)
#endif // ALLOC_PRAGMA

//
//  Mutex for serializing driver loads.
//

PKEVENT FsRecLoadSync;


NTSTATUS
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This routine is invoked once when the driver is loaded to allow the driver
    to initialize itself.  The initialization for the driver consists of simply
    creating a device object for each type of file system recognized by this
    driver, and then registering each as active file systems.

Arguments:

    DriverObject - Pointer to the driver object for this driver.

    RegistryPath - Pointer to the registry service node for this driver.

Return Value:

    The function value is the final status of the initialization for the driver.

--*/

{
    PDEVICE_OBJECT UdfsMainRecognizerDeviceObject;
    NTSTATUS status;
    ULONG count = 0;

    PAGED_CODE();

    //
    // Mark the entire driver as pagable.
    //

    MmPageEntireDriver ((PVOID)DriverEntry);

    //
    // Begin by initializing the driver object so that it the driver is
    // prepared to provide services.
    //

    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecCleanupClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecCleanupClose;
    DriverObject->DriverUnload = FsRecUnload;

    FsRecLoadSync = ExAllocatePoolWithTag( NonPagedPool, sizeof(KEVENT), FSREC_POOL_TAG );

    if (FsRecLoadSync == NULL) {

	return STATUS_INSUFFICIENT_RESOURCES;
    }

    KeInitializeEvent( FsRecLoadSync, SynchronizationEvent, TRUE );

    //
    // Create and initialize each of the file system driver type device
    // objects.
    //

    status = FsRecCreateAndRegisterDO( DriverObject,
                                       NULL,
                                       NULL,
                                       L"\\Cdfs",
                                       L"\\FileSystem\\CdfsRecognizer",
                                       CdfsFileSystem,
                                       FILE_DEVICE_CD_ROM_FILE_SYSTEM );
    if (NT_SUCCESS( status )) {
        count++;
    }

    status = FsRecCreateAndRegisterDO( DriverObject,
                                       NULL,
                                       &UdfsMainRecognizerDeviceObject,
                                       L"\\UdfsCdRom",
                                       L"\\FileSystem\\UdfsCdRomRecognizer",
                                       UdfsFileSystem,
                                       FILE_DEVICE_CD_ROM_FILE_SYSTEM );
    if (NT_SUCCESS( status )) {
        count++;
    }

    status = FsRecCreateAndRegisterDO( DriverObject,
                                       UdfsMainRecognizerDeviceObject,
                                       NULL,
                                       L"\\UdfsDisk",
                                       L"\\FileSystem\\UdfsDiskRecognizer",
                                       UdfsFileSystem,
                                       FILE_DEVICE_DISK_FILE_SYSTEM );
    if (NT_SUCCESS( status )) {
        count++;
    }

    status = FsRecCreateAndRegisterDO( DriverObject,
                                       NULL,
                                       NULL,
                                       L"\\Fat",
                                       L"\\FileSystem\\FatRecognizer",
                                       FatFileSystem,
                                       FILE_DEVICE_DISK_FILE_SYSTEM );
    if (NT_SUCCESS( status )) {
        count++;
    }

    status = FsRecCreateAndRegisterDO( DriverObject,
                                       NULL,
                                       NULL,
                                       L"\\Ntfs",
                                       L"\\FileSystem\\NtfsRecognizer",
                                       NtfsFileSystem,
                                       FILE_DEVICE_DISK_FILE_SYSTEM );
    if (NT_SUCCESS( status )) {
        count++;
    }

    if (count) {
        return STATUS_SUCCESS;
    } else {
        return STATUS_IMAGE_ALREADY_LOADED;
    }
}


NTSTATUS
FsRecCleanupClose (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is invoked when someone attempts to cleanup or close one of
    the system recognizer's registered device objects.

Arguments:

    DeviceObject - Pointer to the device object being closed.

    Irp - Pointer to the cleanup/close IRP.

Return Value:

    The final function value is STATUS_SUCCESS.

--*/

{
    PAGED_CODE();

    //
    // Simply complete the request successfully (note that IoStatus.Status in
    // Irp is already initialized to STATUS_SUCCESS).
    //

    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return STATUS_SUCCESS;
}


NTSTATUS
FsRecCreate (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is invoked when someone attempts to open one of the file
    system recognizer's registered device objects.

Arguments:

    DeviceObject - Pointer to the device object being opened.

    Irp - Pointer to the create IRP.

Return Value:

    The final function value indicates whether or not the open was successful.

--*/

{
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    NTSTATUS status;

    PAGED_CODE();

    //
    // Simply ensure that the name of the "file" being opened is NULL, and
    // complete the request accordingly.
    //

    if (irpSp->FileObject->FileName.Length) {
        status = STATUS_OBJECT_PATH_NOT_FOUND;
    } else {
        status = STATUS_SUCCESS;
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = FILE_OPENED;
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return status;
}


NTSTATUS
FsRecCreateAndRegisterDO (
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT HeadRecognizer OPTIONAL,
    OUT PDEVICE_OBJECT *NewRecognizer OPTIONAL,
    IN PWCHAR RecFileSystem,
    IN PWCHAR FileSystemName,
    IN FILE_SYSTEM_TYPE FileSystemType,
    IN DEVICE_TYPE DeviceType
    )

/*++

Routine Description:

    This routine creates a device object for the specified file system type and
    registers it as an active file system.

Arguments:

    DriverObject - Pointer to the driver object for this driver.
    
    HeadRecognizer - Optionally supplies a pre-existing recognizer that the
        newly created DO should be jointly serialized and unregistered with.
        This is useful if a given filesystem exists on multiple device types
        and thus requires multiple recognizers.
    
    NewDeviceObject - Receives the created DO on success..

    RecFileSystem - Name of the file system to be recognized.

    FileSystemName - Name of file system device object to be registered.

    FileSystemType - Type of this file system recognizer device object.
    
    DeviceType - Type of media this file system recognizer device object will inspect.

Return Value:

    The final function value indicates whether or not the device object was
    successfully created and registered.

--*/

{
    PDEVICE_OBJECT deviceObject;
    NTSTATUS status;
    UNICODE_STRING nameString;
    OBJECT_ATTRIBUTES objectAttributes;
    HANDLE fsHandle;
    IO_STATUS_BLOCK ioStatus;
    PDEVICE_EXTENSION deviceExtension;

    PAGED_CODE();

    if (NewRecognizer) {

        *NewRecognizer = NULL;
    }

    //
    // Begin by attempting to open the file system driver's device object.  If
    // it works, then the file system is already loaded, so don't load this
    // driver.  Otherwise, this mini-driver is the one that should be loaded.
    //

    RtlInitUnicodeString( &nameString, RecFileSystem );
    InitializeObjectAttributes( &objectAttributes,
                                &nameString,
                                OBJ_CASE_INSENSITIVE,
                                (HANDLE) NULL,
                                (PSECURITY_DESCRIPTOR) NULL );

    status = ZwCreateFile( &fsHandle,
                           SYNCHRONIZE,
                           &objectAttributes,
                           &ioStatus,
                           (PLARGE_INTEGER) NULL,
                           0,
                           FILE_SHARE_READ | FILE_SHARE_WRITE,
                           FILE_OPEN,
                           0,
                           (PVOID) NULL,
                           0 );

    if (NT_SUCCESS( status )) {
        ZwClose( fsHandle );
    } else if (status != STATUS_OBJECT_NAME_NOT_FOUND) {
        status = STATUS_SUCCESS;
    }

    if (NT_SUCCESS( status )) {
        return STATUS_IMAGE_ALREADY_LOADED;
    }

    //
    // Attempt to create a device object for this driver.  This device object
    // will be used to represent the driver as an active file system in the
    // system.
    //

    RtlInitUnicodeString( &nameString, FileSystemName );

    status = IoCreateDevice( DriverObject,
                             sizeof( DEVICE_EXTENSION ),
                             &nameString,
                             DeviceType,
                             0,
                             FALSE,
                             &deviceObject );
    if (!NT_SUCCESS( status )) {
        return status;
    }

    //
    // Initialize the device extension for this device object.
    //

    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
    deviceExtension->FileSystemType = FileSystemType;
    deviceExtension->State = Active;

    //
    //  Is this a filesystem being jointly recognized by recognizers for
    //  different device types?
    //
    
    if (HeadRecognizer) {

        //
        //  Link into the list.
        //
        
        deviceExtension->CoRecognizer = ((PDEVICE_EXTENSION)HeadRecognizer->DeviceExtension)->CoRecognizer;
        ((PDEVICE_EXTENSION)HeadRecognizer->DeviceExtension)->CoRecognizer = deviceObject;
    
    } else {

        //
        //  Initialize the list of codependant recognizer objects.
        //
        
        deviceExtension->CoRecognizer = deviceObject;
    }
    
#if _PNP_POWER_
    deviceObject->DeviceObjectExtension->PowerControlNeeded = FALSE;
#endif

    //
    // Finally, register this driver as an active, loaded file system and
    // return to the caller.
    //

    if (NewRecognizer) {

        *NewRecognizer = deviceObject;
    }

    IoRegisterFileSystem( deviceObject );
    return STATUS_SUCCESS;
}


NTSTATUS
FsRecFsControl (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This function performs the mount and driver reload functions for this mini-
    file system recognizer driver.

Arguments:

    DeviceObject - Pointer to this driver's device object.

    Irp - Pointer to the I/O Request Packet (IRP) representing the function to
        be performed.

Return Value:

    The function value is the final status of the operation.


--*/

{
    PDEVICE_EXTENSION deviceExtension;
    PIO_STACK_LOCATION irpSp;
    NTSTATUS status;

    PAGED_CODE();

    //
    // Simply vector to the appropriate FS control function given the type
    // of file system being interrogated.
    //

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Handle the inactive recognizer states directly.
    //
    
    if (deviceExtension->State != Active && irpSp->MinorFunction == IRP_MN_MOUNT_VOLUME) {
        
        if (deviceExtension->State == Transparent) {

            status = STATUS_UNRECOGNIZED_VOLUME;
        
        } else {
        
            status = STATUS_FS_DRIVER_REQUIRED;
        }

        Irp->IoStatus.Status = status;
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        return status;
    }

    switch ( deviceExtension->FileSystemType ) {

        case FatFileSystem:

            status = FatRecFsControl( DeviceObject, Irp );
            break;

        case NtfsFileSystem:

            status = NtfsRecFsControl( DeviceObject, Irp );
            break;

        case CdfsFileSystem:

            status = CdfsRecFsControl( DeviceObject, Irp );
            break;

        case UdfsFileSystem:

            status = UdfsRecFsControl( DeviceObject, Irp );
            break;

        default:

            status = STATUS_INVALID_DEVICE_REQUEST;
    }

    return status;
}


VOID
FsRecUnload (
    IN PDRIVER_OBJECT DriverObject
    )

/*++

Routine Description:

    This routine cleans up the driver's data structures so that it can be
    unloaded.

Arguments:

    DriverObject - Pointer to the driver object for this driver.

Return Value:

    None.

--*/

{
    PAGED_CODE();

    //
    // Simply delete all of the device objects that this driver has created, the
    // load event, and return.
    //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -