⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbcode.cpp

📁 Windows+CE下USB摄像头驱动开发,使用EVC开发。摄像头为 网眼 Webeye 2000 VID 0x05A9 PID 0xA511 输出格式:RAW-YUV
💻 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 + -