391 lines
8.6 KiB
C++
391 lines
8.6 KiB
C++
|
// File: vidwiz.cpp
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
|
|||
|
#include "dcap.h"
|
|||
|
#include "vidinout.h"
|
|||
|
#include "vidwiz.h"
|
|||
|
#include "confcpl.h"
|
|||
|
|
|||
|
|
|||
|
static HINSTANCE g_hDcapLib;
|
|||
|
|
|||
|
typedef int (WINAPI *GNCD)();
|
|||
|
typedef BOOL (WINAPI *FFCD)(FINDCAPTUREDEVICE*, char *);
|
|||
|
typedef BOOL (WINAPI *FFCDBI)(FINDCAPTUREDEVICE*, int);
|
|||
|
|
|||
|
// implementations in DCAP32.DLL
|
|||
|
static FFCD DLL_FindFirstCaptureDevice = NULL;
|
|||
|
static FFCDBI DLL_FindFirstCaptureDeviceByIndex = NULL;
|
|||
|
static GNCD DLL_GetNumCaptureDevices = NULL;
|
|||
|
|
|||
|
// Defined in wizard.cpp
|
|||
|
extern UINT_PTR GetPageBeforeVideoWiz();
|
|||
|
extern UINT_PTR GetPageAfterVideo();
|
|||
|
|
|||
|
// index number of the user's selection on the combo box
|
|||
|
static int g_nCurrentSelection = 0;
|
|||
|
|
|||
|
// set to true only if the user hit's back or next
|
|||
|
static BOOL g_bCurrentValid = FALSE;
|
|||
|
|
|||
|
// was the user prompted to select a video device
|
|||
|
static BOOL g_bPrompted = FALSE;
|
|||
|
|
|||
|
|
|||
|
static char *BuildCaptureDeviceInfoString(FINDCAPTUREDEVICE *pCaptureDeviceInfo, char *szOut);
|
|||
|
|
|||
|
|
|||
|
BOOL InitVidWiz()
|
|||
|
{
|
|||
|
|
|||
|
// initialize locals
|
|||
|
g_hDcapLib = NULL;
|
|||
|
DLL_FindFirstCaptureDevice = NULL;
|
|||
|
DLL_FindFirstCaptureDeviceByIndex = NULL;
|
|||
|
DLL_GetNumCaptureDevices = NULL;
|
|||
|
g_nCurrentSelection = 0;
|
|||
|
g_bCurrentValid = FALSE;
|
|||
|
g_bPrompted = FALSE;
|
|||
|
|
|||
|
g_hDcapLib = NmLoadLibrary("dcap32.dll");
|
|||
|
if (g_hDcapLib == NULL)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
DLL_FindFirstCaptureDevice = (FFCD)GetProcAddress(g_hDcapLib, "FindFirstCaptureDevice");
|
|||
|
DLL_FindFirstCaptureDeviceByIndex = (FFCDBI)GetProcAddress(g_hDcapLib, "FindFirstCaptureDeviceByIndex");
|
|||
|
DLL_GetNumCaptureDevices = (GNCD)GetProcAddress(g_hDcapLib, "GetNumCaptureDevices");
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// returns TRUE if the capture device id in the registry corresponds with
|
|||
|
// the driver description string.
|
|||
|
static BOOL IsVideoRegistryValid()
|
|||
|
{
|
|||
|
RegEntry re(VIDEO_KEY);
|
|||
|
char szDriverDesc[200];
|
|||
|
char *szDriverDescReg;
|
|||
|
int numVideoDevices, nID;
|
|||
|
FINDCAPTUREDEVICE CaptureDeviceInfo;
|
|||
|
BOOL fRet;
|
|||
|
|
|||
|
// just in case InitVidWiz wasn't called
|
|||
|
if (NULL == g_hDcapLib)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
numVideoDevices = DLL_GetNumCaptureDevices();
|
|||
|
|
|||
|
nID = re.GetNumber(REGVAL_CAPTUREDEVICEID, -1);
|
|||
|
szDriverDescReg = re.GetString(REGVAL_CAPTUREDEVICENAME);
|
|||
|
|
|||
|
// no video devices and no registry entry is valid
|
|||
|
if ((numVideoDevices == 0) && (nID == -1))
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ((numVideoDevices == 0) && (nID != -1))
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// TRUE == (numVideoDevice >= 1)
|
|||
|
|
|||
|
// installed video devices but no registry entry is invalid
|
|||
|
if (nID == -1)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
CaptureDeviceInfo.dwSize = sizeof(FINDCAPTUREDEVICE);
|
|||
|
fRet = DLL_FindFirstCaptureDeviceByIndex(&CaptureDeviceInfo, nID);
|
|||
|
|
|||
|
if (fRet == FALSE)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BuildCaptureDeviceInfoString(&CaptureDeviceInfo, szDriverDesc);
|
|||
|
|
|||
|
if (0 == lstrcmp(szDriverDescReg, szDriverDesc))
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL UnInitVidWiz()
|
|||
|
{
|
|||
|
if (g_hDcapLib)
|
|||
|
FreeLibrary(g_hDcapLib);
|
|||
|
|
|||
|
g_hDcapLib = NULL;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static char *BuildCaptureDeviceInfoString(FINDCAPTUREDEVICE *pCaptureDeviceInfo, char *szOut)
|
|||
|
{
|
|||
|
if (pCaptureDeviceInfo->szDeviceDescription[0] != '\0')
|
|||
|
{
|
|||
|
lstrcpy(szOut, pCaptureDeviceInfo->szDeviceDescription);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
lstrcpy(szOut, pCaptureDeviceInfo->szDeviceName);
|
|||
|
}
|
|||
|
|
|||
|
if (pCaptureDeviceInfo->szDeviceVersion[0] != '\0')
|
|||
|
{
|
|||
|
lstrcat(szOut, _T(", "));
|
|||
|
lstrcat(szOut, pCaptureDeviceInfo->szDeviceVersion);
|
|||
|
}
|
|||
|
return szOut;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void UpdateVidConfigRegistry()
|
|||
|
{
|
|||
|
FINDCAPTUREDEVICE CaptureDeviceInfo, *CaptureDevTable;
|
|||
|
RegEntry re(VIDEO_KEY);
|
|||
|
BOOL bRet;
|
|||
|
char strNameDesc[MAX_CAPDEV_NAME+MAX_CAPDEV_VERSION];
|
|||
|
int numVideoDevices, index, enum_index;
|
|||
|
|
|||
|
// just in case InitVidWiz wasn't called
|
|||
|
if (NULL == g_hDcapLib)
|
|||
|
return;
|
|||
|
|
|||
|
numVideoDevices = DLL_GetNumCaptureDevices();
|
|||
|
|
|||
|
// no devices - delete the registry entries
|
|||
|
if (numVideoDevices == 0)
|
|||
|
{
|
|||
|
re.DeleteValue(REGVAL_CAPTUREDEVICEID);
|
|||
|
re.DeleteValue(REGVAL_CAPTUREDEVICENAME);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// build a table of all the devices
|
|||
|
|
|||
|
CaptureDevTable = (FINDCAPTUREDEVICE *)LocalAlloc(LPTR, numVideoDevices*sizeof(FINDCAPTUREDEVICE));
|
|||
|
|
|||
|
if (NULL == CaptureDevTable)
|
|||
|
{
|
|||
|
ERROR_OUT(("UpdateVidConfigRegistry: Out of memory"));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
index = 0;
|
|||
|
for (enum_index=0; enum_index < MAXVIDEODRIVERS; enum_index++)
|
|||
|
{
|
|||
|
CaptureDevTable[index].dwSize = sizeof(FINDCAPTUREDEVICE);
|
|||
|
bRet = DLL_FindFirstCaptureDeviceByIndex(&CaptureDevTable[index], enum_index);
|
|||
|
if (bRet == TRUE)
|
|||
|
index++;
|
|||
|
if (index == numVideoDevices)
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (index != numVideoDevices)
|
|||
|
{
|
|||
|
ERROR_OUT(("UpdateVidConfigReg: Device Enumeration Failure"));
|
|||
|
LocalFree(CaptureDevTable);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// if only one capture device:
|
|||
|
// don't bother to see if the previous entry was valid
|
|||
|
// just update the registry with the current default
|
|||
|
if (numVideoDevices == 1)
|
|||
|
{
|
|||
|
BuildCaptureDeviceInfoString(&CaptureDevTable[0], strNameDesc);
|
|||
|
re.SetValue(REGVAL_CAPTUREDEVICEID, CaptureDevTable[0].nDeviceIndex);
|
|||
|
re.SetValue(REGVAL_CAPTUREDEVICENAME, strNameDesc);
|
|||
|
LocalFree(CaptureDevTable);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// TRUE == (numVideoDevices >= 2)
|
|||
|
|
|||
|
// user wasn't prompted - he must of had a valid registry to start with
|
|||
|
if (g_bPrompted == FALSE)
|
|||
|
{
|
|||
|
LocalFree(CaptureDevTable);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// the user pressed CANCEL during setup
|
|||
|
if (g_bCurrentValid == FALSE)
|
|||
|
{
|
|||
|
if (IsVideoRegistryValid() == TRUE)
|
|||
|
{
|
|||
|
LocalFree(CaptureDevTable);
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
g_nCurrentSelection = 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CaptureDeviceInfo = CaptureDevTable[g_nCurrentSelection];
|
|||
|
|
|||
|
BuildCaptureDeviceInfoString(&CaptureDeviceInfo, strNameDesc);
|
|||
|
re.SetValue(REGVAL_CAPTUREDEVICEID, CaptureDeviceInfo.nDeviceIndex);
|
|||
|
re.SetValue(REGVAL_CAPTUREDEVICENAME, strNameDesc);
|
|||
|
|
|||
|
LocalFree(CaptureDevTable);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// if <= 1 video capture device, return false
|
|||
|
// if 2 or more video devices and the Wizard is in force mode, return true
|
|||
|
// if 2 or more video devices and a MATCHING registry entry, return false
|
|||
|
// otherwise something is fishy - return true
|
|||
|
BOOL NeedVideoPropPage(BOOL fForce)
|
|||
|
{
|
|||
|
// just in case InitVidWiz wasn't called
|
|||
|
if (NULL == g_hDcapLib)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
// check the system policies for sending video
|
|||
|
if (_Module.IsSDKCallerRTC() || SysPol::NoVideoSend())
|
|||
|
{
|
|||
|
WARNING_OUT(("Video is disabled by system policies key\r\n"));
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// count how many devices we have
|
|||
|
int numCaptureDevices = DLL_GetNumCaptureDevices();
|
|||
|
if (numCaptureDevices <= 1)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// TRUE == (numCaptureDevice >= 2)
|
|||
|
|
|||
|
if (fForce)
|
|||
|
{
|
|||
|
g_bPrompted = TRUE;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if (IsVideoRegistryValid() == TRUE)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
g_bPrompted = TRUE;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Message handler for property page
|
|||
|
INT_PTR APIENTRY VidWizDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
|
{
|
|||
|
HWND hwndCB; // handle to the dialog box
|
|||
|
int index;
|
|||
|
char szDriverNameDesc[MAX_CAPDEV_NAME+MAX_CAPDEV_VERSION];
|
|||
|
static LONG_PTR button_mask;
|
|||
|
FINDCAPTUREDEVICE CaptureDeviceInfo;
|
|||
|
|
|||
|
hwndCB = GetDlgItem(hDlg, IDC_VWCOMBO);
|
|||
|
|
|||
|
switch(message)
|
|||
|
{
|
|||
|
case(WM_INITDIALOG) :
|
|||
|
button_mask = ((PROPSHEETPAGE *)lParam)->lParam;
|
|||
|
if (g_hDcapLib == NULL) break;
|
|||
|
for (index = 0; index < MAXVIDEODRIVERS; index++)
|
|||
|
{
|
|||
|
CaptureDeviceInfo.dwSize = sizeof(FINDCAPTUREDEVICE);
|
|||
|
if (DLL_FindFirstCaptureDeviceByIndex(&CaptureDeviceInfo, index))
|
|||
|
{
|
|||
|
BuildCaptureDeviceInfoString(&CaptureDeviceInfo, szDriverNameDesc);
|
|||
|
ComboBox_AddString(hwndCB, szDriverNameDesc);
|
|||
|
}
|
|||
|
}
|
|||
|
ComboBox_SetCurSel(hwndCB, g_nCurrentSelection);
|
|||
|
break;
|
|||
|
|
|||
|
case(WM_NOTIFY) :
|
|||
|
switch (((NMHDR *)lParam)->code)
|
|||
|
{
|
|||
|
case PSN_WIZBACK:
|
|||
|
{
|
|||
|
UINT_PTR iPrev = GetPageBeforeVideoWiz();
|
|||
|
ASSERT( iPrev );
|
|||
|
::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, iPrev);
|
|||
|
g_bCurrentValid = TRUE;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
case PSN_WIZNEXT:
|
|||
|
{
|
|||
|
UINT_PTR iNext = GetPageAfterVideo();
|
|||
|
ASSERT( iNext );
|
|||
|
::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, iNext);
|
|||
|
g_bCurrentValid = TRUE;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
case PSN_WIZFINISH:
|
|||
|
case PSN_KILLACTIVE:
|
|||
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
|
|||
|
g_bCurrentValid = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
case PSN_SETACTIVE:
|
|||
|
if (g_fSilentWizard)
|
|||
|
{
|
|||
|
PropSheet_PressButton(GetParent(hDlg), (button_mask & PSWIZB_NEXT) ? PSBTN_NEXT : PSBTN_FINISH);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PropSheet_SetWizButtons(GetParent(hDlg), button_mask);
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case PSN_RESET:
|
|||
|
// psn_reset get's received even if user presses
|
|||
|
// cancel on another dialog.
|
|||
|
g_bCurrentValid = FALSE;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
// combox box messages get sent here.
|
|||
|
// only one we need is when the user selects something
|
|||
|
case(WM_COMMAND) :
|
|||
|
if (HIWORD(wParam) == CBN_SELCHANGE)
|
|||
|
{
|
|||
|
g_nCurrentSelection = ComboBox_GetCurSel(hwndCB);
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|