資料介紹
有兩種方式可以讓設(shè)備和應(yīng)用程序之間聯(lián)系:
1.?通過為設(shè)備創(chuàng)建的一個符號鏈;
2.?通過輸出到一個接口
WDM驅(qū)動程序建議使用輸出到一個接口而不推薦使用創(chuàng)建符號鏈的方法。這個接口保證PDO的安全,也保證安全地創(chuàng)建一個惟一的、獨立于語言的訪問設(shè)備的方法。
一個應(yīng)用程序使用Win32APIs來調(diào)用設(shè)備。在某個Win32 APIs和設(shè)備對象的分發(fā)函數(shù)之間存在一個映射關(guān)系。
獲得對設(shè)備對象訪問的第一步就是打開一個設(shè)備對象的句柄。
用符號鏈打開一個設(shè)備的句柄
為了打開一個設(shè)備,應(yīng)用程序需要使用CreateFile。如果該設(shè)備有一個符號鏈出口,應(yīng)用程序可以用下面這個例子的形式打開句柄:
hDevice = CreateFile("\\\\.\\OMNIPORT3",
? GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,
? NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL ,NULL
);
文件路徑名的前綴“\\.\”告訴系統(tǒng)本調(diào)用希望打開一個設(shè)備。這個設(shè)備必須有一個符號鏈,以便應(yīng)用程序能夠打開它。有關(guān)細(xì)節(jié)查看有關(guān)Kdevice和CreateLink的內(nèi)容。在上述調(diào)用中第一個參數(shù)中前綴后的部分就是這個符號鏈的名字。
注意:CreatFile中的第一個參數(shù)不是Windows 98/2000中驅(qū)動程序(.sys文件)的路徑。是到設(shè)備對象的符號鏈。
如果使用DriverWizard產(chǎn)生驅(qū)動程序,它通常使用類KunitizedName來構(gòu)成設(shè)備的符號鏈。這意味著符號鏈名有一個附加的數(shù)字,通常是0。例如:如果鏈接名稱的主干是L“TestDevice”那么在CreateFile中的串就該是“\\\\.\\TestDevice0”。
如果應(yīng)用程序需要被覆蓋的I/O,第六個參數(shù)(Flags)必須或上FILE_FLAG_OVERLAPPED。
使用一個輸出接口打開句柄
用這種方式打開一個句柄會稍微麻煩一些。DriverWorks庫提供兩個助手類來使獲得對該接口的訪問容易一些,這兩個類是CDeviceInterface, 和 CdeviceInterfaceClass。
CdeviceInterfaceClass類封裝了一個設(shè)備信息集,該信息集包含了特殊類中的所有設(shè)備接口信息。
應(yīng)用程序能有用CdeviceInterfaceClass類的一個實例來獲得一個或更多的CdeviceInterface類的實例。CdeviceInterface類是一個單一設(shè)備接口的抽象。它的成員函數(shù)DevicePath()返回一個路徑名的指針,該指針可以在CreateFile中使用來打開設(shè)備。
下面用一個小例子來顯示這些類最基本的使用方法:
extern GUID TestGuid;
HANDLE OpenByInterface(
? GUID* pClassGuid,
? DWORD instance,
? PDWORD pError
)
{
? CDeviceInterfaceClass DevClass(pClassGuid, pError);
? if (*pError != ERROR_SUCCESS)
??? return INVALID_HANDLE_VALUE;
? CDeviceInterface DevInterface(&DevClass, instance, pError);
? if (*pError != ERROR_SUCCESS)
??? return INVALID_HANDLE_VALUE;
? cout << "The device path is "
??? << DevInterface.DevicePath()
??? << endl;
? HANDLE hDev;
? hDev = CreateFile(
?? DevInterface.DevicePath(),
??? GENERIC_READ | GENERIC_WRITE,
??? FILE_SHARE_READ | FILE_SHARE_WRITE,
??? NULL,
??? OPEN_EXISTING,
??? FILE_ATTRIBUTE_NORMAL,
??? NULL
? );
? if (hDev == INVALID_HANDLE_VALUE)
??? *pError = GetLastError();
? return hDev;
}
在設(shè)備中執(zhí)行I/O操作
一旦應(yīng)用程序獲得一個有效的設(shè)備句柄,它就能使用Win32 APIs來產(chǎn)生到設(shè)備對象的IRPs。下面的表顯示了這種對應(yīng)關(guān)系。
Win32 API ?DRIVER_FUNCTION_xxx
IRP_MJ_xxx ?KDevice subclass member function
CreateFile ?CREATE ?Create
ReadFile ?READ ?Read
WriteFile ?WRITE ?Write
DeviceIoControl ?DEVICE_CONTROL ?DeviceControl
CloseHandle ?CLOSE
CLEANUP ?Close
CleanUp
需要解釋一下設(shè)備類成員的Close和CleanUp:CreateFile使內(nèi)核為設(shè)備創(chuàng)建一個新的文件對象。這使得多個句柄可以映射同一個文件對象。當(dāng)這個文件對象的最后一個用戶級句柄被撤銷后,I/O管理器調(diào)用CleanUp。當(dāng)沒有任何用戶級和核心級的對文件對象的訪問的時候,I/O管理器調(diào)用Close。
如果被打開的設(shè)備不支持指定的功能,則調(diào)用相應(yīng)的Win32將引起錯誤(無效功能)。
以前為Windows95編寫的VxD的應(yīng)用程序代碼中可能會在打開設(shè)備的時候使用FILE_FLAG_DELETE_ON_CLOSE屬性。在Windows NT/2000中,建議不要使用這個屬性,因為它將導(dǎo)致沒有特權(quán)的用戶企圖打開這個設(shè)備,這是不可能成功的。
I/O管理器將ReadFile和WriteFile的buff參數(shù)轉(zhuǎn)換成IRP域的方法依賴于設(shè)備對象的屬性。當(dāng)設(shè)備設(shè)置DO_DIRECT_IO標(biāo)志,I/O管理器將buff鎖住在存儲器中,并且創(chuàng)建了一個存儲在IRP中的MDL域。一個設(shè)備可以通過調(diào)用Kirp::Mdl來存取MDL。
當(dāng)設(shè)備設(shè)置DO_BUFFERED_IO標(biāo)志,設(shè)備對象分別通過KIrp::BufferedReadDest或 KIrp::BufferedWriteSource為讀或?qū)懖僮鳙@得buff地址。
當(dāng)設(shè)備不設(shè)置DO_BUFFERED_IO標(biāo)志也不設(shè)置DO_DIRECT_IO,內(nèi)核設(shè)置IRP 的UserBuffer域來對應(yīng)ReadFile或WriteFile中的buff參數(shù)。然而,存儲區(qū)并沒有被鎖住而且地址只對調(diào)用進(jìn)程有效。驅(qū)動程序可以使用KIrp::UserBuffer來存取IRP域。
對于DeviceIoControl調(diào)用,buffer參數(shù)的轉(zhuǎn)換依賴于特殊的I/O控制代碼,它不在設(shè)備對象的特性中。宏CTL_CODE(在winioctl.h中定義)用來構(gòu)造控制代碼。這個宏的其中一個參數(shù)指明緩沖方法是METHOD_BUFFERED, METHOD_IN_DIRECT, METHOD_OUT_DIRECT, 或METHOD_NEITHER。下面的表顯示了這些方法和與之對應(yīng)的能獲得輸入緩沖與輸出緩沖的KIrp中的成員函數(shù):
Method ?Input Buffer Parameter ?Output Buffer Parameter
METHOD_BUFFERED ?KIrp::IoctlBuffer
KIrp::IoctlBuffer
METHOD_IN_DIRECT ?KIrp::IoctlBuffer
KIrp::Mdl
METHOD_OUT_DIRECT ?KIrp::IoctlBuffer
KIrp::Mdl
METHOD_NEITHER ?KIrp::IoctlType3InputBuffer
KIrp::UserBuffer
如果控制代碼指明METHOD_BUFFERED,系統(tǒng)分配一個單一的緩沖來作為輸入與輸出。驅(qū)動程序必須在向輸出緩沖放數(shù)據(jù)之前拷貝輸入數(shù)據(jù)。驅(qū)動程序通過調(diào)用KIrp::IoctlBuffer獲得緩沖地址。在完成時,I/O管理器從系統(tǒng)緩沖拷貝數(shù)據(jù)到提供給Ring 3級調(diào)用者使用的緩沖中。驅(qū)動程序必須在結(jié)束前存儲拷貝到IRP的Information成員中的數(shù)據(jù)個數(shù)。
如果控制代碼不指明METHOD_IN_DIRECT或METHOD_OUT_DIRECT,則DeviceIoControl的參數(shù)呈現(xiàn)不同的含義。參數(shù)InputBuffer被拷貝到一個系統(tǒng)緩沖,這個緩沖驅(qū)動程序可以通過調(diào)用KIrp::IoctlBuffer。參數(shù)OutputBuffer被映射到KMemory對象,驅(qū)動程序?qū)@個對象的訪問通過調(diào)用KIrp::Mdl來實現(xiàn)。對于METHOD_OUT_DIRECT,調(diào)用者必須有對緩沖的寫訪問權(quán)限。
注意,對METHOD_NEITHER,內(nèi)核只提供虛擬地址;它不會做映射來配置緩沖。虛擬地址只對調(diào)用進(jìn)程有效。
這里是一個用METHOD_BUFFERED的例子:
首先,使用宏CTL_CODE來定義一個IOCTL代碼:
#define IOCTL_MYDEV_GET_FIRMWARE_REV \
CTL_CODE (FILE_DEVICE_UNKNOWN,0,METHOD_BUFFERED,FILE_ANY_ACCESS)
現(xiàn)在使用一個DeviceIoControl調(diào)用:
BOOLEAN b;
CHAR FirmwareRev[60];
ULONG FirmwareRevSize;
b = DeviceIoControl(hDevice, IOCTL_MYDEV_GET_VERSION_STRING,
? NULL, // no input? 注意,這里放的是包含有執(zhí)行操作命令的字符串指針
? 0,
FirmwareRev,????? //這里是output串指針,存放從驅(qū)動程序中返回的字符串。
sizeof(FirmwareRev),& FirmwareRevSize,
? NULL // not overlapped I/O
?);
如果輸出緩沖足夠大,設(shè)備拷貝串到里面并將拷貝的資結(jié)束設(shè)置到FirmwareRevSize中。
在驅(qū)動程序中,代碼看起來如下所示:
const char* FIRMWARE_REV = "FW 16.33 v5";
NTSTATUS MyDevice::DeviceControl( KIrp I )
{
? ULONG fwLength=0;
? switch ( I.IoctlCode() )
? {
??? case IOCTL_MYDEV_GET_FIRMWARE_REV:
????? fwLength = strlen(FIRMWARE_REV)+1;
????? if (I.IoctlOutputBufferSize() >= fwLength)
????? {
??????? strcpy((PCHAR)I.IoctlBuffer(),FIRMWARE_REV);
??????? I.Information() = fwLength;?
??????? return I.Complete(STATUS_SUCCESS);
????? }
????? else
????? {
???????
????? }
??? case . . .
?? }
?}
- OneInstall Windows驅(qū)動程序和應(yīng)用程序工具
- OneInstall Windows驅(qū)動程序和應(yīng)用程序
- OneInstall Windows驅(qū)動程序和應(yīng)用程序工具包分享
- OneInstall Windows驅(qū)動程序和應(yīng)用程序工具包
- STM32的ADC驅(qū)動程序
- USB驅(qū)動程序
- CP210x Windows驅(qū)動程序應(yīng)用程序軟件免費下載 17次下載
- USB和UART驅(qū)動程序CP2102應(yīng)用程序免費下載 39次下載
- Keil C51的鏈接驅(qū)動程序應(yīng)用程序免費下載 5次下載
- USB下載口驅(qū)動程序CH340應(yīng)用程序免費下載 38次下載
- CDM20600驅(qū)動程序,USB驅(qū)動程序和并口驅(qū)動應(yīng)用程序(免費下載) 57次下載
- Linux字符設(shè)備驅(qū)動程序的實現(xiàn) 0次下載
- Windows CENET環(huán)境下的流接口驅(qū)動程序開發(fā) 3次下載
- USB接口驅(qū)動程序開發(fā)
- Windows CE下GPIO驅(qū)動程序的設(shè)計與應(yīng)用
- 怎么編寫Framebuffer驅(qū)動程序 402次閱讀
- 了解和使用無操作系統(tǒng)和平臺驅(qū)動程序 1066次閱讀
- NDIS小端口驅(qū)動程序實現(xiàn)的關(guān)鍵技術(shù)和應(yīng)用研究 2214次閱讀
- DS18B20的C語言驅(qū)動程序 5345次閱讀
- 米爾科技LINUX設(shè)備驅(qū)動程序教程 1965次閱讀
- 嵌入式Linux內(nèi)核的驅(qū)動程序開發(fā)是怎樣的 1415次閱讀
- 淺談電腦驅(qū)動程序的工作原理 詳解電腦驅(qū)動程序意義 2.9w次閱讀
- 基于Linux2.6.30開發(fā)DS18B20的驅(qū)動程序的類型和文件操作接口函數(shù)詳解 1377次閱讀
- 可動態(tài)安裝的Linux設(shè)備驅(qū)動程序 955次閱讀
- 8255A驅(qū)動程序 3192次閱讀
- 8155驅(qū)動程序 3057次閱讀
- 深入了解USB驅(qū)動之總線驅(qū)動程序 8685次閱讀
- 什么是應(yīng)用程序接口_應(yīng)用程序接口有什么作用 1.4w次閱讀
- Xilinx設(shè)備的驅(qū)動程序 7964次閱讀
- PCI驅(qū)動程序開發(fā)實例 6701次閱讀
下載排行
本周
- 1TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 2開關(guān)電源基礎(chǔ)知識
- 5.73 MB | 6次下載 | 免費
- 3100W短波放大電路圖
- 0.05 MB | 4次下載 | 3 積分
- 4嵌入式linux-聊天程序設(shè)計
- 0.60 MB | 3次下載 | 免費
- 5基于FPGA的光纖通信系統(tǒng)的設(shè)計與實現(xiàn)
- 0.61 MB | 2次下載 | 免費
- 651單片機(jī)窗簾控制器仿真程序
- 1.93 MB | 2次下載 | 免費
- 751單片機(jī)大棚環(huán)境控制器仿真程序
- 1.10 MB | 2次下載 | 免費
- 8基于51單片機(jī)的RGB調(diào)色燈程序仿真
- 0.86 MB | 2次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33564次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關(guān)電源設(shè)計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅(qū)動電路設(shè)計》 溫德爾著
- 0.00 MB | 6653次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537796次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420026次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191185次下載 | 免費
- 7十天學(xué)會AVR單片機(jī)與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多