📄 webcam.cpp
字号:
//-------------------------------------------------------------------------
// <copyright file="WebCam.cpp" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are covered by the
// Microsoft Limited Permissive License (Ms-LPL)
// http://www.microsoft.com/resources/sharedsource/licensingbasics/limitedpermissivelicense.mspx
// which can be found in the file MS-LPL.txt at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license.
//
// You must not remove this notice, or any other, from this software.
// </copyright>
//
// <summary>
// USB Webcam driver for Windows CE
// </summary>
//-------------------------------------------------------------------------
//======================================================================
// WebCam - USB Webcam driver for Windows CE
//
// Author: Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <winioctl.h> // Needed for CTLCODE macro
#include <USBdi.h> // USB includes
#include <usb100.h> // USB includes
#include "webcamsdk.h" // IOCTL defs for driver
#include "WebCam.h" // Local driver includes
// _WIN32_WINCE
// Globals
//
HINSTANCE hInst; // DLL instance handle
//
// Debug zone support
//
#ifdef DEBUG
// Debug zone structure
DBGPARAM dpCurSettings =
{
TEXT("WebCam"),
{
TEXT("Errors"),TEXT("Warnings"),TEXT("Functions"), TEXT("Init"),
TEXT("Driver Calls"),TEXT("USBLoad"),TEXT("Thread"),TEXT("Frame Info"),
TEXT("Packets"),TEXT("Timing"),TEXT("Read Data"),TEXT("Probe/Commit"),
TEXT("Still Cap"),TEXT("Stream Frames"),TEXT("Feature Ctls"), TEXT("Undefined")
},
// 0x1063
0x0003
};
#endif //DEBUG
//======================================================================
// DllMain - DLL initialization entry point
//
BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason,
LPVOID lpvReserved) {
hInst = (HINSTANCE)hinstDLL;
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER(hInst);
// Improve performance by passing on thread attach calls
DisableThreadLibraryCalls (hInst);
break;
case DLL_PROCESS_DETACH:
DEBUGMSG(ZONE_INIT, (DTAG TEXT("DLL_PROCESS_DETACH\r\n")));
break;
}
return TRUE;
}
//======================================================================
// CAM_Init - Driver initialization function
//
DWORD CAM_Init (DWORD dwContext, LPCVOID lpvBusContext) {
PDRVCONTEXT pDrv;
// Allocate a drive instance structure.
pDrv = GetConfigData (dwContext);
if (pDrv)
{
if (!pdd_DrvInit (pDrv))
{
// If failure, the drv context structure will be freed by
// USBDeviceAttach
DEBUGMSG (ZONE_ERROR | ZONE_INIT, (DTAG TEXT("pdd_Init Failure!")));
return 0;
}
}
return (DWORD)pDrv;
}
//======================================================================
// CAM_Deinit - Driver de-initialization function
//
BOOL CAM_Deinit (DWORD dwContext)
{
PDRVCONTEXT pDrv = (PDRVCONTEXT) dwContext;
pdd_DrvUninit (pDrv);
// The drv context structure will be freed by
// USBDeviceNotificationCallback
return TRUE;
}
//======================================================================
// CAM_Open - Called when driver opened
//
DWORD CAM_Open (DWORD dwContext, DWORD dwAccess, DWORD dwShare)
{
PDRVCONTEXT pDrv = (PDRVCONTEXT) dwContext;
DEBUGMSG (ZONE_EXENTRY,
(DTAG TEXT("CAM_Open++ dwContext: %x\r\n"), dwContext));
// Verify that the context handle is valid.
if ((pDrv == 0) || (pDrv->dwSize != sizeof (DRVCONTEXT))) {
return 0;
}
EnterCriticalSection (&pDrv->csDCall);
if (pDrv->nNumOpens)
{
//We're already open, fail...
LeaveCriticalSection (&pDrv->csDCall);
SetLastError(ERROR_ACCESS_DENIED);
return 0;
}
pDrv->nNumOpens++;
pdd_DrvOpen (pDrv);
LeaveCriticalSection (&pDrv->csDCall);
return (DWORD)pDrv;
}
//======================================================================
// CAM_Close - Called when driver closed
//
BOOL CAM_Close (DWORD dwOpen) {
PDRVCONTEXT pDrv = (PDRVCONTEXT) dwOpen;
DEBUGMSG (ZONE_EXENTRY,
(DTAG TEXT("CAM_Close++ dwOpen: %x\r\n"), dwOpen));
EnterCriticalSection (&pDrv->csDCall);
if (pDrv && (pDrv->dwSize != sizeof (DRVCONTEXT))) {
LeaveCriticalSection (&pDrv->csDCall);
DEBUGMSG (ZONE_FUNC | ZONE_ERROR,
(DTAG TEXT("CAM_Close failed\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
// Notify the PDD that the app is closing the driver. The
// PDD will stop any running stream.
pdd_DrvClose (pDrv);
// If we allocated the frame buffer, free it,
if (pDrv->mmFrameBuff.p)
{
DEBUGMSG (ZONE_ERROR,
(DTAG TEXT ("Driver closed with active stream running! Stop stream before closing\r\n")));
// Free up the current frame buffer
FreeSharedObject (&pDrv->mmFrameBuff);
pDrv->mmFrameBuff.p = 0;
}
if (pDrv->nNumOpens)
pDrv->nNumOpens--;
LeaveCriticalSection (&pDrv->csDCall);
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("CAM_Close--\r\n")));
return TRUE;
}
//======================================================================
// CAM_Read - Called when driver read
//
DWORD CAM_Read (DWORD dwOpen, LPVOID pBuffer, DWORD dwCount) {
DWORD dwBytesRead = 0;
DEBUGMSG (ZONE_EXENTRY,
(DTAG TEXT("CAM_Read++ dwOpen: %x\r\n"), dwOpen));
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("CAM_Read--\r\n")));
return dwBytesRead;
}
//======================================================================
// CAM_Write - Called when driver written
//
DWORD CAM_Write (DWORD dwOpen, LPVOID pBuffer, DWORD dwCount) {
DWORD dwBytesWritten = 0;
DEBUGMSG (ZONE_EXENTRY,
(DTAG TEXT("CAM_Write++ dwOpen: %x\r\n"), dwOpen));
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("CAM_Write--\r\n")));
return dwBytesWritten;
}
//======================================================================
// CAM_Seek - Called when SetFilePtr called
//
DWORD CAM_Seek (DWORD dwOpen, long lDelta, WORD wType) {
DEBUGMSG (ZONE_EXENTRY,(DTAG TEXT("CAM_Seek++ dwOpen:%x %d %d\r\n"),
dwOpen, lDelta, wType));
DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("CAM_Seek--\r\n")));
return 0;
}
//======================================================================
// CAM_IOControl - Called when DeviceIOControl called
//
DWORD CAM_IOControl (DWORD dwOpen, DWORD dwCode, PBYTE pIn, DWORD dwIn,
PBYTE pOut, DWORD dwOut, DWORD *pdwBytesWritten) {
PDRVCONTEXT pDrv;
DWORD err = ERROR_INVALID_PARAMETER;
DEBUGMSG (ZONE_EXENTRY,
(DTAG TEXT("CAM_IOControl++ dwOpen: %x dwCode: %x\r\n"),
dwOpen, dwCode));
pDrv = (PDRVCONTEXT) dwOpen;
EnterCriticalSection (&pDrv->csDCall);
switch (dwCode) {
case IOCTL_CAMERA_DEVICE_GETDRIVERVERSION:
err = mdd_GetVersion (pDrv, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_QUERYPARAMETERARARY:
err = mdd_GetParameterList (pDrv, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_QUERYPARAMETER:
err = mdd_GetParameter (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_SETPARAMETER:
err = mdd_SetParameter (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_QUERYVIDEOFORMATS:
err = mdd_QueryVideoFormats (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_GETVIDEOFORMAT:
err = mdd_GetVideoFormat (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_STARTVIDEOSTREAM:
err = mdd_SetVideoFormat (pDrv, pIn, dwIn, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_GETNEXTVIDEOFRAME:
err = mdd_GetNextVideoFrame (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_GETCURRENVIDEOFORMAT:
err = mdd_GetCurrentFormat (pDrv, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_STOPVIDEOSTREAM:
err = mdd_StopVideoStream (pDrv);
if (pdwBytesWritten)
*pdwBytesWritten = 0;
break;
case IOCTL_CAMERA_DEVICE_QUERYSTILLFORMATS:
err = mdd_QueryStillFormats (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_GETSTILLIMAGE:
err = mdd_GetStillImage (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
case IOCTL_CAMERA_DEVICE_WAITONCAMERAEVENT:
err = mdd_WaitOnCameraEvent (pDrv, pIn, dwIn, pOut, dwOut, pdwBytesWritten);
break;
default:
DEBUGMSG (ZONE_ERROR,
(DTAG TEXT("CAM_IOControl: unknown code %x\r\n"), dwCode));
err = ERROR_INVALID_PARAMETER;
}
SetLastError (err);
LeaveCriticalSection (&pDrv->csDCall);
DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("CAM_IOControl-- rc = %d\r\n"), err));
return err ? FALSE : TRUE;
}
//======================================================================
// CAM_PowerDown - Called when system suspends
//
void CAM_PowerDown (DWORD dwContext)
{
return;
}
//======================================================================
// CAM_PowerUp - Called when resumes
//
void CAM_PowerUp (DWORD dwContext)
{
return;
}
//----------------------------------------------------------------------
// GetConfigData - Get the pointer to the driver context structure
//
PDRVCONTEXT GetConfigData (DWORD dwContext)
{
int nLen, rc;
DWORD dwLen, dwType, dwSize = 0;
HKEY hKey;
PDRVCONTEXT pDrv = 0;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetConfigData++\r\n")));
nLen = 0;
// If ptr < 65K, it's a value, not a pointer.
if (dwContext < 0x10000) {
return 0;
} else {
__try {
nLen = lstrlen ((LPTSTR)dwContext);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
nLen = 0;
}
}
if (!nLen) {
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("dwContext not a ptr\r\n")));
return 0;
}
// Open the Active key for the driver.
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPTSTR)dwContext,0, 0, &hKey);
if (rc == ERROR_SUCCESS) {
// Read the key value.
dwLen = sizeof(pDrv);
rc = RegQueryValueEx (hKey, TEXT("ClientInfo"), NULL, &dwType,
(PBYTE)&pDrv, &dwLen);
RegCloseKey(hKey);
if ((rc == ERROR_SUCCESS) && (dwType == REG_DWORD))
{
__try {
if (pDrv->dwSize != sizeof (DRVCONTEXT))
pDrv = 0;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pDrv = 0;
}
}
else
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Error reading registry\r\n")));
pDrv = 0;
}
} else
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Error opening Active key\r\n")));
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetConfigData--\r\n")));
return pDrv;
}
//======================================================================
// MDD functions
//======================================================================
//---------------------------------------------------------------------------------------
// mdd_GetParameterList
//
int mdd_GetVersion (PDRVCONTEXT pDrv, PBYTE pOut, DWORD dwOut, PDWORD pdwBytesWritten)
{
int rc;
DWORD dwOutSize = sizeof (DWORD);
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetVersion++ \r\n")));
// See if they passed the proper parameters
if ((pOut == 0) || (pdwBytesWritten == 0))
return ERROR_INVALID_PARAMETER;
// See if output buffer is big enough
if (dwOut < dwOutSize)
rc = ERROR_NOT_ENOUGH_MEMORY;
else
{
__try
{
*(DWORD *)pOut = MAKELONG (DRV_MINORVER, DRV_MAJORVER);
*pdwBytesWritten = dwOutSize;
rc = 0;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
rc = ERROR_INVALID_PARAMETER;
}
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetVersion-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_GetParameterList
//
int mdd_GetParameterList (PDRVCONTEXT pDrv, PBYTE pOut, DWORD dwOut, PDWORD pdwBytesWritten)
{
int rc, nCnt;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetParameterList++ \r\n")));
// Get size of feature list
nCnt = pdd_GetFeatureList (pDrv, NULL, 0);
DWORD dwOutSize = nCnt * sizeof (FEATUREPROP) + sizeof (FEATUREPROPS);
// See if they want the size of the buffer
if ((pOut == 0) && pdwBytesWritten)
{
__try
{
*pdwBytesWritten = dwOutSize;
return 0;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return ERROR_INVALID_PARAMETER;
}
}
// See if output buffer is big enough
if (dwOut < dwOutSize)
return ERROR_NOT_ENOUGH_MEMORY;
// Get the list of feature IDs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -