你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Linux开发
文件系统识别器(1)
 
文件系统识别器是一个标准的NT内核模式驱动程序。它只实现一项功能:检查物理介质设备,如果它能够识别存储介质的格式便加载相应的文件系统驱动程序。你可能要问:为什么不把所有的文件系统一起加载呢?因为系统几乎从不需要加载所有文件系统驱动程序,用一个小驱动可以节约数百K系统内存。实际上,所有标准的NT物理介质文件系统都利用文件系统识别器。举个例子来说,如果CD-ROM没有被访问,那么CDFS文件系统驱动程序将不会被加载。

文件系统识别器是怎么样知道磁盘上存在什么类型的文件系统呢?一般说来,检查磁盘上的标识符就可以了。标识符可能存储在于分区表里,从分区起始处加上一段偏移量就能定位这个唯一值,这个值可以是序列号或者其他某种标识符。这些标识符必须完全不同,以免加载了不正确的文件系统驱动程序。

以下是一些常用的文件系统标识:

文件系统名 文件系统标识
HFS 0x4244
NTFS ''NTFS''
FAT 0xe9或0xeb或0x49
表1 常见的文件系统标识符

当一个文件系统程序被加载后,它必须分析磁盘以便确定介质上是否包含了它可以识别的文件系统。如果介质上是可以识别的文件系统,该文件系统驱动程序将“装配”这个文件系统。文件系统识别器也分析介质来确认是否有可识别的文件系统。但是文件系统识别器不是“装配”到卷上,而是加载文件系统驱动程序。文件系统识别器完成任务便可以卸载了。

装配过程

在NT系统中,当一个卷被访问时才被装配。一些卷在系统初始化被装配,用磁盘管理程序或可移动介质创建的卷会在晚些时候被装配。因此,当你创建新的分区并且为它分配了盘符,直到有应用程序访问这个卷时这个卷才会被装配。所以,当你为软驱更换了盘片,直到有程序访问软盘时卷才被装配。

一个WIN32应用程序通过盘符访问卷。盘符只是对象管理器名字空间的一个符号连接。你可以利用平台SDK里的工具WINOBJ查看。盘符是物理磁盘卷的符号连接而不是文件文件系统驱动程序创建的设备的符号连接。当IO管理器发现为物理存储设备创建的设备对象有 FILE_DEVICE_DISK, FILE_DEVICE_TAPE, FILE_DEVICE_CD_ROM,或者 FILE_DEVICE_VIRTUAL_DISK标记时,这些设备对象就有卷参数块(Volume Parameter Block)。VPB用于表示卷是否已经被装配了。如果已经装配了,VPB 指向属于文件系统驱动程序的设备对象。如果没有被装配,IO管理器将尝试装配这个卷。

IO管理器为当前物理介质类型( FILE_DEVICE_DISK_FILE_SYSTEM,FILE_DEVICE_TAPE_FILE_SYSTEM, FILE_DEVICE_CD_ROM _FILE _SYSTEM)的卷调用每一个注册的文件系统驱动程序。通过调用驱动的IRP_MJ_FILE_SYSTEM_ CONTROL派遣例程,传递给派遣例程次功能码是IRP_MN_MOUNT_VOLUME便可以实现装配。驱动程序返回给IO管理器该卷是否可以被装配的信息。调用次序是后注册先调用。所以被装载最频繁的文件系统驱动程序首先得到装配卷的机会。

实际上第一个注册的是RAW文件系统,它注册另外三种不同的文件系统。当RAW文件系统装配卷时,它便注册这三种不同的文件系统。属于RAW文件系统的卷只能被“全部访问 ("whole volume" )”操作打开。磁盘管理器需要做这样的操作。

文件系统识别器实际上就是一个只处理装配请求的文件系统驱动程序。因此,它用相应的文件系统类型创建设备对象,向IO管理器注册为文件系统,然后等待被调用去装配卷。如果识别器确认了卷属于它的文件系统,它返回错误码STATUS_FS_DRIVER_REQUIRED,而不是接受这个装配请求。接着IO管理器调用识别器,让它加载整个文件系统驱动程序。具体细节是发送IRP IRP_MJ _FILE_SYSTEM_CONTROL,次功能码为IRP_MN_LOAD_FILE_SYSTEM。

实现

实现一个文件系统识别器是非常直接的,我们提供一个例子程序,你可以利用它创建自己的文件系统识别器。

#include <ntddk.h>

// 定义可能随着你的文件系统而改变

#define FSD_SERVICE_PATH L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MyFsd"
#define FSD_RECOGNIZER_NAME L"\\FileSystem\\MyFsdRecognizer"
#define DEVICE_LOGICAL_BLOCKSIZE 512 // 每一个扇区的大小

//
// IFS Kit中存档的函数
//

NTSYSAPI  NTSTATUS  NTAPI ZwLoadDriver(IN PUNICODE_STRING DriverServiceName);

NTKERNELAPI VOID  IoRegisterFileSystem(IN OUT PDEVICE_OBJECT DeviceObject);
NTKERNELAPI VOID  IoUnregisterFileSystem(IN OUT PDEVICE_OBJECT DeviceObject);

//
// 全局变量
//

static PDRIVER_OBJECT RecognizerDriverObject;
static PDEVICE_OBJECT RecognizerDeviceObject;
static VOID Unload(PDRIVER_OBJECT);
static NTSTATUS RecognizerFsControl(PDEVICE_OBJECT, PIRP);
static NTSTATUS RecognizerDetectFileSystem(PIRP Irp);
static NTSTATUS RecognizerIoControl( IN PDEVICE_OBJECT deviceObject,
	IN ULONG IoctlCode,
	IN PVOID InputBuffer,
	IN ULONG InputBufferSize,
	OUT PVOID OutputBuffer,
	OUT ULONG OutputBufferSize);

static BOOLEAN RecognizerReadDiskSector( IN PDEVICE_OBJECT
	pDeviceObject,
	IN ULONG DiskSector,
	IN UCHAR* Buffer);

上面的代码段定义了文件系统识别器需要的变量和外部函数的声明。我们最关心的是IoRegisterFileSystem(), IoUnregisterFileSystem(), 和 ZwLoadDriver().识别调用IoRegisterFileSystem向IO管理器把自己注册成为文件系统驱动程序。这意味着IO管理器将在新卷被装配时调用此识别器。一旦识别器加载了整个文件系统驱动程序,它可以调用IoUnregisterFileSystem告诉IO管理器当新卷在装配过程中,不要调用识别器。加载文件系统驱动程序的函数是ZwLoadDriver.

(编辑:aniston)

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089