📄 usbcode.cpp
字号:
//======================================================================
// USBCode - USB support entry points for driver
//
// Author: MacintoshM
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <USBdi.h> // USB includes
#include <usb100.h> // USB includes
#include "usbclient.h" // USB client driver helper code
#include "Ov511Cam.h" // Local driver includes
#include "USBVideo.h"
//摄像头的PIV,VID
#define VID_OMINIVISION 0x05A9
#define PID_OV511 0x0511
typedef struct {
LPTSTR lpszCamName;
WORD wVendorID;
WORD wProductID;
} USBCAMSTRUCT, *PUSBCAMSTRUCT;
//
// This structure contains the list of vendor specific cameras
// that closely follow the USB Vid Specification even though they
// don't say they do. If your camera works with the driver, you
// can add your camera to this list.
//
USBCAMSTRUCT csCameras[] =
{
{ TEXT("OminiVision Ov511"), VID_OMINIVISION, PID_OV511},
{ TEXT("OminiVision WebEye 2000"), VID_OMINIVISION, 0xA511},
};
//当设备拔出时的提示
BOOL USBDeviceNotificationCallback (LPVOID lpvNotifyParameter, DWORD dwCode,
LPDWORD* dwInfo1, LPDWORD* dwInfo2,
LPDWORD* dwInfo3, LPDWORD* dwInfo4);
//======================================================================
// USBDeviceAttach - Called when Host controller wants to load the driver
//
BOOL USBDeviceAttach (USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId,
LPBOOL fAcceptControl,
LPCUSB_DRIVER_SETTINGS lpDriverSettings, DWORD dwUnused)
{
//在InstallDriver成功后,设备插入时调用
RETAILMSG(1,(TEXT("Device Attached!\r\n")));
WCHAR wsSubClassRegKey[] = CLIENT_REGKEY_SZ;
DWORD dwContext=0;
*fAcceptControl = FALSE;
LPCUSB_DEVICE lpUsbDev = (lpUsbFuncs->lpGetDeviceInfo)(hDevice);
if(!lpUsbDev)
{
//该设备无法使用
RETAILMSG(1,(TEXT("Unable to get USB device!\r\n")));
return FALSE;
}
//查找需要的接口,这里只找视频控制接口
if((DWORD)lpInterface != 0)
{
//显示相关的usb设备接口描述信息。
RETAILMSG(1,(TEXT("USB OV511: Device Attach, Interface %u, #End Points:%u, Class:%u, Sub:%u, Protocal:%u\r\n"),
lpInterface->Descriptor.bInterfaceNumber,
lpInterface->Descriptor.bNumEndpoints,
lpInterface->Descriptor.bInterfaceClass,
lpInterface->Descriptor.bInterfaceSubClass,
lpInterface->Descriptor.bInterfaceProtocol));
if (lpInterface->Descriptor.bInterfaceSubClass == 0x02)
{
*fAcceptControl = TRUE;
return TRUE;
}
}
//查找控制接口和视频传输接口
if (!ParseStreamInterfaces (lpUsbDev, 0x0e, 2, &dwContext))
{
//没有标准接口,继续查找看有无厂商指定的
if (!ParseStreamInterfaces (lpUsbDev, 0xff, 0, &dwContext))
{
return FALSE;
}
}
RETAILMSG(1, (TEXT("Create Driver Context! \r\n")));
//设备信息保存完成,创建驱动程序上下文
PDRVCONTEXT pDrv = (PDRVCONTEXT)LocalAlloc (LPTR, sizeof (DRVCONTEXT));
if (pDrv == 0)
{
RETAILMSG(1, (TEXT("Not enough memory! \r\n")));
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
pDrv->dwSize = sizeof (DRVCONTEXT);
pDrv->hDevice = hDevice;
pDrv->lpUsbFuncs = lpUsbFuncs;
InitializeCriticalSection (&pDrv->csDCall);
pDrv->dwDeviceContext = dwContext;
RETAILMSG(1, (TEXT("Activate Device! \r\n")));
//激活流驱动接口,使应用程序能够以File API的方式来访问
pDrv->hStreamDevice = ActivateDevice (wsSubClassRegKey, (DWORD)pDrv);
if (pDrv->hStreamDevice)
{
// register for USB callbacks
//在设备拔出时由系统回调
if (lpUsbFuncs->lpRegisterNotificationRoutine (hDevice, USBDeviceNotificationCallback, pDrv))
{
// Accept this device as our own
*fAcceptControl = TRUE;
}
else
{
RETAILMSG(1, (TEXT("Can't register for USB Callbacks! rc=%d\r\n"),
GetLastError()));
}
}
else
{
RETAILMSG(1, (TEXT("Can't activate stream device! rc=%d\r\n"),
GetLastError()));
}
RETAILMSG(1,(TEXT("Device Attach Complete!\r\n")));
return TRUE;
}
//======================================================================
// USBDeviceNotificationCallback - This routine is called by the USB
// host controller when a USB event occurs that the driver needs to
// know about.
//
BOOL USBDeviceNotificationCallback (LPVOID lpvNotifyParameter, DWORD dwCode,
LPDWORD* dwInfo1, LPDWORD* dwInfo2,
LPDWORD* dwInfo3, LPDWORD* dwInfo4)
{
if (dwCode == USB_CLOSE_DEVICE)
{
//清理占用的资源
RETAILMSG(1,(TEXT("Free Driver Resources!\r\n")));
//取得驱动程序指针
PDRVCONTEXT pDrv = (PDRVCONTEXT) lpvNotifyParameter;
//先释放设备上下文
PDEVICECONTEXT pPDD = (PDEVICECONTEXT)pDrv->dwDeviceContext;
LocalFree(pPDD->usbVideoIF);
LocalFree(pPDD);
//再释放驱动程序
LocalFree(pDrv);
return TRUE;
}
return FALSE;
}
//======================================================================
// USBInstallDriver - Called by Host controller to have the driver
// register itself. This call is made in response to the user
// entering the driver's DLL name in the "Unknown Device" message box.
//
BOOL USBInstallDriver (LPCWSTR szDriverLibFile)
{
WCHAR wsUsbDeviceID[] = CLASS_NAME_SZ;
WCHAR wsSubClassRegKey[] = CLIENT_REGKEY_SZ;
USB_DRIVER_SETTINGS usbDriverSettings = { DRIVER_SETTINGS };
BOOL bSuccess;
LPREGISTER_CLIENT_DRIVER_ID lpfnRegisterClientDriverID;
LPREGISTER_CLIENT_SETTINGS lpfnRegisterClientSettings;
RETAILMSG(1, (TEXT("USBInstallDriver++\r\n")));
HINSTANCE hUSBD = LoadLibrary (TEXT("usbd.dll"));
if (hUSBD == 0)
{
RETAILMSG(1, (TEXT("Can't load USBD.DLL\r\n")));
return FALSE;
}
//连接USBD DLL.
lpfnRegisterClientDriverID = (LPREGISTER_CLIENT_DRIVER_ID) GetProcAddress (hUSBD, TEXT("RegisterClientDriverID"));
lpfnRegisterClientSettings = (LPREGISTER_CLIENT_SETTINGS) GetProcAddress (hUSBD, TEXT("RegisterClientSettings"));
if ((lpfnRegisterClientDriverID == 0) || (lpfnRegisterClientSettings == 0))
{
FreeLibrary (hUSBD);
return FALSE;
}
//
//使用USBD注册
//
bSuccess = (lpfnRegisterClientDriverID) (wsUsbDeviceID);
if (!bSuccess)
{
RETAILMSG(1, (TEXT("RegisterClientDriverID error:%d\n"), GetLastError()));
FreeLibrary (hUSBD);
return FALSE;
}
//
// 注册USB Client设备
//
bSuccess = (lpfnRegisterClientSettings) (szDriverLibFile, wsUsbDeviceID,
NULL, &usbDriverSettings);
if (!bSuccess)
{
RETAILMSG(1, (TEXT("RegisterClientSettings error:%d\n"), GetLastError()));
FreeLibrary (hUSBD);
return FALSE;
}
//
// Now add the vendor specific entries
// 增加厂商记录
//
usbDriverSettings.dwInterfaceClass = USB_NO_INFO; // Remove the Video class specifier
for (int i = 0; i < dim (csCameras); i++)
{
usbDriverSettings.dwVendorId = csCameras[i].wVendorID;
usbDriverSettings.dwProductId = csCameras[i].wProductID;
// Call USBD to create registry entries for this specific product
// 使用USBD建立厂商和产品指定的注册表项
bSuccess = (lpfnRegisterClientSettings) (szDriverLibFile, wsUsbDeviceID,
NULL, &usbDriverSettings);
if (!bSuccess)
{
RETAILMSG(1, (TEXT("RegisterClientSettings1 error:%d\n"), GetLastError()));
FreeLibrary (hUSBD);
return FALSE;
}
}
//
// The USB host controller driver has a utility function to make it
// simple to create (and later query) the proper registery entries
// for loading a stream driver. First, we create a table of registry
//values we want to set.
//
REG_VALUE_DESCR usbCamKeyValues[] = {
(TEXT("Dll")), REG_SZ, 0, (PBYTE)(DRIVER_NAME),
(TEXT("Prefix")), REG_SZ, 0, (PBYTE)(DEVICE_PREFIX),
NULL, 0, 0, NULL
};
// Set the default in the registry values. This routine is in the
// USBClient library that we link to.
bSuccess = GetSetKeyValues (wsSubClassRegKey, usbCamKeyValues, SET, TRUE );
if (!bSuccess)
{
RETAILMSG(1, (TEXT("GetSetKeyValues failed!\n")));
FreeLibrary (hUSBD);
return FALSE;
}
FreeLibrary (hUSBD);
RETAILMSG(1, (TEXT("USBInstallDriver--\r\n")));
return TRUE;
}
//======================================================================
// USBUnInstallDriver - Called to have the USB client clean up its
// registry entries.
//
BOOL USBUnInstallDriver()
{
WCHAR wsUsbDeviceID[] = CLASS_NAME_SZ;
USB_DRIVER_SETTINGS usbDriverSettings = { DRIVER_SETTINGS };
LPUN_REGISTER_CLIENT_SETTINGS lpfnUnRegisterClientSettings;
BOOL bSuccess = FALSE;
RETAILMSG(1, (TEXT("USBUnInstallDriver++\r\n")));
// Explicitly link to USBD DLL.
HINSTANCE hUSBD = LoadLibrary (TEXT("usbd.dll"));
if (hUSBD == 0)
{
RETAILMSG(1, (TEXT("Can't load USBD.DLL\r\n")));
return FALSE;
}
lpfnUnRegisterClientSettings = (LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress (hUSBD, TEXT("UnRegisterClientSettings"));
// Clean up the registry
// 清理注册记录
if (lpfnUnRegisterClientSettings)
{
bSuccess = (lpfnUnRegisterClientSettings) (wsUsbDeviceID, NULL, &usbDriverSettings);
}
FreeLibrary (hUSBD);
RETAILMSG(1, (TEXT("USBUnInstallDriver--\r\n")));
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -