【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_
_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的示例驅動基礎上修改。