Leaked source code of windows server 2003
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.

1681 lines
60 KiB

  1. /****************************************************************************
  2. video.c
  3. Contains video APIs
  4. Copyright (c) Microsoft Corporation 1992. All rights reserved
  5. ****************************************************************************/
  6. #include <windows.h>
  7. #include <mmsystem.h>
  8. #include "win32.h"
  9. #include "msviddrv.h"
  10. #include "msvideo.h"
  11. #include "msvideoi.h"
  12. #ifdef WIN32
  13. #include <mmddk.h>
  14. #endif
  15. #include <ver.h>
  16. #ifndef NOTHUNKS
  17. #include "thunks.h"
  18. #endif //!NOTHUNKS
  19. /*****************************************************************************
  20. * Variables
  21. *
  22. ****************************************************************************/
  23. SZCODE szNull[] = TEXT("");
  24. SZCODE szVideo[] = TEXT("msvideo");
  25. #ifndef WIN32
  26. SZCODE szDrivers[] = "Drivers";
  27. SZCODE szDrivers32[] = "Drivers32";
  28. #else
  29. STATICDT SZCODE szDrivers[] = DRIVERS_SECTION;
  30. #endif
  31. STATICDT SZCODE szSystemIni[] = TEXT("system.ini");
  32. UINT wTotalVideoDevs; // total video devices
  33. UINT wVideoDevs32; // 32-bit video devices
  34. UINT bVideo0Invalid; // if true: ignore MSVideo
  35. // (see videoGetNumDevs)
  36. HINSTANCE ghInst; // our module handle
  37. /*****************************************************************************
  38. * @doc INTERNAL VIDEO validation code for VIDEOHDRs
  39. ****************************************************************************/
  40. #define IsVideoHeaderPrepared(hVideo, lpwh) ((lpwh)->dwFlags & VHDR_PREPARED)
  41. #define MarkVideoHeaderPrepared(hVideo, lpwh) ((lpwh)->dwFlags |= VHDR_PREPARED)
  42. #define MarkVideoHeaderUnprepared(hVideo, lpwh) ((lpwh)->dwFlags &=~VHDR_PREPARED)
  43. /*****************************************************************************
  44. * @doc EXTERNAL VIDEO
  45. *
  46. * @func DWORD | videoMessage | This function sends messages to a
  47. * video device channel.
  48. *
  49. * @parm HVIDEO | hVideo | Specifies the handle to the video device channel.
  50. *
  51. * @parm UINT | wMsg | Specifies the message to send.
  52. *
  53. * @parm DWORD | dwP1 | Specifies the first parameter for the message.
  54. *
  55. * @parm DWORD | dwP2 | Specifies the second parameter for the message.
  56. *
  57. * @rdesc Returns the message specific value returned from the driver.
  58. *
  59. * @comm This function is used for configuration messages such as
  60. * <m DVM_SRC_RECT> and <m DVM_DST_RECT>, and
  61. * device specific messages.
  62. *
  63. * @xref <f videoConfigure>
  64. *
  65. ****************************************************************************/
  66. DWORD WINAPI videoMessage(HVIDEO hVideo, UINT msg, DWORD dwP1, DWORD dwP2)
  67. {
  68. if (!hVideo)
  69. return DV_ERR_INVALHANDLE;
  70. #ifndef NOTHUNKS
  71. if (Is32bitHandle(hVideo)) {
  72. return videoMessage32(Map32bitHandle(hVideo), msg, dwP1, dwP2);
  73. }
  74. #endif
  75. return SendDriverMessage (hVideo, msg, dwP1, dwP2);
  76. }
  77. /*****************************************************************************
  78. * @doc EXTERNAL VIDEO
  79. *
  80. * @api DWORD | videoGetNumDevs | This function returns the number of MSVIDEO
  81. * devices installed.
  82. *
  83. * @rdesc Returns the number of MSVIDEO devices listed in the
  84. * [drivers] (or [drivers32] for NT) section of the SYSTEM.INI file.
  85. *
  86. * @comm Because the indexes of the MSVIDEO devices in the SYSTEM.INI
  87. * file can be non-contiguous, applications should not assume
  88. * the indexes range between zero and the number of devices minus
  89. * one.
  90. *
  91. * @xref <f videoOpen>
  92. ****************************************************************************/
  93. DWORD WINAPI videoGetNumDevs(void)
  94. {
  95. TCHAR szKey[(sizeof(szVideo)/sizeof(TCHAR)) + 2];
  96. TCHAR szbuf[128];
  97. TCHAR szMSVideo32[128];
  98. int i;
  99. #ifndef NOTHUNKS
  100. // find how many 32-bit devices there are. indices 0 to wVideoDevs32
  101. // will be on the 32-bit side, and wVideoDevs32 to wTotalVideoDevs on the
  102. // 16-bit side
  103. wVideoDevs32 = (UINT)videoGetNumDevs32();
  104. wTotalVideoDevs = wVideoDevs32;
  105. // now add in the 16-bit devices
  106. #else
  107. wTotalVideoDevs = 0;
  108. #endif
  109. // NT 3.5 shipped with a hack solution to the capGetDriverDescription
  110. // problem which was to copy the MSVideo line from [Drivers32] to
  111. // [Drivers]
  112. // we now have to allow for this hack by detecting the case where the two
  113. // entries are the same. We then set bVideo0Invalid, and do not include it
  114. // in wTotalVideoDevs.
  115. bVideo0Invalid = FALSE;
  116. lstrcpy(szKey, szVideo);
  117. szKey[(sizeof(szVideo)/sizeof(TCHAR)) - 1] = (TCHAR) 0;
  118. szKey[sizeof(szVideo)/sizeof(TCHAR)] = (TCHAR) 0;
  119. // first read the [drivers32] MSVideo to compare against
  120. GetPrivateProfileString(szDrivers32, szKey, szNull, szMSVideo32,
  121. sizeof(szMSVideo32)/sizeof(TCHAR), szSystemIni);
  122. // now read the [Drivers] entries - compare the first one against this
  123. for (i=0; i < MAXVIDEODRIVERS; i++) {
  124. if (GetPrivateProfileString(szDrivers,szKey,szNull,
  125. szbuf,sizeof(szbuf)/sizeof(TCHAR),szSystemIni)) {
  126. if ((i == 0) && (lstrcmp(szbuf, szMSVideo32) == 0)) {
  127. bVideo0Invalid = TRUE;
  128. } else {
  129. wTotalVideoDevs++;
  130. }
  131. }
  132. szKey[(sizeof(szVideo)/sizeof(TCHAR))-1] = (TCHAR) TEXT('1'+ i); // advance driver ordinal
  133. }
  134. return (DWORD)wTotalVideoDevs;
  135. }
  136. /*****************************************************************************
  137. * @doc EXTERNAL VIDEO
  138. *
  139. * @func DWORD | videoGetErrorText | This function retrieves a
  140. * description of the error identified by the error number.
  141. *
  142. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  143. * This might be NULL if the error is not device specific.
  144. *
  145. * @parm UINT | wError | Specifies the error number.
  146. *
  147. * @parm LPSTR | lpText | Specifies a far pointer to a buffer used to
  148. * return the zero-terminated string corresponding to the error number.
  149. *
  150. * @parm UINT | wSize | Specifies the length, in bytes, of the buffer
  151. * referenced by <p lpText>.
  152. *
  153. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  154. * an error number. The following error is defined:
  155. * @flag DV_ERR_BADERRNUM | Specified error number is out of range.
  156. * @flag DV_ERR_SIZEFIELD | The return buffer is not large enough
  157. * to handle the error text.
  158. *
  159. * @comm If the error description is longer than the buffer,
  160. * the description is truncated. The returned error string is always
  161. * zero-terminated. If <p wSize> is zero, nothing is copied and zero
  162. * is returned.
  163. ****************************************************************************/
  164. DWORD WINAPI videoGetErrorText(HVIDEO hVideo, UINT wError,
  165. LPSTR lpText, UINT wSize)
  166. {
  167. VIDEO_GETERRORTEXT_PARMS vet;
  168. if (IsBadWritePtr (lpText, wSize))
  169. return DV_ERR_PARAM1;
  170. lpText[0] = 0;
  171. if (((wError >= DV_ERR_BASE) && (wError <= DV_ERR_LASTERROR))) {
  172. if (wSize > 1) {
  173. if (!LoadStringA(ghInst, wError, lpText, wSize))
  174. return DV_ERR_BADERRNUM;
  175. else
  176. return DV_ERR_OK;
  177. }
  178. else
  179. return DV_ERR_SIZEFIELD;
  180. }
  181. else if (wError >= DV_ERR_USER_MSG && hVideo) {
  182. vet.dwError = (DWORD) wError;
  183. vet.lpText = lpText;
  184. vet.dwLength = (DWORD) wSize;
  185. return videoMessage (hVideo, DVM_GETERRORTEXT, (DWORD) (LPVOID) &vet,
  186. (DWORD) NULL);
  187. }
  188. else
  189. return DV_ERR_BADERRNUM;
  190. }
  191. /*****************************************************************************
  192. * @doc EXTERNAL VIDEO
  193. *
  194. * @func DWORD | videoGetChannelCaps | This function retrieves a
  195. * description of the capabilities of a channel.
  196. *
  197. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  198. *
  199. * @parm LPCHANNEL_CAPS | lpChannelCaps | Specifies a far pointer to a
  200. * <t CHANNEL_CAPS> structure.
  201. *
  202. * @parm DWORD | dwSize | Specifies the size, in bytes, of the
  203. * <t CHANNEL_CAPS> structure.
  204. *
  205. * @rdesc Returns zero if the function is successful. Otherwise, it returns
  206. * an error number. The following errors are defined:
  207. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  208. * @flag DV_ERR_UNSUPPORTED | Function is not supported.
  209. *
  210. * @comm The <t CHANNEL_CAPS> structure returns the capability
  211. * information. For example, capability information might
  212. * include whether or not the channel can crop and scale images,
  213. * or show overlay.
  214. ****************************************************************************/
  215. DWORD WINAPI videoGetChannelCaps(HVIDEO hVideo, LPCHANNEL_CAPS lpChannelCaps,
  216. DWORD dwSize)
  217. {
  218. if (!hVideo)
  219. return DV_ERR_INVALHANDLE;
  220. if (IsBadWritePtr (lpChannelCaps, sizeof (CHANNEL_CAPS)))
  221. return DV_ERR_PARAM1;
  222. // _fmemset (lpChannelCaps, 0, sizeof (CHANNEL_CAPS));
  223. lpChannelCaps->dwFlags = 0;
  224. lpChannelCaps->dwSrcRectXMod = 0;
  225. lpChannelCaps->dwSrcRectYMod = 0;
  226. lpChannelCaps->dwSrcRectWidthMod = 0;
  227. lpChannelCaps->dwSrcRectHeightMod = 0;
  228. lpChannelCaps->dwDstRectXMod = 0;
  229. lpChannelCaps->dwDstRectYMod = 0;
  230. lpChannelCaps->dwDstRectWidthMod = 0;
  231. lpChannelCaps->dwDstRectHeightMod = 0;
  232. return videoMessage(hVideo, DVM_GET_CHANNEL_CAPS, (DWORD) lpChannelCaps,
  233. (DWORD) dwSize);
  234. }
  235. /*****************************************************************************
  236. * @doc EXTERNAL VIDEO
  237. *
  238. * @func DWORD | videoUpdate | This function directs a channel to
  239. * repaint the display. It applies only to VIDEO_EXTERNALOUT channels.
  240. *
  241. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  242. *
  243. * @parm HWND | hWnd | Specifies the handle of the window to be used
  244. * by the channel for image display.
  245. *
  246. * @parm HDC | hDC | Specifies a handle to a device context.
  247. *
  248. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  249. * an error number. The following errors are defined:
  250. * @flag DV_ERR_UNSUPPORTED | Specified message is unsupported.
  251. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  252. *
  253. * @comm This message is normally sent
  254. * whenever the client window receives a <m WM_MOVE>, <m WM_SIZE>,
  255. * or <m WM_PAINT> message.
  256. ****************************************************************************/
  257. DWORD WINAPI videoUpdate (HVIDEO hVideo, HWND hWnd, HDC hDC)
  258. {
  259. if ((!hVideo) || (!hWnd) || (!hDC) )
  260. return DV_ERR_INVALHANDLE;
  261. return videoMessage(hVideo, DVM_UPDATE, (DWORD) hWnd, (DWORD) hDC);
  262. }
  263. /*****************************************************************************
  264. * @doc EXTERNAL VIDEO
  265. *
  266. * @api DWORD | videoOpen | This function opens a channel on the
  267. * specified video device.
  268. *
  269. * @parm LPHVIDEO | lphvideo | Specifies a far pointer to a buffer
  270. * used to return an <t HVIDEO> handle. The video capture driver
  271. * uses this location to return
  272. * a handle that uniquely identifies the opened video device channel.
  273. * Use the returned handle to identify the device channel when
  274. * calling other video functions.
  275. *
  276. * @parm DWORD | dwDeviceID | Identifies the video device to open.
  277. * The value of <p dwDeviceID> varies from zero to one less
  278. * than the number of video capture devices installed in the system.
  279. *
  280. * @parm DWORD | dwFlags | Specifies flags for opening the device.
  281. * The following flags are defined:
  282. *
  283. * @flag VIDEO_EXTERNALIN| Specifies the channel is opened
  284. * for external input. Typically, external input channels
  285. * capture images into a frame buffer.
  286. *
  287. * @flag VIDEO_EXTERNALOUT| Specifies the channel is opened
  288. * for external output. Typically, external output channels
  289. * display images stored in a frame buffer on an auxilary monitor
  290. * or overlay.
  291. *
  292. * @flag VIDEO_IN| Specifies the channel is opened
  293. * for video input. Video input channels transfer images
  294. * from a frame buffer to system memory buffers.
  295. *
  296. * @flag VIDEO_OUT| Specifies the channel is opened
  297. * for video output. Video output channels transfer images
  298. * from system memory buffers to a frame buffer.
  299. *
  300. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  301. * an error number. The following errors are defined:
  302. * @flag DV_ERR_BADDEVICEID | Indicates the specified device ID is out of range.
  303. * @flag DV_ERR_ALLOCATED | Indicates the specified resource is already allocated.
  304. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  305. *
  306. * @comm
  307. * At a minimum, all capture drivers support a VIDEO_EXTERNALIN
  308. * and a VIDEO_IN channel.
  309. * Use <f videoGetNumDevs> to determine the number of video
  310. * devices present in the system.
  311. *
  312. * @xref <f videoClose>
  313. ****************************************************************************/
  314. DWORD WINAPI videoOpen (LPHVIDEO lphVideo, DWORD dwDeviceID, DWORD dwFlags)
  315. {
  316. TCHAR szKey[sizeof(szVideo)/sizeof(TCHAR) + 2];
  317. TCHAR szbuf[128];
  318. UINT w;
  319. VIDEO_OPEN_PARMS vop; // Same as IC_OPEN struct!!!
  320. DWORD dwVersion = VIDEOAPIVERSION;
  321. if (IsBadWritePtr ((LPVOID) lphVideo, sizeof (HVIDEO)) )
  322. return DV_ERR_PARAM1;
  323. vop.dwSize = sizeof (VIDEO_OPEN_PARMS);
  324. vop.fccType = OPEN_TYPE_VCAP; // "vcap"
  325. vop.fccComp = 0L;
  326. vop.dwVersion = VIDEOAPIVERSION;
  327. vop.dwFlags = dwFlags; // In, Out, External In, External Out
  328. vop.dwError = DV_ERR_OK;
  329. w = (WORD)dwDeviceID;
  330. *lphVideo = NULL;
  331. if (!wTotalVideoDevs) // trying to open without finding how many devs.
  332. videoGetNumDevs();
  333. if (!wTotalVideoDevs) // No drivers installed
  334. return DV_ERR_BADINSTALL;
  335. if (w >= MAXVIDEODRIVERS)
  336. return DV_ERR_BADDEVICEID;
  337. #ifndef NOTHUNKS
  338. //
  339. // if it's one of the 32-bit indices then we must open it on the
  340. // 32-bit side or fail.
  341. //
  342. if (w < wVideoDevs32) {
  343. return videoOpen32( lphVideo, dwDeviceID, dwFlags);
  344. } else {
  345. // make it a valid 16-bit index
  346. w -= wVideoDevs32;
  347. }
  348. #endif // NOTHUNKS
  349. // ignore the fake MSVideo copied from [Drivers32]
  350. if (bVideo0Invalid) {
  351. w++;
  352. }
  353. lstrcpy(szKey, szVideo);
  354. szKey[(sizeof(szVideo)/sizeof(TCHAR)) - 1] = (TCHAR)0;
  355. if( w > 0 ) {
  356. szKey[(sizeof(szVideo)/sizeof(TCHAR))] = (TCHAR)0;
  357. szKey[(sizeof(szVideo)/sizeof(TCHAR))-1] = (TCHAR) TEXT('1' + (w-1) ); // driver ordinal
  358. }
  359. if (GetPrivateProfileString(szDrivers, szKey, szNull,
  360. szbuf, sizeof(szbuf)/sizeof(TCHAR), szSystemIni)) {
  361. #ifdef THIS_IS_ANCIENT_CODE
  362. // Removed for VFW1.1
  363. // Only early Alpha 1.0 drivers required this...
  364. // Check driver version number by doing a configuration open...
  365. // Version 1 used LPARAM = dwFlags
  366. // Version 2 uses LPARAM = LPVIDEO_OPEN_PARMS
  367. if (hVideoTemp = OpenDriver(szKey, szDrivers, (LPARAM) NULL)) {
  368. HVIDEO hVideoTemp;
  369. // Version 1 drivers had the added bug of returning
  370. // the version from this message, instead of in
  371. // lParam1
  372. if (videoMessage (hVideoTemp, DVM_GETVIDEOAPIVER,
  373. (LPARAM) (LPVOID) &dwVersion, 0L) == 1)
  374. dwVersion = 1;
  375. CloseDriver(hVideoTemp, 0L, 0L );
  376. }
  377. if (dwVersion == 1)
  378. *lphVideo = OpenDriver(szKey, szDrivers, dwFlags);
  379. else
  380. #endif // THIS_IS_ANCIENT_CODE
  381. *lphVideo = OpenDriver(szKey, szDrivers, (LPARAM) (LPVOID) &vop);
  382. if( ! *lphVideo ) {
  383. if (vop.dwError) // if driver returned an error code...
  384. return vop.dwError;
  385. else {
  386. #ifdef WIN32
  387. if (GetFileAttributes(szbuf) == (DWORD) -1)
  388. #else
  389. OFSTRUCT of;
  390. if (OpenFile (szbuf, &of, OF_EXIST) == HFILE_ERROR)
  391. #endif
  392. return (DV_ERR_BADINSTALL);
  393. else
  394. return (DV_ERR_NOTDETECTED);
  395. }
  396. }
  397. } else {
  398. return( DV_ERR_BADINSTALL );
  399. }
  400. return DV_ERR_OK;
  401. }
  402. typedef struct tagVS_VERSION
  403. {
  404. WORD wTotLen;
  405. WORD wValLen;
  406. TCHAR szSig[16];
  407. VS_FIXEDFILEINFO vffInfo;
  408. } VS_VERSION;
  409. //
  410. // videoGetDriverDesc -
  411. //
  412. // private api to correctly thunk avicap's capGetDriverDescription.
  413. //
  414. // if the index is < wVideoDevs32, then thunk the call through to the
  415. // 32-bit side, otherwise do it here by scanning [drivers].
  416. //
  417. DWORD WINAPI videoCapDriverDescAndVer (
  418. DWORD wDriverIndex,
  419. LPSTR lpszName, UINT cbName,
  420. LPSTR lpszVer, UINT cbVer)
  421. {
  422. LPTSTR lpVersion;
  423. UINT wVersionLen;
  424. BOOL bRetCode;
  425. TCHAR szGetName[MAX_PATH];
  426. DWORD dwVerInfoSize;
  427. DWORD dwVerHnd;
  428. TCHAR szBuf[MAX_PATH];
  429. BOOL fGetName;
  430. BOOL fGetVersion;
  431. static TCHAR szNull[] = TEXT("");
  432. static TCHAR szVideo[] = TEXT("msvideo");
  433. static TCHAR szSystemIni[] = TEXT("system.ini");
  434. static TCHAR szDrivers[] = TEXT("Drivers");
  435. static TCHAR szKey[sizeof(szVideo)/sizeof(TCHAR) + 2];
  436. static TCHAR szVer[] = TEXT("ver.dll");
  437. static TCHAR szGetFileVerInfo[] = TEXT("GetFileVersionInfo");
  438. static TCHAR szGetFileVerInfoSize[] = TEXT("GetFileVersionInfoSize");
  439. static TCHAR szVerQueryValue[] = TEXT("VerQueryValue");
  440. typedef BOOL (WINAPI FAR *LPVERQUERYVALUE)(
  441. const void FAR* pBlock,
  442. LPCSTR lpSubBlock,
  443. void FAR* FAR* lplpBuffer,
  444. UINT FAR* lpuLen
  445. );
  446. typedef BOOL (WINAPI FAR *LPGETFILEVERSIONINFO)(
  447. LPCSTR lpstrFilename,
  448. DWORD dwHandle,
  449. DWORD dwLen,
  450. void FAR* lpData
  451. );
  452. typedef DWORD (WINAPI FAR *LPGETFILEVERSIONINFOSIZE)(
  453. LPCSTR lpstrFilename,
  454. DWORD FAR *lpdwHandle
  455. );
  456. LPGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize;
  457. LPGETFILEVERSIONINFO lpfnGetFileVersionInfo;
  458. LPVERQUERYVALUE lpfnVerQueryValue;
  459. HINSTANCE hinstVer;
  460. #ifndef NOTHUNKS
  461. // must have called videoGetNumDevs first before thunking
  462. if (!wTotalVideoDevs) {
  463. videoGetNumDevs();
  464. }
  465. if (wDriverIndex < wVideoDevs32) {
  466. return videoGetDriverDesc32(wDriverIndex, lpszName, (short) cbName,
  467. lpszVer, (short) cbVer);
  468. } else {
  469. wDriverIndex -= wVideoDevs32;
  470. if (bVideo0Invalid) {
  471. wDriverIndex++;
  472. }
  473. }
  474. #endif
  475. //this is a 16-bit driver - search [Drivers] for it
  476. fGetName = lpszName != NULL && cbName != 0;
  477. fGetVersion = lpszVer != NULL && cbVer != 0;
  478. if (fGetName)
  479. lpszName[0] = TEXT('\0');
  480. if (fGetVersion)
  481. lpszVer [0] = TEXT('\0');
  482. lstrcpy(szKey, szVideo);
  483. szKey[sizeof(szVideo)/sizeof(TCHAR) - 1] = TEXT('\0');
  484. if( wDriverIndex > 0 ) {
  485. szKey[sizeof(szVideo)/sizeof(TCHAR)] = TEXT('\0');
  486. szKey[(sizeof(szVideo)/sizeof(TCHAR))-1] = (TCHAR)(TEXT('1') + (wDriverIndex-1) ); // driver ordinal
  487. }
  488. if (GetPrivateProfileString(szDrivers, szKey, szNull,
  489. szBuf, sizeof(szBuf)/sizeof(TCHAR), szSystemIni) < 2)
  490. return FALSE;
  491. // Copy in the driver name initially, just in case the driver
  492. // has omitted a description field.
  493. if (fGetName)
  494. lstrcpyn(lpszName, szBuf, cbName);
  495. hinstVer = LoadLibrary(szVer);
  496. if ( hinstVer == NULL) {
  497. return FALSE;
  498. }
  499. *(FARPROC *)&lpfnGetFileVersionInfoSize =
  500. GetProcAddress(hinstVer, szGetFileVerInfoSize);
  501. *(FARPROC *)&lpfnGetFileVersionInfo =
  502. GetProcAddress(hinstVer, szGetFileVerInfo);
  503. *(FARPROC *)&lpfnVerQueryValue =
  504. GetProcAddress(hinstVer, szVerQueryValue );
  505. #if 0
  506. {
  507. char szBuffer[256];
  508. wsprintf( szBuffer, "hinstVer = %#X\r\n", hinstVer );
  509. OutputDebugString(szBuffer);
  510. wsprintf( szBuffer, "lpfnGetFileVersionInfoSize = %#X\r\n",
  511. lpfnGetFileVersionInfoSize );
  512. OutputDebugString(szBuffer);
  513. wsprintf( szBuffer, "lpfnGetFileVersionInfo = %#X\r\n",
  514. lpfnGetFileVersionInfo );
  515. OutputDebugString(szBuffer);
  516. wsprintf( szBuffer, "lpfnVerQueryValue = %#X\r\n",
  517. lpfnVerQueryValue );
  518. OutputDebugString(szBuffer);
  519. }
  520. #endif
  521. // You must find the size first before getting any file info
  522. dwVerInfoSize =
  523. (*lpfnGetFileVersionInfoSize)(szBuf, &dwVerHnd);
  524. if (dwVerInfoSize) {
  525. LPTSTR lpstrVffInfo; // Pointer to block to hold info
  526. HANDLE hMem; // handle to mem alloc'ed
  527. // Get a block big enough to hold version info
  528. hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  529. lpstrVffInfo = GlobalLock(hMem);
  530. // Get the File Version first
  531. if( (*lpfnGetFileVersionInfo)(szBuf, 0L, dwVerInfoSize, lpstrVffInfo)) {
  532. VS_VERSION FAR *pVerInfo = (VS_VERSION FAR *) lpstrVffInfo;
  533. // fill in the file version
  534. wsprintf(szBuf,
  535. TEXT("Version: %d.%d.%d.%d"),
  536. HIWORD(pVerInfo->vffInfo.dwFileVersionMS),
  537. LOWORD(pVerInfo->vffInfo.dwFileVersionMS),
  538. HIWORD(pVerInfo->vffInfo.dwFileVersionLS),
  539. LOWORD(pVerInfo->vffInfo.dwFileVersionLS));
  540. if (fGetVersion)
  541. lstrcpyn (lpszVer, szBuf, cbVer);
  542. }
  543. // Now try to get the FileDescription
  544. // First try this for the "Translation" entry, and then
  545. // try the American english translation.
  546. // Keep track of the string length for easy updating.
  547. // 040904E4 represents the language ID and the four
  548. // least significant digits represent the codepage for
  549. // which the data is formatted. The language ID is
  550. // composed of two parts: the low ten bits represent
  551. // the major language and the high six bits represent
  552. // the sub language.
  553. lstrcpy(szGetName, TEXT("\\StringFileInfo\\040904E4\\FileDescription"));
  554. wVersionLen = 0;
  555. lpVersion = NULL;
  556. // Look for the corresponding string.
  557. bRetCode = (*lpfnVerQueryValue)((LPVOID)lpstrVffInfo,
  558. (LPTSTR)szGetName,
  559. (void FAR* FAR*)&lpVersion,
  560. (UINT FAR *) &wVersionLen);
  561. if (fGetName && bRetCode && wVersionLen && lpVersion)
  562. lstrcpyn (lpszName, lpVersion, cbName);
  563. // Let go of the memory
  564. GlobalUnlock(hMem);
  565. GlobalFree(hMem);
  566. }
  567. FreeLibrary(hinstVer);
  568. return TRUE;
  569. }
  570. /*****************************************************************************
  571. * @doc EXTERNAL VIDEO
  572. *
  573. * @api DWORD | videoClose | This function closes the specified video
  574. * device channel.
  575. *
  576. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  577. * If this function is successful, the handle is invalid
  578. * after this call.
  579. *
  580. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  581. * an error number. The following errors are defined:
  582. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  583. * @flag DV_ERR_NONSPECIFIC | The driver failed to close the channel.
  584. *
  585. * @comm If buffers have been sent with <f videoStreamAddBuffer> and
  586. * they haven't been returned to the application,
  587. * the close operation fails. You can use <f videoStreamReset> to mark all
  588. * pending buffers as done.
  589. *
  590. * @xref <f videoOpen> <f videoStreamInit> <f videoStreamFini> <f videoStreamReset>
  591. ****************************************************************************/
  592. DWORD WINAPI videoClose (HVIDEO hVideo)
  593. {
  594. if (!hVideo)
  595. return DV_ERR_INVALHANDLE;
  596. #ifndef NOTHUNKS
  597. if (Is32bitHandle(hVideo)) {
  598. return videoClose32(Map32bitHandle(hVideo));
  599. }
  600. #endif // NOTHUNKS
  601. return (CloseDriver(hVideo, 0L, 0L ) ? DV_ERR_OK : DV_ERR_NONSPECIFIC);
  602. }
  603. /*****************************************************************************
  604. * @doc EXTERNAL VIDEO
  605. *
  606. * @api DWORD | videoConfigure | This function sets or retrieves
  607. * the options for a configurable driver.
  608. *
  609. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  610. *
  611. * @parm UINT | msg | Specifies the option to set or retrieve. The
  612. * following options are defined:
  613. *
  614. * @flag DVM_PALETTE | Indicates a palette is being sent to the driver
  615. * or retrieved from the driver.
  616. *
  617. * @flag DVM_PALETTERGB555 | Indicates an RGB555 palette is being
  618. * sent to the driver.
  619. *
  620. * @flag DVM_FORMAT | Indicates format information is being sent to
  621. * the driver or retrieved from the driver.
  622. *
  623. * @parm DWORD | dwFlags | Specifies flags for configuring or
  624. * interrogating the device driver. The following flags are defined:
  625. *
  626. * @flag VIDEO_CONFIGURE_SET | Indicates values are being sent to the driver.
  627. *
  628. * @flag VIDEO_CONFIGURE_GET | Indicates values are being obtained from the driver.
  629. *
  630. * @flag VIDEO_CONFIGURE_QUERY | Determines if the
  631. * driver supports the option specified by <p msg>. This flag
  632. * should be combined with either the VIDEO_CONFIGURE_SET or
  633. * VIDEO_CONFIGURE_GET flag. If this flag is
  634. * set, the <p lpData1>, <p dwSize1>, <p lpData2>, and <p dwSize2>
  635. * parameters are ignored.
  636. *
  637. * @flag VIDEO_CONFIGURE_QUERYSIZE | Returns the size, in bytes,
  638. * of the configuration option in <p lpdwReturn>. This flag is only valid if
  639. * the VIDEO_CONFIGURE_GET flag is also set.
  640. *
  641. * @flag VIDEO_CONFIGURE_CURRENT | Requests the current value.
  642. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  643. * @flag VIDEO_CONFIGURE_NOMINAL | Requests the nominal value.
  644. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  645. * @flag VIDEO_CONFIGURE_MIN | Requests the minimum value.
  646. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  647. * @flag VIDEO_CONFIGURE_MAX | Get the maximum value.
  648. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  649. *
  650. * @parm LPDWORD | lpdwReturn | Points to a DWORD used for returning information
  651. * from the driver. If
  652. * the VIDEO_CONFIGURE_QUERYSIZE flag is set, <p lpdwReturn> is
  653. * filled with the size of the configuration option.
  654. *
  655. * @parm LPVOID | lpData1 |Specifies a pointer to message specific data.
  656. *
  657. * @parm DWORD | dwSize1 | Specifies the size, in bytes, of the <p lpData1>
  658. * buffer.
  659. *
  660. * @parm LPVOID | lpData2 | Specifies a pointer to message specific data.
  661. *
  662. * @parm DWORD | dwSize2 | Specifies the size, in bytes, of the <p lpData2>
  663. * buffer.
  664. *
  665. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  666. * an error number. The following errors are defined:
  667. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  668. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  669. *
  670. * @xref <f videoOpen> <f videoMessage>
  671. *
  672. ****************************************************************************/
  673. DWORD WINAPI videoConfigure (HVIDEO hVideo, UINT msg, DWORD dwFlags,
  674. LPDWORD lpdwReturn, LPVOID lpData1, DWORD dwSize1,
  675. LPVOID lpData2, DWORD dwSize2)
  676. {
  677. VIDEOCONFIGPARMS vcp;
  678. if (!hVideo)
  679. return DV_ERR_INVALHANDLE;
  680. if (lpData1)
  681. if (IsBadHugeReadPtr (lpData1, dwSize1))
  682. return DV_ERR_CONFIG1;
  683. if (lpData2)
  684. if (IsBadHugeReadPtr (lpData2, dwSize2))
  685. return DV_ERR_CONFIG2;
  686. if (dwFlags & VIDEO_CONFIGURE_QUERYSIZE) {
  687. if (!lpdwReturn)
  688. return DV_ERR_NONSPECIFIC;
  689. if (IsBadWritePtr (lpdwReturn, sizeof (DWORD)) )
  690. return DV_ERR_NONSPECIFIC;
  691. }
  692. vcp.lpdwReturn = lpdwReturn;
  693. vcp.lpData1 = lpData1;
  694. vcp.dwSize1 = dwSize1;
  695. vcp.lpData2 = lpData2;
  696. vcp.dwSize2 = dwSize2;
  697. return videoMessage(hVideo, msg, dwFlags,
  698. (DWORD)(LPVIDEOCONFIGPARMS)&vcp );
  699. }
  700. /*****************************************************************************
  701. * @doc EXTERNAL VIDEO
  702. *
  703. * @api DWORD | videoConfigureStorage | This function saves or loads
  704. * all configurable options for a channel. Options
  705. * can be saved and recalled for each application or each application
  706. * instance.
  707. *
  708. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  709. *
  710. * @parm LPSTR | lpstrIdent | Identifies the application or instance.
  711. * Use an arbitrary string which uniquely identifies your application
  712. * or instance.
  713. *
  714. * @parm DWORD | dwFlags | Specifies any flags for the function. The following
  715. * flags are defined:
  716. * @flag VIDEO_CONFIGURE_GET | Requests that the values be loaded.
  717. * @flag VIDEO_CONFIGURE_SET | Requests that the values be saved.
  718. *
  719. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  720. * an error number. The following errors are defined:
  721. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  722. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  723. *
  724. * @comm The method used by a driver to save configuration options is
  725. * device dependent.
  726. *
  727. * @xref <f videoOpen>
  728. ****************************************************************************/
  729. DWORD WINAPI videoConfigureStorage (HVIDEO hVideo,
  730. LPSTR lpstrIdent, DWORD dwFlags)
  731. {
  732. if (!hVideo)
  733. return DV_ERR_INVALHANDLE;
  734. return videoMessage(hVideo, DVM_CONFIGURESTORAGE,
  735. (DWORD)lpstrIdent, dwFlags);
  736. }
  737. /*****************************************************************************
  738. * @doc EXTERNAL VIDEO
  739. *
  740. * @api DWORD | videoDialog | This function displays a channel-specific
  741. * dialog box used to set configuration parameters.
  742. *
  743. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  744. *
  745. * @parm HWND | hWndParent | Specifies the parent window handle.
  746. *
  747. * @parm DWORD | dwFlags | Specifies flags for the dialog box. The
  748. * following flag is defined:
  749. * @flag VIDEO_DLG_QUERY | If this flag is set, the driver immediately
  750. * returns zero if it supplies a dialog box for the channel,
  751. * or DV_ERR_NOTSUPPORTED if it does not.
  752. *
  753. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  754. * an error number. The following errors are defined:
  755. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  756. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  757. *
  758. * @comm Typically, each dialog box displayed by this
  759. * function lets the user select options appropriate for the channel.
  760. * For example, a VIDEO_IN channel dialog box lets the user select
  761. * the image dimensions and bit depth.
  762. *
  763. * @xref <f videoOpen> <f videoConfigureStorage>
  764. ****************************************************************************/
  765. DWORD WINAPI videoDialog (HVIDEO hVideo, HWND hWndParent, DWORD dwFlags)
  766. {
  767. if (!hVideo)
  768. return DV_ERR_INVALHANDLE;
  769. if ((!hWndParent) || (!IsWindow (hWndParent)) )
  770. return DV_ERR_INVALHANDLE;
  771. return videoMessage(hVideo, DVM_DIALOG, (DWORD)hWndParent, dwFlags);
  772. }
  773. //////////////////////////////////////////////////////////////////////////
  774. //////////////////////////////////////////////////////////////////////////
  775. /*****************************************************************************
  776. * @doc INTERNAL VIDEO
  777. *
  778. * @api DWORD | videoPrepareHeader | This function prepares the
  779. * header and data
  780. * by performing a <f GlobalPageLock>.
  781. *
  782. * @rdesc Returns zero if the function was successful. Otherwise, it
  783. * specifies an error number.
  784. ****************************************************************************/
  785. DWORD WINAPI videoPrepareHeader(LPVIDEOHDR lpVideoHdr, DWORD dwSize)
  786. {
  787. if (!HugePageLock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR)))
  788. return DV_ERR_NOMEM;
  789. if (!HugePageLock(lpVideoHdr->lpData, lpVideoHdr->dwBufferLength)) {
  790. HugePageUnlock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR));
  791. return DV_ERR_NOMEM;
  792. }
  793. lpVideoHdr->dwFlags |= VHDR_PREPARED;
  794. return DV_ERR_OK;
  795. }
  796. /*****************************************************************************
  797. * @doc INTERNAL VIDEO
  798. *
  799. * @api DWORD | videoUnprepareHeader | This function unprepares the header and
  800. * data if the driver returns DV_ERR_NOTSUPPORTED.
  801. *
  802. * @rdesc Currently always returns DV_ERR_OK.
  803. ****************************************************************************/
  804. DWORD WINAPI videoUnprepareHeader(LPVIDEOHDR lpVideoHdr, DWORD dwSize)
  805. {
  806. HugePageUnlock(lpVideoHdr->lpData, lpVideoHdr->dwBufferLength);
  807. HugePageUnlock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR));
  808. lpVideoHdr->dwFlags &= ~VHDR_PREPARED;
  809. return DV_ERR_OK;
  810. }
  811. //////////////////////////////////////////////////////////////////////////
  812. /*****************************************************************************
  813. * @doc EXTERNAL VIDEO
  814. *
  815. * @api DWORD | videoStreamAllocHdrAndBuffer | This function is used to allow
  816. * drivers to optionally allocate video buffers. Normally, the client
  817. * application is responsible for allocating buffer memory, but devices
  818. * which have on-board memory may optionally allocate headers and buffers
  819. * using this function. Generally, this will avoid an additional data copy,
  820. * resulting in faster capture rates.
  821. *
  822. * @parm HVIDEO | hVideo | Specifies a handle to the video
  823. * device channel.
  824. *
  825. * @parm LPVIDEOHDR FAR * | plpvideoHdr | Specifies a pointer to the address of a
  826. * <t VIDEOHDR> structure. The driver saves the buffer address in this
  827. * location, or NULL if it cannot allocate a buffer.
  828. *
  829. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure
  830. * and associated video buffer in bytes.
  831. *
  832. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  833. * an error number. The following errors are defined:
  834. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  835. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  836. * @flag DV_ERR_NOTSUPPORTED | Indicates the driver does not have on-board memory.
  837. *
  838. * @comm If the driver
  839. * allocates buffers via this method, the <f videoStreamPrepareHeader> and
  840. * <f videoStreamUnprepareHeader> functions must not be used.
  841. *
  842. * The buffer allocated must be accessible for DMA by the host.
  843. *
  844. * @xref <f videoStreamFreeHdrAndBuffer>
  845. ****************************************************************************/
  846. DWORD WINAPI videoStreamAllocHdrAndBuffer(HVIDEO hVideo,
  847. LPVIDEOHDR FAR * plpvideoHdr, DWORD dwSize)
  848. {
  849. if (!hVideo)
  850. return DV_ERR_INVALHANDLE;
  851. return(DV_ERR_NOTSUPPORTED);
  852. #if 0
  853. if (IsBadWritePtr (plpvideoHdr, sizeof (VIDEOHDR *)) )
  854. return DV_ERR_PARAM1;
  855. *plpvideoHdr = NULL; // Init to NULL ptr
  856. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_ALLOCHDRANDBUFFER,
  857. (DWORD)plpvideoHdr, (DWORD)dwSize);
  858. if (*plpvideoHdr == NULL ||
  859. IsBadHugeWritePtr (*plpvideoHdr, dwSize)) {
  860. DebugErr(DBF_WARNING,"videoStreamAllocHdrAndBuffer: Allocation failed.");
  861. *plpvideoHdr = NULL;
  862. return wRet;
  863. }
  864. if (IsVideoHeaderPrepared(HVIDEO, *plpvideoHdr))
  865. {
  866. DebugErr(DBF_WARNING,"videoStreamAllocHdrAndBuffer: header is already prepared.");
  867. return DV_ERR_OK;
  868. }
  869. (*plpvideoHdr)->dwFlags = 0;
  870. if (wRet == DV_ERR_OK)
  871. MarkVideoHeaderPrepared(hVideo, *plpvideoHdr);
  872. return wRet;
  873. #endif
  874. }
  875. /*****************************************************************************
  876. * @doc EXTERNAL VIDEO
  877. *
  878. * @api DWORD | videoStreamFreeHdrAndBuffer | This function is used to free
  879. * buffers allocated by the driver using the <f videoStreamAllocHdrAndBuffer>
  880. * function.
  881. *
  882. * @parm HVIDEO | hVideo | Specifies a handle to the video
  883. * device channel.
  884. *
  885. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to the
  886. * <t VIDEOHDR> structure and associated buffer to be freed.
  887. *
  888. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  889. * an error number. The following errors are defined:
  890. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  891. * @flag DV_ERR_NOTSUPPORTED | Indicates the driver does not have on-board memory.
  892. *
  893. * @comm If the driver
  894. * allocates buffers via this method, the <f videoStreamPrepareHeader> and
  895. * <f videoStreamUnprepareHeader> functions must not be used.
  896. *
  897. * @xref <f videoStreamAllocHdrAndBuffer>
  898. ****************************************************************************/
  899. DWORD WINAPI videoStreamFreeHdrAndBuffer(HVIDEO hVideo,
  900. LPVIDEOHDR lpvideoHdr)
  901. {
  902. if (!hVideo)
  903. return DV_ERR_INVALHANDLE;
  904. return(DV_ERR_NOTSUPPORTED);
  905. #if 0
  906. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  907. return DV_ERR_PARAM1;
  908. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  909. {
  910. DebugErr(DBF_WARNING, "videoStreamFreeHdrAndBuffer: buffer still in queue.");
  911. return DV_ERR_STILLPLAYING;
  912. }
  913. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  914. {
  915. DebugErr(DBF_WARNING,"videoStreamFreeHdrAndBuffer: header is not prepared.");
  916. }
  917. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_FREEHDRANDBUFFER,
  918. (DWORD)lpvideoHdr, (DWORD)0);
  919. if (wRet != DV_ERR_OK)
  920. {
  921. DebugErr(DBF_WARNING,"videoStreamFreeHdrAndBuffer: Error freeing buffer.");
  922. }
  923. return wRet;
  924. #endif
  925. }
  926. //////////////////////////////////////////////////////////////////////////
  927. /*****************************************************************************
  928. * @doc EXTERNAL VIDEO
  929. *
  930. * @api DWORD | videoStreamPrepareHeader | This function prepares a buffer
  931. * for video streaming.
  932. *
  933. * @parm HVIDEO | hVideo | Specifies a handle to the video
  934. * device channel.
  935. *
  936. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to a
  937. * <t VIDEOHDR> structure identifying the buffer to be prepared.
  938. *
  939. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  940. *
  941. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  942. * an error number. The following errors are defined:
  943. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  944. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  945. *
  946. * @comm Use this function after <f videoStreamInit> or
  947. * after <f videoStreamReset> to prepare the data buffers
  948. * for streaming data.
  949. *
  950. * The <t VIDEOHDR> data structure and the data block pointed to by its
  951. * <e VIDEOHDR.lpData> member must be allocated with <f GlobalAlloc> using the
  952. * GMEM_MOVEABLE and GMEM_SHARE flags, and locked with <f GlobalLock>.
  953. * Preparing a header that has already been prepared will have no effect
  954. * and the function will return zero. Typically, this function is used
  955. * to ensure that the buffer will be available for use at interrupt time.
  956. *
  957. * @xref <f videoStreamUnprepareHeader>
  958. ****************************************************************************/
  959. DWORD WINAPI videoStreamPrepareHeader(HVIDEO hVideo,
  960. LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  961. {
  962. DWORD wRet;
  963. if (!hVideo)
  964. return DV_ERR_INVALHANDLE;
  965. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  966. return DV_ERR_PARAM1;
  967. if (IsVideoHeaderPrepared(HVIDEO, lpvideoHdr))
  968. {
  969. DebugErr(DBF_WARNING,"videoStreamPrepareHeader: header is already prepared.");
  970. return DV_ERR_OK;
  971. }
  972. lpvideoHdr->dwFlags = 0;
  973. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_PREPAREHEADER,
  974. (DWORD)lpvideoHdr, (DWORD)dwSize);
  975. #ifndef NOTHUNKS
  976. //
  977. // 32-bit side can't do the locking but needs it locked
  978. //
  979. if (wRet == DV_ERR_OK && Is32bitHandle(hVideo))
  980. wRet = videoPrepareHeader(lpvideoHdr, dwSize);
  981. #endif // NOTHUNKS
  982. if (wRet == DV_ERR_NOTSUPPORTED)
  983. wRet = videoPrepareHeader(lpvideoHdr, dwSize);
  984. if (wRet == DV_ERR_OK)
  985. MarkVideoHeaderPrepared(hVideo, lpvideoHdr);
  986. return wRet;
  987. }
  988. /*****************************************************************************
  989. * @doc EXTERNAL VIDEO
  990. *
  991. * @api DWORD | videoStreamUnprepareHeader | This function clears the
  992. * preparation performed by <f videoStreamPrepareHeader>.
  993. *
  994. * @parm HVIDEO | hVideo | Specifies a handle to the video
  995. * device channel.
  996. *
  997. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to a <t VIDEOHDR>
  998. * structure identifying the data buffer to be unprepared.
  999. *
  1000. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  1001. *
  1002. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1003. * an error number. The following errors are defined:
  1004. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1005. * @flag DV_ERR_STILLPLAYING | Indicates the structure identified by <p lpvideoHdr>
  1006. * is still in the queue.
  1007. *
  1008. * @comm This function is the complementary function to <f videoStreamPrepareHeader>.
  1009. * You must call this function before freeing the data buffer with <f GlobalFree>.
  1010. * After passing a buffer to the device driver with <f videoStreamAddBuffer>, you
  1011. * must wait until the driver is finished with the buffer before calling
  1012. * <f videoStreamUnprepareHeader>. Unpreparing a buffer that has not been
  1013. * prepared or has been already unprepared has no effect,
  1014. * and the function returns zero.
  1015. *
  1016. * @xref <f videoStreamPrepareHeader>
  1017. ****************************************************************************/
  1018. DWORD WINAPI videoStreamUnprepareHeader(HVIDEO hVideo, LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  1019. {
  1020. DWORD wRet;
  1021. if (!hVideo)
  1022. return DV_ERR_INVALHANDLE;
  1023. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1024. return DV_ERR_PARAM1;
  1025. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  1026. {
  1027. DebugErr(DBF_WARNING, "videoStreamUnprepareHeader: buffer still in queue.");
  1028. return DV_ERR_STILLPLAYING;
  1029. }
  1030. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  1031. {
  1032. DebugErr(DBF_WARNING,"videoStreamUnprepareHeader: header is not prepared.");
  1033. return DV_ERR_OK;
  1034. }
  1035. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_UNPREPAREHEADER,
  1036. (DWORD)lpvideoHdr, (DWORD)dwSize);
  1037. #ifndef NOTHUNKS
  1038. //
  1039. // 32-bit side can't do the unlocking but needs it unlocked
  1040. //
  1041. if (wRet == DV_ERR_OK && Is32bitHandle(hVideo))
  1042. wRet = videoUnprepareHeader(lpvideoHdr, dwSize);
  1043. #endif // NOTHUNKS
  1044. if (wRet == DV_ERR_NOTSUPPORTED)
  1045. wRet = videoUnprepareHeader(lpvideoHdr, dwSize);
  1046. if (wRet == DV_ERR_OK)
  1047. MarkVideoHeaderUnprepared(hVideo, lpvideoHdr);
  1048. return wRet;
  1049. }
  1050. /*****************************************************************************
  1051. * @doc EXTERNAL VIDEO
  1052. *
  1053. * @api DWORD | videoStreamAddBuffer | This function sends a buffer to a
  1054. * video-capture device. After the buffer is filled by the device,
  1055. * the device sends it back to the application.
  1056. *
  1057. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1058. *
  1059. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a far pointer to a <t VIDEOHDR>
  1060. * structure that identifies the buffer.
  1061. *
  1062. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  1063. *
  1064. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1065. * an error number. The following errors are defined:
  1066. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1067. * @flag DV_ERR_UNPREPARED | Indicates the <p lpvideoHdr> structure hasn't been prepared.
  1068. * @flag DV_ERR_STILLPLAYING | Indicates a buffer is still in the queue.
  1069. * @flag DV_ERR_PARAM1 | The <p lpvideoHdr> parameter is invalid or
  1070. * the <e VIDEOHDR.dwBufferLength> member of the <t VIDEOHDR>
  1071. * structure is not set to the proper value.
  1072. *
  1073. * @comm The data buffer must be prepared with <f videoStreamPrepareHeader>
  1074. * before it is passed to <f videoStreamAddBuffer>. The <t VIDEOHDR> data
  1075. * structure and the data buffer referenced by its <e VIDEOHDR.lpData>
  1076. * member must be allocated with <f GlobalAlloc> using the GMEM_MOVEABLE
  1077. * and GMEM_SHARE flags, and locked with <f GlobalLock>. Set the
  1078. * <e VIDEOHDR.dwBufferLength> member to the size of the header.
  1079. *
  1080. * @xref <f videoStreamPrepareHeader>
  1081. ****************************************************************************/
  1082. DWORD WINAPI videoStreamAddBuffer(HVIDEO hVideo, LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  1083. {
  1084. if (!hVideo)
  1085. return DV_ERR_INVALHANDLE;
  1086. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1087. return DV_ERR_PARAM1;
  1088. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  1089. {
  1090. DebugErr(DBF_WARNING, "videoStreamAddBuffer: buffer not prepared.");
  1091. return DV_ERR_UNPREPARED;
  1092. }
  1093. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  1094. {
  1095. DebugErr(DBF_WARNING, "videoStreamAddBuffer: buffer already in queue.");
  1096. return DV_ERR_STILLPLAYING;
  1097. }
  1098. return (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_ADDBUFFER, (DWORD)lpvideoHdr, (DWORD)dwSize);
  1099. }
  1100. /*****************************************************************************
  1101. * @doc EXTERNAL VIDEO
  1102. *
  1103. * @api DWORD | videoStreamStop | This function stops streaming on a video channel.
  1104. *
  1105. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1106. * device channel.
  1107. *
  1108. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1109. * an error number. The following error is defined:
  1110. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1111. *
  1112. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1113. * function.
  1114. * @comm If there are any buffers in the queue, the current buffer will be
  1115. * marked as done (the <e VIDEOHDR.dwBytesRecorded> member in
  1116. * the <t VIDEOHDR> header will contain the actual length of data), but any
  1117. * empty buffers in the queue will remain there. Calling this
  1118. * function when the channel is not started has no effect, and the
  1119. * function returns zero.
  1120. *
  1121. * @xref <f videoStreamStart> <f videoStreamReset>
  1122. ****************************************************************************/
  1123. DWORD WINAPI videoStreamStop(HVIDEO hVideo)
  1124. {
  1125. if (!hVideo)
  1126. return DV_ERR_INVALHANDLE;
  1127. return videoMessage((HVIDEO)hVideo, DVM_STREAM_STOP, 0L, 0L);
  1128. }
  1129. /*****************************************************************************
  1130. * @doc EXTERNAL VIDEO
  1131. *
  1132. * @api DWORD | videoStreamReset | This function stops streaming
  1133. * on the specified video device channel and resets the current position
  1134. * to zero. All pending buffers are marked as done and
  1135. * are returned to the application.
  1136. *
  1137. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1138. *
  1139. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1140. * an error number. The following errors are defined:
  1141. *
  1142. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1143. *
  1144. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1145. * function.
  1146. *
  1147. * @xref <f videoStreamReset> <f videoStreamStop> <f videoStreamAddBuffer> <f videoStreamClose>
  1148. /****************************************************************************/
  1149. DWORD WINAPI videoStreamReset(HVIDEO hVideo)
  1150. {
  1151. if (!hVideo)
  1152. return DV_ERR_INVALHANDLE;
  1153. return videoMessage((HVIDEO)hVideo, DVM_STREAM_RESET, 0L, 0L);
  1154. }
  1155. /*****************************************************************************
  1156. * @doc EXTERNAL VIDEO
  1157. *
  1158. * @api DWORD | videoStreamGetPosition | This function retrieves the current
  1159. * position of the specified video device channel.
  1160. *
  1161. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1162. *
  1163. * @parm LPMMTIME | lpInfo | Specifies a far pointer to an <t MMTIME>
  1164. * structure.
  1165. *
  1166. * @parm DWORD | dwSize | Specifies the size of the <t MMTIME> structure in bytes.
  1167. *
  1168. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1169. * an error number. The following errors are defined:
  1170. *
  1171. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1172. *
  1173. * @comm Before using <f videoStreamGetPosition>, set the
  1174. * <e MMTIME.wType> member of the <t MMTIME> structure to indicate
  1175. * the time format desired. After
  1176. * <f videoStreamGetPosition> returns, check the <e MMTIME.wType>
  1177. * member to determine if the your time format is supported. If
  1178. * not, <e MMTIME.wType> specifies an alternate format.
  1179. * Video capture drivers typically provide the millisecond time
  1180. * format.
  1181. *
  1182. * The position is set to zero when streaming is started with
  1183. * <f videoStreamStart>.
  1184. ****************************************************************************/
  1185. DWORD WINAPI videoStreamGetPosition(HVIDEO hVideo, LPMMTIME lpInfo, DWORD dwSize)
  1186. {
  1187. if (!hVideo)
  1188. return DV_ERR_INVALHANDLE;
  1189. if (IsBadWritePtr (lpInfo, sizeof (MMTIME)) )
  1190. return DV_ERR_PARAM1;
  1191. return videoMessage(hVideo, DVM_STREAM_GETPOSITION,
  1192. (DWORD)lpInfo, (DWORD)dwSize);
  1193. }
  1194. // ============================================
  1195. /*****************************************************************************
  1196. * @doc EXTERNAL VIDEO
  1197. *
  1198. * @api DWORD | videoStreamInit | This function initializes a video
  1199. * device channel for streaming.
  1200. *
  1201. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1202. *
  1203. * @parm DWORD | dwMicroSecPerFrame | Specifies the number of microseconds
  1204. * between frames.
  1205. *
  1206. * @parm DWORD | dwCallback | Specifies the address of a callback
  1207. * function or a handle to a window called during video
  1208. * streaming. The callback function or window processes
  1209. * messages related to the progress of streaming.
  1210. *
  1211. * @parm DWORD | dwCallbackInstance | Specifies user
  1212. * instance data passed to the callback function. This parameter is not
  1213. * used with window callbacks.
  1214. *
  1215. * @parm DWORD | dwFlags | Specifies flags for opening the device channel.
  1216. * The following flags are defined:
  1217. * @flag CALLBACK_WINDOW | If this flag is specified, <p dwCallback> is
  1218. * a window handle.
  1219. * @flag CALLBACK_FUNCTION | If this flag is specified, <p dwCallback> is
  1220. * a callback procedure address.
  1221. *
  1222. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1223. * an error number. The following errors are defined:
  1224. * @flag DV_ERR_BADDEVICEID | Indicates the device ID specified in
  1225. * <p hVideo> is not valid.
  1226. * @flag DV_ERR_ALLOCATED | Indicates the resource specified is already allocated.
  1227. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  1228. *
  1229. * @comm If a window or function is chosen to receive callback information, the following
  1230. * messages are sent to it to indicate the
  1231. * progress of video input:
  1232. *
  1233. * <m MM_DRVM_OPEN> is sent at the time of <f videoStreamInit>
  1234. *
  1235. * <m MM_DRVM_CLOSE> is sent at the time of <f videoStreamFini>
  1236. *
  1237. * <m MM_DRVM_DATA> is sent when a buffer of image data is available
  1238. *
  1239. * <m MM_DRVM_ERROR> is sent when an error occurs
  1240. *
  1241. * Callback functions must reside in a DLL.
  1242. * You do not have to use <f MakeProcInstance> to get
  1243. * a procedure-instance address for the callback function.
  1244. *
  1245. * @cb void CALLBACK | videoFunc | <f videoFunc> is a placeholder for an
  1246. * application-supplied function name. The actual name must be exported by
  1247. * including it in an EXPORTS statement in the DLL's module-definition file.
  1248. * This is used only when a callback function is specified in
  1249. * <f videoStreamInit>.
  1250. *
  1251. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel
  1252. * associated with the callback.
  1253. *
  1254. * @parm DWORD | wMsg | Specifies the <m MM_DRVM_> messages. Messages indicate
  1255. * errors and when image data is available. For information on
  1256. * these messages, see <f videoStreamInit>.
  1257. *
  1258. * @parm DWORD | dwInstance | Specifies the user instance
  1259. * data specified with <f videoStreamInit>.
  1260. *
  1261. * @parm DWORD | dwParam1 | Specifies a parameter for the message.
  1262. *
  1263. * @parm DWORD | dwParam2 | Specifies a parameter for the message.
  1264. *
  1265. * @comm Because the callback is accessed at interrupt time, it must reside
  1266. * in a DLL and its code segment must be specified as FIXED in the
  1267. * module-definition file for the DLL. Any data the callback accesses
  1268. * must be in a FIXED data segment as well. The callback may not make any
  1269. * system calls except for <f PostMessage>, <f timeGetSystemTime>,
  1270. * <f timeGetTime>, <f timeSetEvent>, <f timeKillEvent>,
  1271. * <f midiOutShortMsg>, <f midiOutLongMsg>, and <f OutputDebugStr>.
  1272. *
  1273. * @xref <f videoOpen> <f videoStreamFini> <f videoClose>
  1274. ****************************************************************************/
  1275. DWORD WINAPI videoStreamInit(HVIDEO hVideo,
  1276. DWORD dwMicroSecPerFrame, DWORD dwCallback,
  1277. DWORD dwCallbackInst, DWORD dwFlags)
  1278. {
  1279. VIDEO_STREAM_INIT_PARMS vsip;
  1280. if (!hVideo)
  1281. return DV_ERR_INVALHANDLE;
  1282. if (dwCallback && ((dwFlags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) ) {
  1283. if (IsBadCodePtr ((FARPROC) dwCallback) )
  1284. return DV_ERR_PARAM2;
  1285. if (!dwCallbackInst)
  1286. return DV_ERR_PARAM2;
  1287. }
  1288. if (dwCallback && ((dwFlags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) ) {
  1289. if (!IsWindow((HWND) LOWORD (dwCallback)) )
  1290. return DV_ERR_PARAM2;
  1291. }
  1292. vsip.dwMicroSecPerFrame = dwMicroSecPerFrame;
  1293. vsip.dwCallback = dwCallback;
  1294. vsip.dwCallbackInst = dwCallbackInst;
  1295. vsip.dwFlags = dwFlags;
  1296. vsip.hVideo = (DWORD)hVideo;
  1297. return videoMessage(hVideo, DVM_STREAM_INIT,
  1298. (DWORD) (LPVIDEO_STREAM_INIT_PARMS) &vsip,
  1299. (DWORD) sizeof (VIDEO_STREAM_INIT_PARMS));
  1300. }
  1301. /*****************************************************************************
  1302. * @doc EXTERNAL VIDEO
  1303. *
  1304. * @api DWORD | videoStreamFini | This function terminates streaming
  1305. * from the specified device channel.
  1306. *
  1307. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1308. *
  1309. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1310. * an error number. The following errors are defined:
  1311. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1312. * @flag DV_ERR_STILLPLAYING | Indicates there are still buffers in the queue.
  1313. *
  1314. * @comm If there are buffers that have been sent with
  1315. * <f videoStreamAddBuffer> that haven't been returned to the application,
  1316. * this operation will fail. Use <f videoStreamReset> to return all
  1317. * pending buffers.
  1318. *
  1319. * Each call to <f videoStreamInit> must be matched with a call to
  1320. * <f videoStreamFini>.
  1321. *
  1322. * For VIDEO_EXTERNALIN channels, this function is used to
  1323. * halt capturing of data to the frame buffer.
  1324. *
  1325. * For VIDEO_EXTERNALOUT channels supporting overlay,
  1326. * this function is used to disable the overlay.
  1327. *
  1328. * @xref <f videoStreamInit>
  1329. ****************************************************************************/
  1330. DWORD WINAPI videoStreamFini(HVIDEO hVideo)
  1331. {
  1332. if (!hVideo)
  1333. return DV_ERR_INVALHANDLE;
  1334. return videoMessage(hVideo, DVM_STREAM_FINI, 0L, 0L);
  1335. }
  1336. /*****************************************************************************
  1337. * @doc EXTERNAL VIDEO
  1338. *
  1339. * @api DWORD | videoStreamStart | This function starts streaming on the
  1340. * specified video device channel.
  1341. *
  1342. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1343. *
  1344. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1345. * an error number. The following errors are defined:
  1346. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1347. *
  1348. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1349. * function.
  1350. *
  1351. * @xref <f videoStreamReset> <f videoStreamStop> <f videoStreamAddBuffer> <f videoStreamClose>
  1352. /****************************************************************************/
  1353. DWORD WINAPI videoStreamStart(HVIDEO hVideo)
  1354. {
  1355. if (!hVideo)
  1356. return DV_ERR_INVALHANDLE;
  1357. return videoMessage(hVideo, DVM_STREAM_START, 0L, 0L);
  1358. }
  1359. /*****************************************************************************
  1360. * @doc EXTERNAL VIDEO
  1361. *
  1362. * @api DWORD | videoStreamGetError | This function returns the error
  1363. * most recently encountered.
  1364. *
  1365. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1366. *
  1367. * @parm LPDWORD | lpdwErrorID | Specifies a far pointer to the <t DWORD>
  1368. * used to return the error ID.
  1369. *
  1370. * @parm LPDWORD | lpdwErrorValue | Specifies a far pointer to the <t DWORD>
  1371. * used to return the number of frames skipped.
  1372. *
  1373. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1374. * an error number. The following error is defined:
  1375. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1376. *
  1377. * @comm While streaming video data, a capture
  1378. * driver can fill buffers faster than the client application can
  1379. * save the buffers to disk. In this case, the
  1380. * DV_ERR_NO_BUFFERS error is returned in <p lpdwErrorID>
  1381. * and <p lpdwErrorValue> contains a count of the number of
  1382. * frames missed. After
  1383. * receiving this message and returning the error status, a driver
  1384. * should reset its internal error flag to DV_ERR_OK and
  1385. * the count of missed frames to zero.
  1386. *
  1387. * Applications should send this message frequently during capture
  1388. * since some drivers which do not have access to interrupts use
  1389. * this message to trigger buffer processing.
  1390. *
  1391. * @xref <f videoOpen>
  1392. /****************************************************************************/
  1393. DWORD WINAPI videoStreamGetError(HVIDEO hVideo, LPDWORD lpdwError,
  1394. LPDWORD lpdwFramesSkipped)
  1395. {
  1396. if (!hVideo)
  1397. return DV_ERR_INVALHANDLE;
  1398. if (IsBadWritePtr (lpdwError, sizeof (DWORD)) )
  1399. return DV_ERR_PARAM1;
  1400. if (IsBadWritePtr (lpdwFramesSkipped, sizeof (DWORD)) )
  1401. return DV_ERR_PARAM2;
  1402. return videoMessage(hVideo, DVM_STREAM_GETERROR, (DWORD) lpdwError,
  1403. (DWORD) lpdwFramesSkipped);
  1404. }
  1405. /*****************************************************************************
  1406. * @doc EXTERNAL VIDEO
  1407. *
  1408. * @api DWORD | videoFrame | This function transfers a single frame
  1409. * to or from a video device channel.
  1410. *
  1411. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1412. * The channel must be of type VIDEO_IN or VIDEO_OUT.
  1413. *
  1414. * @parm LPVIDEOHDR | lpVHdr | Specifies a far pointer to an <t VIDEOHDR>
  1415. * structure.
  1416. *
  1417. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1418. * an error number. The following errors are defined:
  1419. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  1420. * @flag DV_ERR_PARAM1 | The <p lpVDHdr> parameter is invalid or
  1421. * the <e VIDEOHDR.dwBufferLength> member of the <t VIDEOHDR>
  1422. * structure is not set to the proper value.
  1423. *
  1424. * @comm Use this function with a VIDEO_IN channel to transfer a single
  1425. * image from the frame buffer.
  1426. * Use this function with a VIDEO_OUT channel to transfer a single
  1427. * image to the frame buffer.
  1428. *
  1429. * @xref <f videoOpen>
  1430. /****************************************************************************/
  1431. DWORD WINAPI videoFrame (HVIDEO hVideo, LPVIDEOHDR lpVHdr)
  1432. {
  1433. if (!hVideo)
  1434. return DV_ERR_INVALHANDLE;
  1435. if (!lpVHdr)
  1436. return DV_ERR_PARAM1;
  1437. if (IsBadWritePtr (lpVHdr, sizeof (VIDEOHDR)) )
  1438. return DV_ERR_PARAM1;
  1439. return videoMessage(hVideo, DVM_FRAME, (DWORD) lpVHdr,
  1440. sizeof(VIDEOHDR));
  1441. }
  1442. /**************************************************************************
  1443. * @doc INTERNAL VIDEO
  1444. *
  1445. * @api void | videoCleanup | clean up video stuff
  1446. * called in MSVIDEOs WEP()
  1447. *
  1448. **************************************************************************/
  1449. void FAR PASCAL videoCleanup(HTASK hTask)
  1450. {
  1451. #ifndef NOTHUNKS
  1452. LRESULT FAR PASCAL ICSendMessage32(DWORD hic, UINT msg, DWORD dwP1, DWORD dwP2);
  1453. // Special internal message to give the 32 bit side a chance to clean
  1454. // up -- which it may or may not need
  1455. videoMessage32(0, DVM_START-1, (DWORD)hTask, 0);
  1456. ICSendMessage32(0, DRV_USER-1, (DWORD)hTask, 0);
  1457. return;
  1458. #endif
  1459. }
  1460.