Windows NT 4.0 source code leak
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.

922 lines
24 KiB

4 years ago
  1. //==========================================================================;
  2. // thunk32.c
  3. //
  4. // Copyright (c) 1991-1994 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // Description:
  7. // This module contains routines for thunking the video APIs
  8. // from 16-bit Windows to 32-bit WOW.
  9. //
  10. // History:
  11. //
  12. //==========================================================================;
  13. /*
  14. WOW Thunking design:
  15. Thunks are generated as follows :
  16. 16-bit :
  17. */
  18. #include <windows.h>
  19. #include <windowsx.h>
  20. #include <mmsystem.h>
  21. #include <mmddk.h>
  22. #include <mmreg.h>
  23. #include <memory.h>
  24. #include <win32.h>
  25. #ifdef _WIN32
  26. #include <ivideo32.h>
  27. #else
  28. #include <msvideo.h>
  29. #endif
  30. #include <msviddrv.h>
  31. #include <msvideoi.h>
  32. #ifdef _WIN32
  33. #include <wownt32.h>
  34. #include <stdlib.h> // for mbstowcs and wcstombs
  35. #include <video16.h>
  36. #ifdef UNICODE
  37. #include "profile.h" // NT only (for now?)
  38. #endif
  39. #endif // WIN32
  40. // in capinit.c
  41. BOOL capInternalGetDriverDescA(UINT wDriverIndex,
  42. LPSTR lpszName, int cbName,
  43. LPSTR lpszVer, int cbVer);
  44. //
  45. // pick up the function definitions
  46. //
  47. #include "vidthunk.h"
  48. #ifdef DEBUG
  49. #define MODNAME "AVICAP32"
  50. int videoDebugLevel = -1;
  51. void videoDebugInit(VOID)
  52. {
  53. if (videoDebugLevel == -1)
  54. videoDebugLevel = GetProfileIntA("Debug", MODNAME, 0);
  55. }
  56. #else
  57. #define videoDebugInit()
  58. #endif
  59. /* -------------------------------------------------------------------------
  60. ** Handle and memory mapping functions.
  61. ** -------------------------------------------------------------------------
  62. */
  63. LPWOWHANDLE32 lpWOWHandle32;
  64. LPWOWHANDLE16 lpWOWHandle16;
  65. LPWOWCALLBACK16 lpWOWCallback16;
  66. LPGETVDMPOINTER GetVdmPointer;
  67. int ThunksInitialized;
  68. #ifdef WIN32
  69. #ifdef DEBUG
  70. void FAR cdecl thkdprintf(LPSTR szFormat, ...)
  71. {
  72. char ach[128];
  73. va_list va;
  74. #define MARKER "AVICAP (thunk): "
  75. lstrcpyA(ach, MARKER);
  76. va_start(va, szFormat);
  77. wvsprintfA(ach+sizeof(MARKER), szFormat, va);
  78. va_end(va);
  79. OutputDebugStringA(ach);
  80. }
  81. #endif
  82. #endif
  83. //
  84. // Useful functions
  85. //
  86. //
  87. // CopyAlloc - allocate a new piece of memory, and copy the data in
  88. // Must use LocalFree to release the memory later
  89. //
  90. PVOID CopyAlloc(PVOID pvSrc, UINT uSize)
  91. {
  92. PVOID pvDest;
  93. pvDest = (PVOID)LocalAlloc(LMEM_FIXED, uSize);
  94. if (pvDest != NULL) {
  95. CopyMemory(pvDest, pvSrc, uSize);
  96. }
  97. return pvDest;
  98. }
  99. /*
  100. * Copy data from source to dest where source is a 32bit pointer
  101. * and dest is a 16bit pointer
  102. */
  103. void CopyTo16Bit(LPVOID Dest16, LPVOID Src32, DWORD Length)
  104. {
  105. PVOID Dest32;
  106. if (Src32 == NULL) {
  107. return;
  108. }
  109. Dest32 = GetVdmPointer((DWORD)Dest16, Length, TRUE);
  110. CopyMemory(Dest32, Src32, Length);
  111. }
  112. /*
  113. * Copy data from source to dest where source is a 16bit pointer
  114. * and dest is a 32bit pointer
  115. */
  116. void CopyTo32Bit(LPVOID Dest32, LPVOID Src16, DWORD Length)
  117. {
  118. PVOID Src32;
  119. if (Src16 == NULL) {
  120. return;
  121. }
  122. Src32 = GetVdmPointer((DWORD)Src16, Length, TRUE);
  123. CopyMemory(Dest32, Src32, Length);
  124. }
  125. /*
  126. * Copy data from source to dest where source is a 16bit pointer
  127. * and dest is a 32bit pointer ONLY if the source is not aligned
  128. *
  129. * Returns which pointer to use (src or dest)
  130. */
  131. LPVOID CopyIfNotAligned(LPVOID Dest32, LPVOID Src16, DWORD Length)
  132. {
  133. PVOID Src32;
  134. if (Src16 == NULL) {
  135. return Dest32;
  136. }
  137. Src32 = GetVdmPointer((DWORD)Src16, Length, TRUE);
  138. CopyMemory(Dest32, Src32, Length);
  139. return Dest32;
  140. }
  141. typedef struct _callback {
  142. WORD flags;
  143. WORD hVideo16;
  144. WORD msg;
  145. DWORD dwCallback16inst;
  146. DWORD dw1;
  147. DWORD dw2;
  148. } CALLBACK16;
  149. typedef CALLBACK16 * PCALLBACK16;
  150. /*
  151. * Callbacks
  152. */
  153. void MyVideoCallback(HANDLE handle,
  154. UINT msg,
  155. DWORD dwUser,
  156. DWORD dw1,
  157. DWORD dw2)
  158. {
  159. PVIDEOINSTANCEDATA32 pInst;
  160. BOOL fFree = FALSE;
  161. pInst = (PVIDEOINSTANCEDATA32)dwUser;
  162. DPF3(("Video callback - handle = %8X, msg = %8X, dwUser = %8X, dw1 = %8X, dw2 = %8X\n",
  163. handle, msg, dwUser, dw1, dw2));
  164. switch (msg) {
  165. /*
  166. * What are the parameters for these messages ??
  167. */
  168. case MM_DRVM_OPEN:
  169. /*
  170. * We get this when we INIT_STREAM
  171. */
  172. break;
  173. case MM_DRVM_CLOSE:
  174. /*
  175. * Device is closing - this is where we free our structures
  176. * (just in case the 32-bit side called close to clean up).
  177. * dwUser points to our data
  178. */
  179. fFree = TRUE;
  180. break;
  181. case MM_DRVM_DATA:
  182. /*
  183. * We have data - this means a buffer has been returned in
  184. * dw1
  185. */
  186. {
  187. PVIDEOHDR32 pHdr32;
  188. pHdr32 = CONTAINING_RECORD((PVIDEOHDR)dw1,
  189. VIDEOHDR32,
  190. videoHdr);
  191. dw1 = (DWORD)pHdr32->pHdr16; // For callback below
  192. /*
  193. * Map back the data and free our structure
  194. */
  195. {
  196. VIDEOHDR Hdr16;
  197. Hdr16 = pHdr32->videoHdr;
  198. Hdr16.lpData = pHdr32->lpData16;
  199. memcpy(pHdr32->pHdr32, (LPVOID)&Hdr16, sizeof(VIDEOHDR));
  200. }
  201. /*
  202. * Clean up our local structure
  203. */
  204. LocalFree((HLOCAL)pHdr32);
  205. }
  206. break;
  207. case MM_DRVM_ERROR:
  208. /*
  209. * dw1 = frames skipped - unfortunately there's nobody to tell!
  210. */
  211. break;
  212. }
  213. /*
  214. * Call back the application if appropriate
  215. */
  216. switch (pInst->dwFlags & CALLBACK_TYPEMASK) {
  217. case CALLBACK_WINDOW:
  218. PostMessage(ThunkHWND(LOWORD(pInst->dwCallback)),
  219. msg, (WPARAM)handle, (LPARAM)dw1);
  220. break;
  221. case CALLBACK_FUNCTION:
  222. #if 0
  223. // Must call a generic 16 bit callback passing a pointer to
  224. // a parameter array.
  225. {
  226. WORD hMem;
  227. PCALLBACK16 pCallStruct;
  228. pCallStruct = WOWGlobalAllocLock16(0, sizeof(CALLBACK16), &hMem);
  229. if (pCallStruct) {
  230. pCallStruct->flags = HIWORD(pInst->dwFlags);
  231. pCallStruct->hVideo16 = (WORD)pInst->hVideo;
  232. pCallStruct->msg = (WORD)msg;
  233. pCallStruct->dwCallback16inst = pInst->dwCallbackInst;
  234. pCallStruct->dw1 = (DWORD)dw1;
  235. pCallStruct->dw2 = (DWORD)dw2;
  236. lpWOWCallback16(pInst->dwCallback, pCallStruct);
  237. // Now free off the callback structure
  238. WOWGlobalUnlockFree16(pCallStruct);
  239. }
  240. }
  241. #endif
  242. break;
  243. }
  244. if (fFree) {
  245. LocalFree((HLOCAL)pInst);
  246. }
  247. }
  248. //
  249. // Thunking callbacks to WOW32 (or wherever)
  250. //
  251. //--------------------------------------------------------------------------;
  252. //
  253. // DWORD videoThunk32
  254. //
  255. // Description:
  256. //
  257. // 32-bit function dispatcher for thunks.
  258. //
  259. // Arguments:
  260. // DWORD dwThunkId:
  261. //
  262. // DWORD dw1:
  263. //
  264. // DWORD dw2:
  265. //
  266. // DWORD dw3:
  267. //
  268. // DWORD dw4:
  269. //
  270. // Return (DWORD):
  271. //
  272. // History:
  273. //
  274. //--------------------------------------------------------------------------;
  275. DWORD videoThunk32(DWORD dwThunkId,DWORD dw1,DWORD dw2,DWORD dw3,DWORD dw4)
  276. {
  277. //
  278. // Make sure we've got thunking functionality
  279. //
  280. if (ThunksInitialized <= 0) {
  281. HMODULE hMod;
  282. if (ThunksInitialized == -1) {
  283. return MMSYSERR_ERROR;
  284. }
  285. videoDebugInit();
  286. hMod = GetModuleHandle(GET_MAPPING_MODULE_NAME);
  287. if (hMod != NULL) {
  288. GetVdmPointer =
  289. (LPGETVDMPOINTER)GetProcAddress(hMod, GET_VDM_POINTER_NAME);
  290. lpWOWHandle32 =
  291. (LPWOWHANDLE32)GetProcAddress(hMod, GET_HANDLE_MAPPER32 );
  292. lpWOWHandle16 =
  293. (LPWOWHANDLE16)GetProcAddress(hMod, GET_HANDLE_MAPPER16 );
  294. lpWOWCallback16 =
  295. (LPWOWCALLBACK16)GetProcAddress(hMod, GET_CALLBACK16 );
  296. }
  297. if ( GetVdmPointer == NULL
  298. || lpWOWHandle16 == NULL
  299. || lpWOWHandle32 == NULL ) {
  300. ThunksInitialized = -1;
  301. return MMSYSERR_ERROR;
  302. } else {
  303. ThunksInitialized = 1;
  304. }
  305. }
  306. //
  307. // Perform the requested function
  308. //
  309. switch (dwThunkId) {
  310. case vidThunkvideoMessage32:
  311. return videoMessage32((HVIDEO)dw1, (UINT)dw2, dw3, dw4);
  312. break;
  313. case vidThunkvideoGetNumDevs32:
  314. return videoGetNumDevs32();
  315. break;
  316. case vidThunkvideoOpen32:
  317. return videoOpen32((LPHVIDEO)dw1, dw2, dw3);
  318. break;
  319. case vidThunkvideoClose32:
  320. return videoClose32((HVIDEO)dw1);
  321. break;
  322. case vidThunkvideoGetDriverDesc32:
  323. {
  324. LPSTR lpszName = NULL, lpszVer = NULL;
  325. short cbName, cbVer;
  326. DWORD dwRet;
  327. cbName = (short) LOWORD(dw4);
  328. cbVer = (short) HIWORD(dw4);
  329. // for chicago, need to call WOW32GetVdmPointerFix
  330. // (via getprocaddr!)
  331. if ((dw2 != 0) && (cbName > 0)) {
  332. lpszName = WOW32ResolveMemory(dw2);
  333. }
  334. if ((dw3 != 0) && (cbVer > 0)) {
  335. lpszVer = WOW32ResolveMemory(dw3);
  336. }
  337. dwRet = capInternalGetDriverDescA(
  338. dw1, // device id
  339. lpszName,
  340. cbName,
  341. lpszVer,
  342. cbVer);
  343. #if 0 //should do this for chicago
  344. if (lpszName) {
  345. WOWGetVDMPointerUnfix(dw2);
  346. }
  347. if (lpszVer) {
  348. WOWGetVDMPointerUnfix(dw3);
  349. }
  350. #endif
  351. return dwRet;
  352. }
  353. default:
  354. return(0);
  355. }
  356. }
  357. DWORD FAR PASCAL videoMessage32(HVIDEO hVideo, UINT msg, DWORD dwP1, DWORD dwP2)
  358. {
  359. StartThunk(videoMessage);
  360. DPF2(("\tvideoMessage id = %4X, lParam1 = %8X, lParam2 = %8X",
  361. msg, dwP1, dwP2));
  362. /*
  363. * We ONLY support (and we only ever will support) messages which
  364. * have ALREADY been defined. New 32-bit driver messages will NOT
  365. * be supported from 16-bit apps.
  366. */
  367. switch (msg) {
  368. case DVM_GETVIDEOAPIVER:
  369. {
  370. DWORD ApiVer;
  371. ReturnCode = videoMessage((HVIDEO)hVideo,
  372. (UINT)msg,
  373. (DWORD)&ApiVer,
  374. dwP2);
  375. if (ReturnCode == DV_ERR_OK) {
  376. CopyTo16Bit((LPVOID)dwP1, &ApiVer, sizeof(DWORD));
  377. }
  378. }
  379. break;
  380. case DVM_GETERRORTEXT:
  381. {
  382. VIDEO_GETERRORTEXT_PARMS vet;
  383. VIDEO_GETERRORTEXT_PARMS MappedVet;
  384. /*
  385. * Get the parameter block
  386. */
  387. CopyTo32Bit((LPVOID)&vet, (LPVOID)dwP1, sizeof(vet));
  388. MappedVet = vet;
  389. /*
  390. * Map the string pointer
  391. */
  392. MappedVet.lpText = WOW32ResolveMemory(vet.lpText);
  393. ReturnCode = videoMessage(hVideo,
  394. msg,
  395. (DWORD)&MappedVet,
  396. 0);
  397. }
  398. break;
  399. case DVM_GET_CHANNEL_CAPS:
  400. {
  401. CHANNEL_CAPS Caps;
  402. ReturnCode = videoMessage((HVIDEO)hVideo,
  403. (UINT)msg,
  404. (DWORD)&Caps,
  405. dwP2);
  406. /*
  407. * If successful return the data to the 16-bit app
  408. */
  409. if (ReturnCode == DV_ERR_OK) {
  410. CopyTo16Bit((LPVOID)dwP1, (LPVOID)&Caps,
  411. sizeof(Caps));
  412. }
  413. }
  414. break;
  415. case DVM_UPDATE:
  416. {
  417. ReturnCode = videoMessage(hVideo,
  418. msg,
  419. (DWORD)ThunkHWND(dwP1),
  420. (DWORD)ThunkHDC(dwP2));
  421. }
  422. break;
  423. case DVM_PALETTE:
  424. case DVM_PALETTERGB555:
  425. case DVM_FORMAT:
  426. /*
  427. * This stuff all comes from videoConfigure
  428. *
  429. * Let's hope this data is all DWORDs!
  430. */
  431. {
  432. VIDEOCONFIGPARMS vcp, MappedVcp;
  433. DWORD dwReturn;
  434. BOOL Ok;
  435. Ok = TRUE;
  436. CopyTo32Bit((LPVOID)&vcp, (LPVOID)dwP2, sizeof(vcp));
  437. MappedVcp.lpdwReturn = &dwReturn;
  438. MappedVcp.dwSize1 = vcp.dwSize1;
  439. MappedVcp.dwSize2 = vcp.dwSize2;
  440. /*
  441. * Get some storage to store the answer
  442. */
  443. if (MappedVcp.dwSize1 != 0) {
  444. MappedVcp.lpData1 = (LPSTR)LocalAlloc(LPTR, MappedVcp.dwSize1);
  445. if (MappedVcp.lpData1 == NULL) {
  446. Ok = FALSE;
  447. } else {
  448. if (MappedVcp.dwSize2 != 0) {
  449. MappedVcp.lpData2 = (LPSTR)LocalAlloc(LPTR, MappedVcp.dwSize2);
  450. if (MappedVcp.lpData2 == NULL) {
  451. Ok = FALSE;
  452. if (MappedVcp.dwSize1 != 0) {
  453. LocalFree((HLOCAL)MappedVcp.lpData1);
  454. }
  455. }
  456. }
  457. }
  458. }
  459. if (Ok) {
  460. CopyTo32Bit(MappedVcp.lpData1, vcp.lpData1, MappedVcp.dwSize1);
  461. CopyTo32Bit(MappedVcp.lpData2, vcp.lpData2, MappedVcp.dwSize2);
  462. ReturnCode = videoMessage(hVideo,
  463. msg,
  464. dwP1,
  465. (DWORD)&MappedVcp);
  466. if (ReturnCode == DV_ERR_OK) {
  467. if (vcp.lpdwReturn != NULL) {
  468. CopyTo16Bit(vcp.lpdwReturn, MappedVcp.lpdwReturn,
  469. sizeof(DWORD));
  470. }
  471. CopyTo16Bit(vcp.lpData1, MappedVcp.lpData1, MappedVcp.dwSize1);
  472. CopyTo16Bit(vcp.lpData2, MappedVcp.lpData2, MappedVcp.dwSize2);
  473. }
  474. if (MappedVcp.dwSize1 != 0) {
  475. LocalFree((HLOCAL)MappedVcp.lpData1);
  476. }
  477. if (MappedVcp.dwSize2 != 0) {
  478. LocalFree((HLOCAL)MappedVcp.lpData2);
  479. }
  480. } else {
  481. ReturnCode = DV_ERR_NOMEM;
  482. }
  483. }
  484. break;
  485. case DVM_CONFIGURESTORAGE:
  486. {
  487. LPSTR lpStrIdent;
  488. lpStrIdent = WOW32ResolveMemory(dwP1);
  489. ReturnCode = videoMessage(hVideo,
  490. msg,
  491. (DWORD)lpStrIdent,
  492. dwP2);
  493. }
  494. break;
  495. case DVM_DIALOG:
  496. {
  497. ReturnCode = videoMessage(hVideo,
  498. msg,
  499. (DWORD)ThunkHWND(dwP1),
  500. dwP2);
  501. }
  502. break;
  503. case DVM_SRC_RECT:
  504. case DVM_DST_RECT:
  505. /*
  506. * If it's a query only then don't bother with the
  507. * rectangle
  508. */
  509. if (dwP2 & VIDEO_CONFIGURE_QUERY) {
  510. ReturnCode = videoMessage(hVideo,
  511. msg,
  512. dwP1,
  513. dwP2);
  514. } else {
  515. /*
  516. * The rectangle is regarded as 'in' and 'out'
  517. * We need to translate between 16-bit and 32-bit rectangle structures
  518. */
  519. RECT_SHORT SRect;
  520. RECT Rect;
  521. CopyTo32Bit((LPVOID)&SRect, (LPVOID)dwP1, sizeof(SRect));
  522. SHORT_RECT_TO_RECT(Rect, SRect);
  523. ReturnCode = videoMessage(hVideo,
  524. msg,
  525. (DWORD)&Rect,
  526. dwP2);
  527. if (ReturnCode == DV_ERR_OK) {
  528. RECT_TO_SHORT_RECT(SRect, Rect);
  529. CopyTo16Bit((LPVOID)dwP1, (LPVOID)&SRect, sizeof(SRect));
  530. }
  531. }
  532. break;
  533. case DVM_STREAM_PREPAREHEADER:
  534. case DVM_STREAM_UNPREPAREHEADER:
  535. case DVM_FRAME:
  536. case DVM_STREAM_ADDBUFFER:
  537. {
  538. VIDEOHDR Hdr32;
  539. LPBYTE pData16, pData32;
  540. DWORD dwSize;
  541. dwSize = (UINT)msg == DVM_FRAME ? sizeof(VIDEOHDR) :
  542. min(dwP2, sizeof(VIDEOHDR));
  543. CopyTo32Bit((LPVOID)&Hdr32, (LPVOID)dwP1, dwSize);
  544. pData16 = Hdr32.lpData;
  545. /*
  546. * Create a mapping for the pointer
  547. */
  548. pData32 = GetVdmPointer((DWORD)pData16, Hdr32.dwBufferLength, TRUE);
  549. Hdr32.lpData = pData32;
  550. if (msg == DVM_STREAM_ADDBUFFER) {
  551. PVIDEOHDR32 pHdr32;
  552. /*
  553. * Allocate our callback structure and pass this
  554. * as our header (suitably offset to the video header part).
  555. */
  556. pHdr32 = (PVIDEOHDR32)LocalAlloc(LPTR, sizeof(VIDEOHDR32));
  557. if (pHdr32 == NULL) {
  558. ReturnCode = DV_ERR_NOMEM;
  559. } else {
  560. /*
  561. * Remember the old header so we can pass it back
  562. * and the old data pointer so we can flush it
  563. */
  564. pHdr32->pHdr16 = (LPVOID)dwP1;
  565. /*
  566. * Some systems can't handle GetVdmPointer at interrupt
  567. * time so get a pointer here
  568. */
  569. pHdr32->pHdr32 = WOW32ResolveMemory(dwP1);
  570. pHdr32->lpData16 = pData16;
  571. pHdr32->videoHdr = Hdr32;
  572. ReturnCode = videoMessage(hVideo,
  573. msg,
  574. (DWORD)&pHdr32->videoHdr,
  575. dwP2);
  576. /*
  577. * If everything was OK copy it back
  578. */
  579. if (ReturnCode == DV_ERR_OK) {
  580. Hdr32.lpData = pData16;
  581. CopyTo16Bit((LPVOID)dwP1, (LPVOID)&Hdr32, dwSize);
  582. }
  583. }
  584. } else {
  585. /*
  586. * Prepare/unprepare the header for 32bit
  587. */
  588. ReturnCode = videoMessage(hVideo,
  589. msg,
  590. (DWORD)&Hdr32,
  591. dwP2);
  592. /*
  593. * If everything was OK copy it back
  594. */
  595. if (ReturnCode == DV_ERR_OK) {
  596. Hdr32.lpData = pData16;
  597. CopyTo16Bit((LPVOID)dwP1, (LPVOID)&Hdr32, dwSize);
  598. }
  599. }
  600. }
  601. break;
  602. case DVM_STREAM_RESET:
  603. case DVM_STREAM_FINI:
  604. case DVM_STREAM_STOP:
  605. case DVM_STREAM_START:
  606. /*
  607. * Note that the MM_DRVM_CLOSE message will cause us to clean up our
  608. * callback structures on DVM_STREAM_FINI.
  609. */
  610. ReturnCode = videoMessage(hVideo,
  611. msg,
  612. 0,
  613. 0);
  614. break;
  615. case DVM_STREAM_GETPOSITION:
  616. {
  617. MMTIME mmTime;
  618. MMTIME16 mmTime16;
  619. ReturnCode = videoMessage(hVideo,
  620. msg,
  621. (DWORD)&mmTime,
  622. sizeof(mmTime));
  623. if (ReturnCode == DV_ERR_OK) {
  624. mmTime16.wType = (WORD)mmTime.wType;
  625. CopyMemory((LPVOID)&mmTime16.u,
  626. (LPVOID)&mmTime.u, sizeof(mmTime16.u));
  627. CopyTo16Bit((LPVOID)dwP1, (LPVOID)&mmTime16,
  628. min(sizeof(mmTime16), dwP2));
  629. }
  630. }
  631. break;
  632. case DVM_STREAM_INIT:
  633. {
  634. VIDEO_STREAM_INIT_PARMS vsip;
  635. VIDEO_STREAM_INIT_PARMS * pvsip = WOW32ResolveMemory(dwP1);
  636. PVIDEOINSTANCEDATA32 pInst32;
  637. #if 0
  638. // always do callback
  639. if (!(pvsip->dwFlags & CALLBACK_TYPEMASK)) {
  640. // No callback wanted by the 16 bit code. Pass call
  641. // straight through
  642. ReturnCode = videoMessage((HVIDEO)hVideo,
  643. (UINT)msg,
  644. (DWORD)pvsip,
  645. (DWORD)dwP2);
  646. } else
  647. #endif
  648. {
  649. // We set up a callback to a 32 bit routine, that in
  650. // turn will callback to the 16 bit function/window
  651. pInst32 = (PVIDEOINSTANCEDATA32)
  652. LocalAlloc(LPTR, sizeof(VIDEOINSTANCEDATA32));
  653. if (pInst32 == NULL) {
  654. ReturnCode = DV_ERR_NOMEM;
  655. } else {
  656. CopyTo32Bit((LPVOID)&vsip, (LPVOID)dwP1,
  657. min(sizeof(vsip), dwP2));
  658. pInst32->dwFlags = vsip.dwFlags;
  659. pInst32->dwCallbackInst = vsip.dwCallbackInst;
  660. pInst32->dwCallback = vsip.dwCallback;
  661. pInst32->hVideo = (HVIDEO16)vsip.hVideo;
  662. /*
  663. * Make up our own parms. Only set up a callback if
  664. * the user wanted one
  665. */
  666. vsip.dwCallback = (DWORD)MyVideoCallback;
  667. vsip.dwFlags = (vsip.dwFlags & ~CALLBACK_TYPEMASK) |
  668. CALLBACK_FUNCTION;
  669. vsip.dwCallbackInst = (DWORD)pInst32;
  670. ReturnCode = videoMessage((HVIDEO)hVideo,
  671. (UINT)msg,
  672. (DWORD)&vsip,
  673. (DWORD)dwP2);
  674. if (ReturnCode != DV_ERR_OK) {
  675. LocalFree((HLOCAL)pInst32);
  676. } else {
  677. // The instance block will be freed off by the
  678. // 32 bit callback routine when all over
  679. }
  680. }
  681. }
  682. }
  683. break;
  684. case DVM_STREAM_GETERROR:
  685. {
  686. DWORD dwError;
  687. DWORD dwFramesSkipped;
  688. ReturnCode = videoMessage(hVideo,
  689. msg,
  690. (DWORD)&dwError,
  691. (DWORD)&dwFramesSkipped);
  692. if (ReturnCode == DV_ERR_OK) {
  693. CopyTo16Bit((LPVOID)dwP1, &dwError, sizeof(DWORD));
  694. CopyTo16Bit((LPVOID)dwP2, &dwFramesSkipped, sizeof(DWORD));
  695. }
  696. }
  697. break;
  698. default:
  699. DPF2(("videoMessage - Message not implemented %X\n", (UINT)msg));
  700. ReturnCode = DV_ERR_NOTSUPPORTED;
  701. }
  702. EndThunk();
  703. }
  704. INLINE DWORD FAR PASCAL videoGetNumDevs32(void)
  705. {
  706. StartThunk(videoGetNumDevs);
  707. ReturnCode = videoGetNumDevs();
  708. EndThunk();
  709. }
  710. DWORD FAR PASCAL videoClose32(HVIDEO hVideo)
  711. {
  712. StartThunk(videoClose)
  713. ReturnCode = videoClose(hVideo);
  714. EndThunk();
  715. }
  716. DWORD FAR PASCAL videoOpen32(LPHVIDEO lphVideo, DWORD dwDeviceID, DWORD dwFlags)
  717. {
  718. HVIDEO hVideo;
  719. StartThunk(videoOpen);
  720. ReturnCode = videoOpen(
  721. &hVideo,
  722. dwDeviceID,
  723. dwFlags);
  724. if (ReturnCode == DV_ERR_OK) {
  725. lphVideo = WOW32ResolveMemory((PVOID)lphVideo);
  726. * (HVIDEO UNALIGNED *)lphVideo = hVideo;
  727. }
  728. EndThunk();
  729. }