1. 程式人生 > >【windows核心驅動開發】檔案系統微過濾驅動Minifilter——繫結指定的卷(磁碟分割槽)

【windows核心驅動開發】檔案系統微過濾驅動Minifilter——繫結指定的卷(磁碟分割槽)

【我的】檔案系統微過濾驅動Minifilter——繫結指定的卷(磁碟分割槽)

作者:zcr214 時間:2016/4/21

在編寫檔案系統微過濾驅動minifilter的時候,很有可能我們只對某一個特定的磁碟分割槽感興趣,而其他的如系統盤的很多IRP對於我們要編寫的驅動可能是不關注的,所以有必要使得我們的驅動只繫結指定的這個卷,從而減少其他的IRP帶來的干擾,節省很多處理流程,比如系統盤的很多I/O請求。

1.    InstanceSetup回撥函式

InstanceSetup回撥函式的作用就是來決定是否繫結卷的。它在以下情況被呼叫:

(1)   當minifilter初次載入時,每個已存在的卷都會導致這個呼叫。

(2)   當一個新的卷被掛載時。

(3)   當FltAttachVolume被呼叫(核心模式)時。

(4)   當FltAttachVolumeAtAltitude被呼叫(核心模式)時。

(5)   當FilterAttach被呼叫(使用者模式)時。

(6)   當FilterAttach被呼叫(使用者模式)時。

在這個過程中,minifilter決定是否在這個捲上生成例項。函式原型為:

NTSTATUS

InstanceSetup(

_In_PCFLT_RELATED_OBJECTS FltObjects,

_In_FLT_INSTANCE_SETUP_FLAGS Flags,

_In_

DEVICE_TYPE VolumeDeviceType,

_In_FLT_FILESYSTEM_TYPE VolumeFilesystemType

);

這個回撥函式的返回值為一個NTSTATUS狀態值,表示繫結或者不繫結。

如果確認繫結,則返回STATUS_SUCCESS

如果不繫結,則返回STATUS_FLT_DO_NOT_ATTACH ,或者有警告或者錯誤,返回其他相應的狀態,也是不繫結的。

引數解釋:

(1)_In_PCFLT_RELATED_OBJECTS FltObjects 結構中含有指向minifilter,卷和例項的指標,這個例項是即將在此回撥函式中生成的例項。定義為:

typedefstruct_FLT_RELATED_OBJECTS{

USHORTCONSTSize;

USHORTCONSTTransactionContext;//TxFmini-version

PFLT_FILTERCONSTFilter;

PFLT_VOLUMECONSTVolume;

PFLT_INSTANCECONSTInstance;

PFILE_OBJECTCONSTFileObject;

PKTRANSACTIONCONSTTransaction;

}FLT_RELATED_OBJECTS,*PFLT_RELATED_OBJECTS;

(2)_In_FLT_INSTANCE_SETUP_FLAGS Flags標記是什麼操作導致激發了InstanceSetup這個回撥。

FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT標記是在minifilter註冊時,一個自動的繫結通知,過濾管理器為剛載入的minifilter列舉所有的卷,如果使用者已經明確指定了一個例項繫結到某個卷,則不會設定這個標記。

FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT標記是使用者態呼叫FilterAttach或者FilterAttachAtAltitude,或者核心態呼叫FltAttachVolume時發起的手工請求。

FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME標記是新掛載一個卷時發起的請求。

(3)_In_DEVICE_TYPEVolumeDeviceType引數傳遞卷裝置型別,它是一個ULONG型別,具體定義如下圖

總共有84種之多,針對檔案系統的話一般的值是FILE_DEVICE_DISK_FILE_SYSTEM

(4)_In_FLT_FILESYSTEM_TYPE VolumeFilesystemType 引數傳遞卷檔案系統型別,比如我們熟悉的NTFS,FAT32等等。是一個enum列舉型別,具體定義如下圖

2.    繫結指定卷

繫結指定的卷,首先得確定哪一個卷才是需要繫結的。

利用InstanceSetup回撥函式得到的引數卷裝置型別VolumeDeviceType和卷檔案系統型別VolumeFileSystemType可以篩選出基本的卷型別,做一個初步篩選。

接下來可以呼叫FltGetVolumeProperties函式來獲取卷屬性,基本用法在WDK的示例驅動中均有涉及,如下:

status=FltGetVolumeProperties(FltObjects->Volume,

volProp,

sizeof(volPropBuffer),

&retLen);

返回是否獲取成功的狀態值,volProp即是獲取到的卷屬性,卷屬性定義如下

typedefstruct_FLT_VOLUME_PROPERTIES{

DEVICE_TYPEDeviceType;

ULONGDeviceCharacteristics;

ULONGDeviceObjectFlags;

ULONGAlignmentRequirement;

USHORTSectorSize;

USHORTReserved0;

UNICODE_STRINGFileSystemDriverName;

UNICODE_STRINGFileSystemDeviceName;

UNICODE_STRINGRealDeviceName;

}FLT_VOLUME_PROPERTIES,*PFLT_VOLUME_PROPERTIES;

可以利用卷屬性中的這些資訊鎖定它是否是我們想要繫結的這個卷。

確定繫結卷之後,做完異常處理等,就可以返回STATUS_SUCCESS了,當然,如果不是我們想要繫結的卷,則返回STATUS_FLT_DO_NOT_ATTACH

簡單的舉例,比如在我的虛擬機器win7上,D盤對應的卷名稱是HarddiskVolume3,現在要繫結到D盤,則首先判斷卷裝置型別VolumeDeviceType是8(即FILE_DEVICE_DISK_FILE_SYSTEM),卷檔案系統型別VolumeFileSystemType是2(即NTFS),然後呼叫FltGetVolumeProperties得到卷屬性,取出RealDeviceName判斷是否是\Device\HarddiskVolume3,最後返回STATUS_SUCCESS。就完成了這個驅動對D盤的繫結。當然這個過程中還有一些異常處理等操作。最後在WDK的示例驅動基礎上修改。