Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

390 lines
8.6 KiB

  1. // File: vidwiz.cpp
  2. #include "precomp.h"
  3. #include "dcap.h"
  4. #include "vidinout.h"
  5. #include "vidwiz.h"
  6. #include "confcpl.h"
  7. static HINSTANCE g_hDcapLib;
  8. typedef int (WINAPI *GNCD)();
  9. typedef BOOL (WINAPI *FFCD)(FINDCAPTUREDEVICE*, char *);
  10. typedef BOOL (WINAPI *FFCDBI)(FINDCAPTUREDEVICE*, int);
  11. // implementations in DCAP32.DLL
  12. static FFCD DLL_FindFirstCaptureDevice = NULL;
  13. static FFCDBI DLL_FindFirstCaptureDeviceByIndex = NULL;
  14. static GNCD DLL_GetNumCaptureDevices = NULL;
  15. // Defined in wizard.cpp
  16. extern UINT_PTR GetPageBeforeVideoWiz();
  17. extern UINT_PTR GetPageAfterVideo();
  18. // index number of the user's selection on the combo box
  19. static int g_nCurrentSelection = 0;
  20. // set to true only if the user hit's back or next
  21. static BOOL g_bCurrentValid = FALSE;
  22. // was the user prompted to select a video device
  23. static BOOL g_bPrompted = FALSE;
  24. static char *BuildCaptureDeviceInfoString(FINDCAPTUREDEVICE *pCaptureDeviceInfo, char *szOut);
  25. BOOL InitVidWiz()
  26. {
  27. // initialize locals
  28. g_hDcapLib = NULL;
  29. DLL_FindFirstCaptureDevice = NULL;
  30. DLL_FindFirstCaptureDeviceByIndex = NULL;
  31. DLL_GetNumCaptureDevices = NULL;
  32. g_nCurrentSelection = 0;
  33. g_bCurrentValid = FALSE;
  34. g_bPrompted = FALSE;
  35. g_hDcapLib = NmLoadLibrary("dcap32.dll");
  36. if (g_hDcapLib == NULL)
  37. return FALSE;
  38. DLL_FindFirstCaptureDevice = (FFCD)GetProcAddress(g_hDcapLib, "FindFirstCaptureDevice");
  39. DLL_FindFirstCaptureDeviceByIndex = (FFCDBI)GetProcAddress(g_hDcapLib, "FindFirstCaptureDeviceByIndex");
  40. DLL_GetNumCaptureDevices = (GNCD)GetProcAddress(g_hDcapLib, "GetNumCaptureDevices");
  41. return TRUE;
  42. }
  43. // returns TRUE if the capture device id in the registry corresponds with
  44. // the driver description string.
  45. static BOOL IsVideoRegistryValid()
  46. {
  47. RegEntry re(VIDEO_KEY);
  48. char szDriverDesc[200];
  49. char *szDriverDescReg;
  50. int numVideoDevices, nID;
  51. FINDCAPTUREDEVICE CaptureDeviceInfo;
  52. BOOL fRet;
  53. // just in case InitVidWiz wasn't called
  54. if (NULL == g_hDcapLib)
  55. return FALSE;
  56. numVideoDevices = DLL_GetNumCaptureDevices();
  57. nID = re.GetNumber(REGVAL_CAPTUREDEVICEID, -1);
  58. szDriverDescReg = re.GetString(REGVAL_CAPTUREDEVICENAME);
  59. // no video devices and no registry entry is valid
  60. if ((numVideoDevices == 0) && (nID == -1))
  61. {
  62. return TRUE;
  63. }
  64. if ((numVideoDevices == 0) && (nID != -1))
  65. {
  66. return FALSE;
  67. }
  68. // TRUE == (numVideoDevice >= 1)
  69. // installed video devices but no registry entry is invalid
  70. if (nID == -1)
  71. {
  72. return FALSE;
  73. }
  74. CaptureDeviceInfo.dwSize = sizeof(FINDCAPTUREDEVICE);
  75. fRet = DLL_FindFirstCaptureDeviceByIndex(&CaptureDeviceInfo, nID);
  76. if (fRet == FALSE)
  77. {
  78. return FALSE;
  79. }
  80. BuildCaptureDeviceInfoString(&CaptureDeviceInfo, szDriverDesc);
  81. if (0 == lstrcmp(szDriverDescReg, szDriverDesc))
  82. {
  83. return TRUE;
  84. }
  85. return FALSE;
  86. }
  87. BOOL UnInitVidWiz()
  88. {
  89. if (g_hDcapLib)
  90. FreeLibrary(g_hDcapLib);
  91. g_hDcapLib = NULL;
  92. return TRUE;
  93. }
  94. static char *BuildCaptureDeviceInfoString(FINDCAPTUREDEVICE *pCaptureDeviceInfo, char *szOut)
  95. {
  96. if (pCaptureDeviceInfo->szDeviceDescription[0] != '\0')
  97. {
  98. lstrcpy(szOut, pCaptureDeviceInfo->szDeviceDescription);
  99. }
  100. else
  101. {
  102. lstrcpy(szOut, pCaptureDeviceInfo->szDeviceName);
  103. }
  104. if (pCaptureDeviceInfo->szDeviceVersion[0] != '\0')
  105. {
  106. lstrcat(szOut, _T(", "));
  107. lstrcat(szOut, pCaptureDeviceInfo->szDeviceVersion);
  108. }
  109. return szOut;
  110. }
  111. void UpdateVidConfigRegistry()
  112. {
  113. FINDCAPTUREDEVICE CaptureDeviceInfo, *CaptureDevTable;
  114. RegEntry re(VIDEO_KEY);
  115. BOOL bRet;
  116. char strNameDesc[MAX_CAPDEV_NAME+MAX_CAPDEV_VERSION];
  117. int numVideoDevices, index, enum_index;
  118. // just in case InitVidWiz wasn't called
  119. if (NULL == g_hDcapLib)
  120. return;
  121. numVideoDevices = DLL_GetNumCaptureDevices();
  122. // no devices - delete the registry entries
  123. if (numVideoDevices == 0)
  124. {
  125. re.DeleteValue(REGVAL_CAPTUREDEVICEID);
  126. re.DeleteValue(REGVAL_CAPTUREDEVICENAME);
  127. return;
  128. }
  129. // build a table of all the devices
  130. CaptureDevTable = (FINDCAPTUREDEVICE *)LocalAlloc(LPTR, numVideoDevices*sizeof(FINDCAPTUREDEVICE));
  131. if (NULL == CaptureDevTable)
  132. {
  133. ERROR_OUT(("UpdateVidConfigRegistry: Out of memory"));
  134. return;
  135. }
  136. index = 0;
  137. for (enum_index=0; enum_index < MAXVIDEODRIVERS; enum_index++)
  138. {
  139. CaptureDevTable[index].dwSize = sizeof(FINDCAPTUREDEVICE);
  140. bRet = DLL_FindFirstCaptureDeviceByIndex(&CaptureDevTable[index], enum_index);
  141. if (bRet == TRUE)
  142. index++;
  143. if (index == numVideoDevices)
  144. break;
  145. }
  146. if (index != numVideoDevices)
  147. {
  148. ERROR_OUT(("UpdateVidConfigReg: Device Enumeration Failure"));
  149. LocalFree(CaptureDevTable);
  150. return;
  151. }
  152. // if only one capture device:
  153. // don't bother to see if the previous entry was valid
  154. // just update the registry with the current default
  155. if (numVideoDevices == 1)
  156. {
  157. BuildCaptureDeviceInfoString(&CaptureDevTable[0], strNameDesc);
  158. re.SetValue(REGVAL_CAPTUREDEVICEID, CaptureDevTable[0].nDeviceIndex);
  159. re.SetValue(REGVAL_CAPTUREDEVICENAME, strNameDesc);
  160. LocalFree(CaptureDevTable);
  161. return;
  162. }
  163. // TRUE == (numVideoDevices >= 2)
  164. // user wasn't prompted - he must of had a valid registry to start with
  165. if (g_bPrompted == FALSE)
  166. {
  167. LocalFree(CaptureDevTable);
  168. return;
  169. }
  170. // the user pressed CANCEL during setup
  171. if (g_bCurrentValid == FALSE)
  172. {
  173. if (IsVideoRegistryValid() == TRUE)
  174. {
  175. LocalFree(CaptureDevTable);
  176. return;
  177. }
  178. else
  179. g_nCurrentSelection = 0;
  180. }
  181. CaptureDeviceInfo = CaptureDevTable[g_nCurrentSelection];
  182. BuildCaptureDeviceInfoString(&CaptureDeviceInfo, strNameDesc);
  183. re.SetValue(REGVAL_CAPTUREDEVICEID, CaptureDeviceInfo.nDeviceIndex);
  184. re.SetValue(REGVAL_CAPTUREDEVICENAME, strNameDesc);
  185. LocalFree(CaptureDevTable);
  186. return;
  187. }
  188. // if <= 1 video capture device, return false
  189. // if 2 or more video devices and the Wizard is in force mode, return true
  190. // if 2 or more video devices and a MATCHING registry entry, return false
  191. // otherwise something is fishy - return true
  192. BOOL NeedVideoPropPage(BOOL fForce)
  193. {
  194. // just in case InitVidWiz wasn't called
  195. if (NULL == g_hDcapLib)
  196. return FALSE;
  197. // check the system policies for sending video
  198. if (_Module.IsSDKCallerRTC() || SysPol::NoVideoSend())
  199. {
  200. WARNING_OUT(("Video is disabled by system policies key\r\n"));
  201. return FALSE;
  202. }
  203. // count how many devices we have
  204. int numCaptureDevices = DLL_GetNumCaptureDevices();
  205. if (numCaptureDevices <= 1)
  206. {
  207. return FALSE;
  208. }
  209. // TRUE == (numCaptureDevice >= 2)
  210. if (fForce)
  211. {
  212. g_bPrompted = TRUE;
  213. return TRUE;
  214. }
  215. if (IsVideoRegistryValid() == TRUE)
  216. {
  217. return FALSE;
  218. }
  219. g_bPrompted = TRUE;
  220. return TRUE;
  221. }
  222. // Message handler for property page
  223. INT_PTR APIENTRY VidWizDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  224. {
  225. HWND hwndCB; // handle to the dialog box
  226. int index;
  227. char szDriverNameDesc[MAX_CAPDEV_NAME+MAX_CAPDEV_VERSION];
  228. static LONG_PTR button_mask;
  229. FINDCAPTUREDEVICE CaptureDeviceInfo;
  230. hwndCB = GetDlgItem(hDlg, IDC_VWCOMBO);
  231. switch(message)
  232. {
  233. case(WM_INITDIALOG) :
  234. button_mask = ((PROPSHEETPAGE *)lParam)->lParam;
  235. if (g_hDcapLib == NULL) break;
  236. for (index = 0; index < MAXVIDEODRIVERS; index++)
  237. {
  238. CaptureDeviceInfo.dwSize = sizeof(FINDCAPTUREDEVICE);
  239. if (DLL_FindFirstCaptureDeviceByIndex(&CaptureDeviceInfo, index))
  240. {
  241. BuildCaptureDeviceInfoString(&CaptureDeviceInfo, szDriverNameDesc);
  242. ComboBox_AddString(hwndCB, szDriverNameDesc);
  243. }
  244. }
  245. ComboBox_SetCurSel(hwndCB, g_nCurrentSelection);
  246. break;
  247. case(WM_NOTIFY) :
  248. switch (((NMHDR *)lParam)->code)
  249. {
  250. case PSN_WIZBACK:
  251. {
  252. UINT_PTR iPrev = GetPageBeforeVideoWiz();
  253. ASSERT( iPrev );
  254. ::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, iPrev);
  255. g_bCurrentValid = TRUE;
  256. return TRUE;
  257. }
  258. case PSN_WIZNEXT:
  259. {
  260. UINT_PTR iNext = GetPageAfterVideo();
  261. ASSERT( iNext );
  262. ::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, iNext);
  263. g_bCurrentValid = TRUE;
  264. return TRUE;
  265. }
  266. case PSN_WIZFINISH:
  267. case PSN_KILLACTIVE:
  268. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
  269. g_bCurrentValid = TRUE;
  270. break;
  271. case PSN_SETACTIVE:
  272. if (g_fSilentWizard)
  273. {
  274. PropSheet_PressButton(GetParent(hDlg), (button_mask & PSWIZB_NEXT) ? PSBTN_NEXT : PSBTN_FINISH);
  275. }
  276. else
  277. {
  278. PropSheet_SetWizButtons(GetParent(hDlg), button_mask);
  279. }
  280. break;
  281. case PSN_RESET:
  282. // psn_reset get's received even if user presses
  283. // cancel on another dialog.
  284. g_bCurrentValid = FALSE;
  285. break;
  286. default:
  287. return FALSE;
  288. }
  289. break;
  290. // combox box messages get sent here.
  291. // only one we need is when the user selects something
  292. case(WM_COMMAND) :
  293. if (HIWORD(wParam) == CBN_SELCHANGE)
  294. {
  295. g_nCurrentSelection = ComboBox_GetCurSel(hwndCB);
  296. break;
  297. }
  298. else
  299. {
  300. return FALSE;
  301. }
  302. break;
  303. default:
  304. return FALSE;
  305. }
  306. return TRUE;
  307. }
  308.