deviceiocontrol這個api我們用的不多,但是很重要,有時會幫助我們實現一些特別的需求, 如獲取硬體裝置資訊、與硬體裝置通訊(讀寫資料)等,對照msdn,下面我們詳細解釋一下這個api的用法(有什麼錯誤再所難免,各位不吝指教啊)。
deviceiocontrol是用來控制我們指定裝置的輸入輸出操作,使裝置按照我們發的指令去工作。
deviceiocontrol是kernel32中的函式,需要包含的標頭檔案是winbase.h,先看函式原型
bool deviceiocontrol(哈哈,引數不少,而且還都很抽象,沒關係,我們乙個乙個擊破它handle
hdevice,
dworddwiocontrolcode
,
lpvoidlpinbuffer
,
dwordninbuffersize
,
lpvoidlpoutbuffer
,
dwordnoutbuffersize
,
lpdwordlpbytesreturned
,
);
來到第乙個引數,hdevice,當然是要操作的裝置的控制代碼了,這個控制代碼需要通過createfile的返回值中獲取,對於createfile這裡只做乙個粗略的解釋:
引數:要開啟的檔名,訪問許可權,共享模式,安全屬性,檔案存在與不存在時的檔案建立模式,檔案屬性設定(隱藏、唯讀、壓縮、指定為系統檔案等),檔案副本控制代碼。要說明的是第乙個引數lpfilename,是裝置的名稱或者是和裝置關連的驅動的名稱,一般用\\.\devicename的形式,比如要開啟邏輯驅動盤a就用\\.\a,也可以用\\.\physicaldevice0,\\.\phsycaldebive1來指定物理驅動器,\\.\physicaldevice0表示本機的物理驅動器0(一般是主硬碟),從而來獲取硬碟的序列號、模組名、扇區數、磁頭數等相關資訊
搞定hdevice!
dwiocontrolcode
: 當然就是控制裝置的指令了,指令怎麼來是個問題,微軟已經定義好了很多種操作,在winioctl.h檔案中,但最終都是通過ctl_code巨集來實現的,其實這就是一種通訊協議。ctl_code的具體用法在最後來介紹。
lpinbuffer
: 裝置操控請求資料的緩衝區基址,如果dwiocontrolcode 指定了乙個操作,該操作不需要輸入資料,那麼這個引數設為null
ninbuffersize
:lplnbuffer的size
lpoutbuffer
:存放輸出資料的buffer,同樣,如果dwiocontrolcode 指定了乙個操作,該操作不需要處理輸出資料,那麼這個引數設為null
noutbuffersize
:haha,別說你不知道什麼什麼意思,pass
lpbytesreturned
:實際輸出資料的bytes
:ignored; set to null.(are you understand?)
下面來到第二個引數的詳解,ctl_code的定義與應用:
ctl_code原型:
#define ctl_code(devicetype可以看到,這個巨集四個引數,自然是乙個32位分成了4部分,高16位儲存裝置型別( 這裡不列舉了,看msdn哦),14~15位訪問許可權,2~13位操作功能,最後乙個就是確定緩衝區(別忘記上面deviceiocontrol中緩衝區的定義哦)是如何與i/o和檔案系統資料緩衝區進行資料傳遞的方式(具體取值檢視msdn)我們最常用的就是method_buffered, function
, method
, access
) (
((devicetype
) << 16) | ((access
) << 14) | ((function
) << 2) | (method
)
)
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!
關於DeviceIoControl實現非同步的筆記
鏈結位址 一直所做的都是同步實現的。當然很多情況這並不是很好的解決問題。現在手上的問題是 使用者層通知底層驅動 filter driver 做某件事,然後返回該事件執行的結果。如果該事件是一件簡單的事情,這裡是指極短時間內可以完成的,那麼在允許範圍內,我們可以用同步來完成。但是如果該事件是一件耗時的...
通過DeviceIoControl獲取真實網絡卡位址
我們可以通過deviceiocontrol介面與核心驅動通訊來獲取真實網絡卡以及當前網絡卡的位址。首先包含標頭檔案 include 網絡卡標識,xp下可以在登錄檔下對應位置找到,本例 hkey local machine software microsoft windows nt currentve...
DeviceIOControl具體解釋 各個擊破
deviceiocontrol這個api我們用的不多,可是非常重要,有時會幫助我們實現一些特別的需求,如獲取硬體裝置資訊 與硬體裝置通訊 讀寫資料 等,對比msdn,以下我們詳解一下這個api的使用方法 有什麼錯誤再所難免,各位不吝不吝賜教啊 deviceiocontrol是用來控制我們指定裝置的輸...