WinCE下所有的驅(qū)動(dòng)都是以DLL的形式,被device.exe進(jìn)程加載的,所以每個(gè)驅(qū)動(dòng)程序中都要實(shí)現(xiàn)DllEntry函數(shù)。
在注冊(cè)表的HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\鍵下保存了USB Host的驅(qū)動(dòng)程序信息。當(dāng)我們第一次插入U(xiǎn)SB設(shè)備時(shí)。因?yàn)椴淮嬖谶@樣的信息,所以系統(tǒng)會(huì)彈出一個(gè)“
未能識(shí)別的USB設(shè)備”的對(duì)話(huà)框,要求用戶(hù)輸入驅(qū)動(dòng)程序的名稱(chēng)。該名稱(chēng)就是USB Host驅(qū)動(dòng)DLL的文件名。在輸入了名稱(chēng)后,系統(tǒng)會(huì)自動(dòng)調(diào)用該DLL的USBInstallDriver函數(shù)。該函數(shù)
負(fù)責(zé)向注冊(cè)表添加USB Host驅(qū)動(dòng)的信息,以便再次插入設(shè)備時(shí),能夠識(shí)別該USB設(shè)備。其原型如下:
BOOL USBInstallDriver(LPCWSTR szDriverLibFile); 其中szDriverLibFile就是輸入的DLL文件名稱(chēng)。返回TRUE表示注冊(cè)成功。 在向注冊(cè)表注冊(cè)USB Host信息時(shí),不能使用普通的注冊(cè)表函數(shù),只能使用USBD提供的注冊(cè)函數(shù)。 BOOL RegisterClientDriverID(LPCWSTR szUniqueDriverId); BOOL RegisterClientSettings(LPCWSTR szDriverLibFile, LPCWSTR szUniqueDriverId, LPCWSTR erved, LPCUSB_DRIVER_SETTINGS lpDriverSettings); 這兩個(gè)函數(shù)在USBD.DLL中,可以通過(guò)動(dòng)態(tài)方式調(diào)用,也可以通過(guò)靜態(tài)方式調(diào)用。
動(dòng)態(tài)方式如下: HINSTANCE hInst = LoadLibrary(L"USBD.DLL"); if(hInst) { LPREGISTER_CLIENT_DRIVER_ID lpRegisterClientId = (LPREGISTER_CLIENT_DRIVER_ID)GetProcAddress( hInst, L"RegisterClientDriverID"); if(!lpRegisterClientId) return FALSE; LPREGISTER_CLIENT_SETTINGS lpRegisterClientSetting = (LPREGISTER_CLIENT_SETTINGS)GetProcAddress( hInst, L"RegisterClientSettings"); if(!lpRegisterClientSetting) return FALSE; else return FALSE; 此后,就可以通過(guò)lpRegisterClientId和lpRegisterClientSetting函數(shù)指針調(diào)用這些函數(shù),最后記得要FreeLibrary。
靜態(tài)方式: 在.cpp源文件中加入 #pragma comment(lib,"usbd.lib") 并在source文件的TARGETLIBS變量中加入$(_SYSGENOAKROOT)\lib\$(_CPUINDPATH)\usbd.lib 如此一來(lái),就可以直接使用這兩個(gè)函數(shù)了。
1) BOOL RegisterClientDriverID(LPCWSTR szUniqueDriverId) 該函數(shù)注冊(cè)USB Host驅(qū)動(dòng)程序的ID。 2) BOOL RegisterClientSettings(LPCWSTR szDriverLibFile, LPCWSTR szUniqueDriverId, LPCWSTR erved, LPCUSB_DRIVER_SETTINGS lpDriverSettings) 該函數(shù)負(fù)責(zé)注冊(cè)驅(qū)動(dòng)程序的信息。 szDriverLibFile 設(shè)置為USBInstallDriver函數(shù)傳入的DLL驅(qū)動(dòng)程序名稱(chēng)。 szUniqueDriverId 設(shè)置為調(diào)用RegisterClientDriverID注冊(cè)的驅(qū)動(dòng)程序ID。 erved 設(shè)置為NULL lpDriverSettings 該參數(shù)是一個(gè)USB_DRIVER_SETTINGS結(jié)構(gòu)體。其聲明如下: typedef struct { DWORD dwCount; DWORD dwVendorId; DWORD dwProductId; DWORD dwReleaseNumber; DWORD dwDeviceClass; DWORD dwDeviceSubClass; DWORD dwDeviceProtocol; DWORD dwInterfaceClass; DWORD dwInterfaceSubClass; DWORD dwInterfaceProtocol; } USB_DRIVER_SETTINGS; Count為結(jié)構(gòu)體大小,其他項(xiàng)對(duì)應(yīng)USB描述符。 其中除Count外的各字段,如果不設(shè)置具體的值,可以設(shè)置為USB_NO_INFO。 這個(gè)結(jié)構(gòu)體中的信息講反應(yīng)到注冊(cè)表的HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\鍵下,用于在USB設(shè)備插入時(shí),查找USB驅(qū)動(dòng)。下面以一個(gè)例子說(shuō)明: BOOL USBInstallDriver(LPCWSTR szDriverLibFile) { RETAILMSG(1,(TEXT("USBInstallDriver\r\n"))); RETAILMSG(1,(TEXT("USBInstallDriver:%s\r\n"), szDriverLibFile)); BOOL fRet = FALSE; USB_DRIVER_SETTINGS DriverSettings; DriverSettings.dwCount = sizeof(DriverSettings); DriverSettings.dwVendorId = 0x10C4; DriverSettings.dwProductId = 0x0003; DriverSettings.dwReleaseNumber = USB_NO_INFO; DriverSettings.dwDeviceClass = USB_NO_INFO; DriverSettings.dwDeviceSubClass = USB_NO_INFO; DriverSettings.dwDeviceProtocol = USB_NO_INFO; DriverSettings.dwInterfaceClass = 0; DriverSettings.dwInterfaceSubClass = 0; DriverSettings.dwInterfaceProtocol = 0; fRet = RegisterClientDriverID(L"USBTest"); if (fRet) { fRet = RegisterClientSettings( szDriverLibFile, L"USBTest", NULL, &DriverSettings); if(!fRet) RETAILMSG(1,(TEXT("RegisterClientSettings error\r\n"))); } else RETAILMSG(1,(TEXT("RegisterClientDriverID error\r\n")));
return fRet; }
在WinCE中,將設(shè)置信息分為了三組,每組3個(gè)值, 第一組: dwVendorId、dwProductId、dwReleaseNumber 第二組: dwDeviceClass、dwDeviceSubClass、dwDeviceProtocol 第三組: dwInterfaceClass、dwInterfaceSubClass、dwInterfaceProtocol 如果注冊(cè)成功,將會(huì)在HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\鍵下出現(xiàn) “第一組\第二組\第三組\注冊(cè)ID\DLL”這樣的建,鍵值為DLL驅(qū)動(dòng)名稱(chēng)。其中每組又是由三個(gè)值中間加下劃線(xiàn)組成。如果有一個(gè)值設(shè)置為USB_NO_INFO,則鍵名不包括該值。如果整個(gè)組中每個(gè)值都設(shè)置成USB_NO_INFO,則鍵名為Default。
據(jù)上面的例子,在我的系統(tǒng)下,將會(huì)生成如下鍵名: HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\4292_3\Default\0_0_0\USBTest\DLL = "MyUSBTest" (我的驅(qū)動(dòng)程序?yàn)镸yUSBTest.dll) 當(dāng)用戶(hù)插入U(xiǎn)SB設(shè)備時(shí),它會(huì)讀取USB設(shè)備的描述符,根據(jù)描述符中的值在注冊(cè)表中查找驅(qū)動(dòng)程序名稱(chēng)。
現(xiàn)在假設(shè),我們要WinCE只支持USB鍵盤(pán),另外我們自己實(shí)現(xiàn)一個(gè)USB鼠標(biāo)驅(qū)動(dòng)程序。如果不加注意,我們的USB鼠標(biāo)驅(qū)動(dòng)程序?qū)⒉荒鼙徽{(diào)用。原因正是在于這個(gè)查找USB設(shè)備驅(qū)動(dòng)的過(guò)程。WINCE提供的USBHID驅(qū)動(dòng)程序的注冊(cè)表信息是 HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\Default\Default\3\Hid_Class\DLL = "USBHID.DLL"
其中第三組信息只使用了dwInterfaceClass,而USB鍵盤(pán)和USB鼠標(biāo)只有dwInterfaceProtocol不同。所以,一個(gè)3概括了所有的HID,當(dāng)我們的USB鼠標(biāo)插入系統(tǒng)后,將會(huì)調(diào)用USBHID.DLL驅(qū)動(dòng)程序處理,但是它只包括鍵盤(pán)的驅(qū)動(dòng),沒(méi)有鼠標(biāo)的驅(qū)動(dòng),所以鼠標(biāo)不能使用。要想使得自定義的USB鼠標(biāo)可以使用,則將第三組的值都設(shè)置上,如下: HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\Default\Default\3_1_1\Hid_Class\DLL = "USBHID.DLL"
如此一來(lái),當(dāng)值為3_1_2的鼠標(biāo)插入后,因?yàn)檎也坏綄?duì)應(yīng)的鍵值,將提示要求我們輸入U(xiǎn)SB鼠標(biāo)的驅(qū)動(dòng)。
|