DeviceIOControl讀寫硬盤設備

DeviceIoControl這個api咱們用的很少,可是很重要,有時會幫助咱們實現一些特別的需求, 如獲取硬件設備信息、與硬件設備通訊(讀寫數據)等,對照msdn,下面咱們詳細解釋一下這個api的用法(有什麼錯誤再所不免,各位不吝指教啊)。
DeviceIoControl是用來控制咱們指定設備的輸入輸出操做,使設備按照咱們發的指令去工做。api

DeviceIoControl是kernel32中的函數,須要包含的頭文件是winbase.h,先看函數原型安全

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
哈哈,參數很多,並且還都很抽象,不要緊,咱們一個一個擊破它markdown

來到第一個參數,hDevice,固然是要操做的設備的句柄了,這個句柄須要經過CreateFile的返回值中獲取,對於createfile這裏只作一個粗略的解釋:app

HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
參數:要打開的文件名,訪問權限,共享模式,安全屬性,文件存在與不存在時的文件建立模式,文件屬性設定(隱藏、只讀、壓縮、指定爲系統文件等),文件副本句柄。要說明的是第一個參數lpFileName,是設備的名稱或者是和設備關連的驅動的名稱,通常用\.\DeviceName的形式,好比要打開邏輯驅動盤A就用\.\a,也能夠用\.\PhysicalDevice0,\.\PhsycalDebive1來指定物理驅動器,\.\PhysicalDevice0表示本機的物理驅動器0(通常是主硬盤),從而來獲取硬盤的序列號、模塊名、扇區數、磁頭數等相關信息函數

搞定hDevice!code

dwIoControlCode: 固然就是控制設備的指令了,指令怎麼來是個問題,微軟已經定義好了不少種操做,在winioctl.h文件中,但最終都是經過CTL_CODE宏來實現的,其實這就是一種通訊協議。CTL_CODE的具體用法在最後來介紹。orm

lpInBuffer: 設備操控請求數據的緩衝區基址,若是dwIoControlCode 指定了一個操做,該操做不須要輸入數據,那麼這個參數設爲NULL接口

nInBufferSize:lplnBuffer的size原型

lpOutBuffer:存放輸出數據的buffer,一樣,若是dwIoControlCode 指定了一個操做,該操做不須要處理輸出數據,那麼這個參數設爲NULLit

nOutBufferSize:haha,別說你不知道什麼什麼意思,pass

lpBytesReturned:實際輸出數據的bytes

lpOverlapped:Ignored; set to NULL.(Are you understand?)

下面來到第二個參數的詳解,CTL_CODE的定義與應用:

CTL_CODE原型:

define CTL_CODE(DeviceType, Function, Method, Access) (

((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
)
能夠看到,這個宏四個參數,天然是一個32位分紅了4部分,高16位存儲設備類型( 這裏不列舉了,看msdn哦),14~15位訪問權限,2~13位操做功能,最後一個就是肯定緩衝區(別忘記上面DeviceIOControl中緩衝區的定義哦)是如何與I/O和文件系統數據緩衝區進行數據傳遞的方式(具體取值查看msdn)咱們最經常使用的就是METHOD_BUFFERED

Function codes 0-2047 are reserved for Microsoft; codes 2048-4095 are reserved for OEMs and IHVs. (咱們能用的是2048~4095)

看如下一段:

這個宏常常用來定義IOCTL(I/O控制)和FSCTL(文件系統控制)功能控制代碼,全部的IOCTLs必須經過這種方式定義,以確保這些指令能被Microsoft,以及其餘的硬件廠商通訊接口所識別

The following illustration shows the format of the resulting IOCTL.

援引微軟定義的一個指令:鎖卷

define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)

Game over!

相關文章
相關標籤/搜索