首先,必须输出USBD要求调用的三个函数,首先到设备插入到USB端口时,USBD会调用USBDeviceAttach()函数,相应的代码如下:
extern"C"BOOL
USBDeviceAttach(
USB_HANDLEhDevice,//USB设备句柄
LPCUSB_FUNCSlpUsbFuncs,//USBDI的函数集合
LPCUSB_INTERFACElPINterface,//设备接口描述信息
LPCWSTRszUniqueDriverId,//设备ID描述字符串。
LPBOOLfACCePTControl,//返回TRUE,标识我们可以控制此设备,反之表示不能控制
DWORDdwUnused)
{
*fAccePTControl=FALSE;
//我们的鼠标设备有特定的描述信息,要检测是否是我们的设备。
if(lpInterface==NULL)
returnFALSE;
//打印相关的USB设备接口描述信息。
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse:DeviceAttach,IF%u,#EP:%u,Class:%u,Sub:%u,Prot:%urn"),lpInterface->Descriptor.bInterfaceNumber,lpInterface->Descriptor.bNumEndpoints,lpInterface->Descriptor.bInterfaceClass,lpInterface->Descriptor.bInterfaceSubClass,lpInterface->Descriptor.bInterfaceProtocol));
//初试数据USB鼠标类,产生一个接受USB鼠标数据的线程
CMouse*pMouse=newCMouse(hDevice,lpUsbFuncs,lpInterface);
if(pMouse==NULL)
returnFALSE;
if(!pMouse->Initialize())
{
deletepMouse;
returnFALSE;
}
//注册一个监控USB设备事件的回调函数,用于监控USB设备是否已经拔掉。
(*lpUsbFuncs->lpRegisterNotificationRoutine)(hDevice,
USBDeviceNotifications,pMouse);
*fAcceptControl=TRUE;
returnTRUE;
}
第二个函数是USBInstallDriver()函数,
一些基本定义如下:
constWCHARgcszRegisterClientDriverId[]=L"RegisterClientDriverID";
constWCHARgcszRegisterClientSettings[]=L"RegisterClientSettings";
constWCHARgcszUnRegisterClientDriverId[]=L"UnRegisterClientDriverID";
constWCHARgcszUnRegisterClientSettings[]=L"UnRegisterClientSettings";
constWCHARgcszMouseDriverId[]=L"Generic_Sample_Mouse_Driver";
函数接口如下:
extern"C"BOOL
USBInstallDriver(
LPCWSTRszDriverLibFile)//@parm[IN]-ContainsclientdriverDLLname
{
BOOLfRet=FALSE;
HINSTANCEhInst=LoadLibrary(L"USBD.DLL");
//注册USB设备信息
if(hInst)
{
LPREGISTER_CLIENT_DRIVER_IDpRegisterId=(LPREGISTER_CLIENT_DRIVER_ID)
GetProcAddress(hInst,gcszRegisterClientDriverId);
LPREGISTER_CLIENT_SETTINGSpRegisterSettings=
(LPREGISTER_CLIENT_SETTINGS)GetProcAddress(hInst,
gcszRegisterClientSettings);
if(pRegisterId&&pRegisterSettings)
{
USB_DRIVER_SETTINGSDriverSettings;
DriverSettings.dwCount=sizeof(DriverSettings);
//设置我们的特定的信息。
DriverSettings.dwVendorId=USB_NO_INFO;
DriverSettings.dwProductId=USB_NO_INFO;
DriverSettings.dwReleaseNumber=USB_NO_INFO;
DriverSettings.dwDeviceClass=USB_NO_INFO;
DriverSettings.dwDeviceSubClass=USB_NO_INFO;
DriverSettings.dwDeviceProtocol=USB_NO_INFO;
DriverSettings.dwInterfaceClass=0x03;//HID
DriverSettings.dwInterfaceSubClass=0x01;//bootdevice
DriverSettings.dwInterfaceProtocol=0x02;//mouse
fRet=(*pRegisterId)(gcszMouseDriverId);
if(fRet)
{
fRet=(*pRegisterSettings)(szDriverLibFile,
gcszMouseDriverId,NULL,&DriverSettings);
if(!fRet)
{
//BUGBUGunregistertheClientDriver’sID
}
}
}
else
{
RETAILMSG(1,(TEXT("!USBMouse:ErrorgettingUSBDfunctionpointersrn")));
}
FreeLibrary(hInst);
}
returnfRet;
}
上述代码主要用于产生USB设备驱动程序需要的注册表信息,需要注意的是:USB设备驱动程序不使用标准的注册表函数,而是使用RegisterClientDriverID()和RegisterClientSettings来注册相应的设备信息。
另外一个函数是USBUninstallDriver()函数,具体代码如下:
extern"C"BOOL
USBUnInstallDriver()
{
BOOLfRet=FALSE;
HINSTANCEhInst=LoadLibrary(L"USBD.DLL");
if(hInst)
{
LPUN_REGISTER_CLIENT_DRIVER_IDpUnRegisterId=
(LPUN_REGISTER_CLIENT_DRIVER_ID)
GetProcAddress(hInst,gcszUnRegisterClientDriverId);
LPUN_REGISTER_CLIENT_SETTINGSpUnRegisterSettings=
(LPUN_REGISTER_CLIENT_SETTINGS)GetProcAddress(hInst,
gcszUnRegisterClientSettings);
if(pUnRegisterSettings)
{
USB_DRIVER_SETTINGSDriverSettings;
DriverSettings.dwCount=sizeof(DriverSettings);
//必须填入与注册时相同的信息。
DriverSettings.dwVendorId=USB_NO_INFO;
DriverSettings.dwProductId=USB_NO_INFO;
DriverSettings.dwReleaseNumber=USB_NO_INFO;
DriverSettings.dwDeviceClass=USB_NO_INFO;
DriverSettings.dwDeviceSubClass=USB_NO_INFO;
DriverSettings.dwDeviceProtocol=USB_NO_INFO;
DriverSettings.dwInterfaceClass=0x03;//HID
DriverSettings.dwInterfaceSubClass=0x01;//bootdevice
DriverSettings.dwInterfaceProtocol=0x02;//mouse
fRet=(*pUnRegisterSettings)(gcszMouseDriverId,NULL,
&DriverSettings);
}
if(pUnRegisterId)
{
BOOLfRetTemp=(*pUnRegisterId)(gcszMouseDriverId);
fRet=fRet?fRetTemp:fRet;
}
FreeLibrary(hInst);
}
returnfRet;
}
此函数主要用于删除USBInstallDriver()时创建的注册表信息,同样的它使用自己的函数接口UnRegisterClientDriverID()和UnRegisterClientSettings()来做相应的处理。
另外一个需要处理的注册的监控通知函数USBDevICeNotifications():
extern"C"BOOLUSBDeviceNotifications(LPVOIDlpvNotifyParameter,DWORDdwCode,
LPDWORD*dwInfo1,LPDWORD*dwInfo2,LPDWORD*dwInfo3,
LPDWORD*dwInfo4)
{
CMouse*pMouse=(CMouse*)lpvNotifyParameter;
switch(dwCode)
{
caseUSB_CLOSE_DEVICE:
//删除相关的资源。
deletepMouse;
returnTRUE;
}
returnFALSE;
}
USB鼠标的类的定义如下:
classCMouse
{
public:
CMouse::CMouse(USB_HANDLEhDevice,LPCUSB_FUNCSlpUsbFuncs,
LPCUSB_INTERFACElPINterface);
~CMouse();
BOOLInitialize();
private:
//传输完毕调用的回调函数
staticDWORDCALLBACKMouseTransferCompleteStub(LPVOIDlpvNotifyParameter);
//中断处理函数
staticULONGCALLBACKCMouse::MouseThreadStub(PVOIDcontext);
DWORDMouseTransferComplete();
DWORDMouseThread();
BOOLSubmitInterrupt();
BOOLHandleInterrupt();
BOOLm_fClosing;
BOOLm_fReadyForMouseEvents;
HANDLEm_hEvent;
HANDLEm_hThread;
USB_HANDLEm_hDevice;
USB_PIPEm_hInterruptPipe;
USB_TRANSFERm_hInterruptTransfer;
LPCUSB_FUNCSm_lpUsbFuncs;
LPCUSB_INTERFACEm_pInterface;
BOOLm_FPrevButton1;
BOOLm_fPrevButton2;
BOOLm_fPrevButton3;
//数据接受缓冲区。
BYTEm_pbDataBuffer[8];
};
具体实现如下:
//构造函数,初始化时调用
CMouse::CMouse(USB_HANDLEhDevice,LPCUSB_FUNCSlpUsbFuncs,
LPCUSB_INTERFACElpInterface)
{
m_fClosing=FALSE;
m_fReadyForMouseEvents=FALSE;
m_hEvent=NULL;
m_hThread=NULL;
m_hDevice=hDevice;
m_hInterruptPipe=NULL;
m_hInterruptTransfer=NULL;
m_lpUsbFuncs=lpUsbFuncs;
m_pInterface=lpInterface;
m_fPrevButton1=FALSE;
m_fPrevButton2=FALSE;
m_fPrevButton3=FALSE;
MEMSet(m_pbDataBuffer,0,sizeof(m_pbDataBuffer));
}
//析构函数,用于清除申请的资源。