2 * msvideo 16-bit functions
4 * Copyright 1998 Marcus Meissner
5 * Copyright 2000 Bradley Baetz
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/winbase16.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
39 /* Drivers32 settings */
40 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
42 /* handle16 --> handle conversions */
43 #define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16))
44 #define HIC_32(h16) ((HIC)(ULONG_PTR)(h16))
46 /* handle --> handle16 conversions */
47 #define HDRVR_16(h32) (LOWORD(h32))
48 #define HDRAWDIB_16(h32) (LOWORD(h32))
49 #define HIC_16(h32) (LOWORD(h32))
51 /***********************************************************************
52 * DrawDibOpen [MSVIDEO.102]
54 HDRAWDIB16 VFWAPI DrawDibOpen16(void)
56 return HDRAWDIB_16(DrawDibOpen());
59 /***********************************************************************
60 * DrawDibClose [MSVIDEO.103]
62 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd)
64 return DrawDibClose(HDRAWDIB_32(hdd));
67 /************************************************************************
68 * DrawDibBegin [MSVIDEO.104]
70 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst,
71 INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc,
72 INT16 dySrc, UINT16 wFlags)
74 return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi,
75 dxSrc, dySrc, wFlags);
78 /***********************************************************************
79 * DrawDibEnd [MSVIDEO.105]
81 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd)
83 return DrawDibEnd(HDRAWDIB_32(hdd));
86 /**********************************************************************
87 * DrawDibDraw [MSVIDEO.106]
89 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst,
90 INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi,
91 LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc,
92 INT16 dySrc, UINT16 wFlags)
94 return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst,
95 dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
98 /***********************************************************************
99 * DrawDibGetPalette [MSVIDEO.108]
101 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd)
103 return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd)));
106 /***********************************************************************
107 * DrawDibSetPalette [MSVIDEO.110]
109 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
111 return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal));
114 /***********************************************************************
115 * DrawDibRealize [MSVIDEO.112]
117 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
120 return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
123 /*************************************************************************
124 * DrawDibStart [MSVIDEO.118]
126 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate)
128 return DrawDibStart(HDRAWDIB_32(hdd), rate);
131 /*************************************************************************
132 * DrawDibStop [MSVIDEO.119]
134 BOOL16 VFWAPI DrawDibStop16(HDRAWDIB16 hdd)
136 return DrawDibStop(HDRAWDIB_32(hdd));
139 /***********************************************************************
140 * ICOpen [MSVIDEO.203]
142 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
144 return HIC_16(ICOpen(fccType, fccHandler, wMode));
147 /***********************************************************************
148 * _ICMessage [MSVIDEO.207]
150 LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
157 lpData = HeapAlloc(GetProcessHeap(), 0, cb);
159 TRACE("0x%08x, %u, %u, ...)\n", (DWORD) hic, msg, cb);
161 for (i = 0; i < cb / sizeof(WORD); i++)
163 lpData[i] = VA_ARG16(valist, WORD);
166 segData = MapLS(lpData);
167 ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
169 HeapFree(GetProcessHeap(), 0, lpData);
173 /***********************************************************************
174 * ICGetInfo [MSVIDEO.212]
176 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
180 TRACE("(0x%08x,%p,%d)\n", (DWORD) hic, picinfo, cb);
181 ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb);
182 TRACE(" -> 0x%08lx\n", ret);
186 /***********************************************************************
187 * ICLocate [MSVIDEO.213]
189 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
190 LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
193 return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags));
196 /***********************************************************************
197 * _ICCompress [MSVIDEO.224]
199 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags,
200 LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
201 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits,
202 LPDWORD lpckid, LPDWORD lpdwFlags,
203 LONG lFrameNum, DWORD dwFrameSize,
204 DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev,
211 TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags,
212 lpbiOutput, lpData, lpbiInput, lpBits);
214 iccmp.dwFlags = dwFlags;
216 iccmp.lpbiOutput = lpbiOutput;
217 iccmp.lpOutput = lpData;
218 iccmp.lpbiInput = lpbiInput;
219 iccmp.lpInput = lpBits;
221 iccmp.lpckid = lpckid;
222 iccmp.lpdwFlags = lpdwFlags;
223 iccmp.lFrameNum = lFrameNum;
224 iccmp.dwFrameSize = dwFrameSize;
225 iccmp.dwQuality = dwQuality;
226 iccmp.lpbiPrev = lpbiPrev;
227 iccmp.lpPrev = lpPrev;
228 seg_iccmp = MapLS(&iccmp);
229 ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS));
234 /***********************************************************************
235 * _ICDecompress [MSVIDEO.230]
237 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
238 LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
239 LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
245 TRACE("(0x%08x,%d,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat,
246 lpData, lpbi, lpBits);
248 icd.dwFlags = dwFlags;
249 icd.lpbiInput = lpbiFormat;
250 icd.lpInput = lpData;
251 icd.lpbiOutput = lpbi;
252 icd.lpOutput = lpBits;
254 segptr = MapLS(&icd);
255 ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
260 /***********************************************************************
261 * _ICDrawBegin [MSVIDEO.232]
263 DWORD VFWAPIV ICDrawBegin16(HIC16 hic, /* [in] */
264 DWORD dwFlags, /* [in] flags */
265 HPALETTE16 hpal, /* [in] palette to draw with */
266 HWND16 hwnd, /* [in] window to draw to */
267 HDC16 hdc, /* [in] HDC to draw to */
268 INT16 xDst, /* [in] destination rectangle */
269 INT16 yDst, /* [in] */
270 INT16 dxDst, /* [in] */
271 INT16 dyDst, /* [in] */
272 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */
273 INT16 xSrc, /* [in] source rectangle */
274 INT16 ySrc, /* [in] */
275 INT16 dxSrc, /* [in] */
276 INT16 dySrc, /* [in] */
277 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
278 DWORD dwScale) /* [in] */
284 TRACE ("(0x%08x,%d,0x%08x,0x%08x,0x%08x,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
285 (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc,
286 xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate,
289 icdb.dwFlags = dwFlags;
297 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
302 icdb.dwRate = dwRate;
303 icdb.dwScale = dwScale;
304 seg_icdb = MapLS(&icdb);
305 ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb,
306 sizeof(ICDRAWBEGIN16));
311 /***********************************************************************
312 * _ICDraw [MSVIDEO.234]
314 DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags,
315 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
316 LPVOID lpData, /* [???] NOTE: SEGPTR */
317 DWORD cbData, LONG lTime)
323 TRACE("(0x%08x,0x%08x,%p,%p,%d,%d)\n", (DWORD) hic, dwFlags,
324 lpFormat, lpData, cbData, lTime);
325 icd.dwFlags = dwFlags;
326 icd.lpFormat = lpFormat;
330 seg_icd = MapLS(&icd);
331 ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
336 /***********************************************************************
337 * ICGetDisplayFormat [MSVIDEO.239]
339 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
340 LPBITMAPINFOHEADER lpbiOut, INT16 depth,
343 return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
347 #define COPY(x,y) (x->y = x##16->y);
348 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
350 /******************************************************************
351 * MSVIDEO_MapICDEX16To32
355 static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam)
359 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
360 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
364 COPYPTR(icdx, lpbiSrc);
365 COPYPTR(icdx, lpSrc);
366 COPYPTR(icdx, lpbiDst);
367 COPYPTR(icdx, lpDst);
377 *lParam = (DWORD)(icdx);
381 /******************************************************************
382 * MSVIDEO_MapMsg16To32
386 static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
390 TRACE("Mapping %d\n", msg);
401 case ICM_COMPRESS_END:
402 case ICM_DECOMPRESS_END:
403 case ICM_DECOMPRESSEX_END:
405 case ICM_DRAW_START_PLAY:
406 case ICM_DRAW_STOP_PLAY:
407 case ICM_DRAW_REALIZE:
408 case ICM_DRAW_RENDERBUFFER:
412 case ICM_GETDEFAULTQUALITY:
415 case ICM_DRAW_WINDOW:
416 case ICM_GETBUFFERSWANTED:
417 *lParam1 = (DWORD)MapSL(*lParam1);
421 ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
424 ici16 = MapSL(*lParam1);
427 ici->dwSize = sizeof(ICINFO);
429 COPY(ici, fccHandler);
431 COPY(ici, dwVersion);
432 COPY(ici, dwVersionICM);
433 MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
434 MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
435 MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
436 *lParam1 = (DWORD)(ici);
437 *lParam2 = sizeof(ICINFO);
442 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
445 icc16 = MapSL(*lParam1);
449 COPYPTR(icc, lpbiOutput);
450 COPYPTR(icc, lpOutput);
451 COPYPTR(icc, lpbiInput);
452 COPYPTR(icc, lpInput);
453 COPYPTR(icc, lpckid);
454 COPYPTR(icc, lpdwFlags);
455 COPY(icc, lFrameNum);
456 COPY(icc, dwFrameSize);
457 COPY(icc, dwQuality);
458 COPYPTR(icc, lpbiPrev);
459 COPYPTR(icc, lpPrev);
461 *lParam1 = (DWORD)(icc);
462 *lParam2 = sizeof(ICCOMPRESS);
467 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
468 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
470 icd16 = MapSL(*lParam1);
474 COPYPTR(icd, lpbiInput);
475 COPYPTR(icd, lpInput);
476 COPYPTR(icd, lpbiOutput);
477 COPYPTR(icd, lpOutput);
480 *lParam1 = (DWORD)(icd);
481 *lParam2 = sizeof(ICDECOMPRESS);
484 case ICM_COMPRESS_BEGIN:
485 case ICM_COMPRESS_GET_FORMAT:
486 case ICM_COMPRESS_GET_SIZE:
487 case ICM_COMPRESS_QUERY:
488 case ICM_DECOMPRESS_GET_FORMAT:
489 case ICM_DECOMPRESS_QUERY:
490 case ICM_DECOMPRESS_BEGIN:
491 case ICM_DECOMPRESS_SET_PALETTE:
492 case ICM_DECOMPRESS_GET_PALETTE:
493 *lParam1 = (DWORD)MapSL(*lParam1);
494 *lParam2 = (DWORD)MapSL(*lParam2);
496 case ICM_DECOMPRESSEX_QUERY:
497 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
498 WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
499 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
500 * This is because of ICMessage(). Special case it?
502 LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
503 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
505 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
512 case ICM_DECOMPRESSEX_BEGIN:
513 case ICM_DECOMPRESSEX:
514 ret = MSVIDEO_MapICDEX16To32(lParam1);
515 *lParam2 = sizeof(ICDECOMPRESSEX);
519 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
520 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
524 icdb->hpal = HPALETTE_32(icdb16->hpal);
525 icdb->hwnd = HWND_32(icdb16->hwnd);
526 icdb->hdc = HDC_32(icdb16->hdc);
539 *lParam1 = (DWORD)(icdb);
540 *lParam2 = sizeof(ICDRAWBEGIN);
543 case ICM_DRAW_SUGGESTFORMAT:
545 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
546 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
551 COPYPTR(icds, lpbiIn);
552 COPYPTR(icds, lpbiSuggest);
557 icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
559 *lParam1 = (DWORD)(icds);
560 *lParam2 = sizeof(ICDRAWSUGGEST);
565 ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
566 ICDRAW *icd16 = MapSL(*lParam1);
570 COPYPTR(icd, lpFormat);
571 COPYPTR(icd, lpData);
575 *lParam1 = (DWORD)(icd);
576 *lParam2 = sizeof(ICDRAW);
583 FIXME("%d is not yet handled. Expect a crash.\n", msg);
591 /******************************************************************
592 * MSVIDEO_UnmapMsg16To32
596 static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
598 TRACE("Unmapping %d\n", msg);
600 #define UNCOPY(x, y) (x##16->y = x->y);
606 ICINFO *ici = (ICINFO*)(*lParam1);
607 ICINFO16 *ici16 = data16;
609 UNCOPY(ici, fccType);
610 UNCOPY(ici, fccHandler);
611 UNCOPY(ici, dwFlags);
612 UNCOPY(ici, dwVersion);
613 UNCOPY(ici, dwVersionICM);
614 WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
615 sizeof(ici16->szName), NULL, NULL );
616 ici16->szName[sizeof(ici16->szName)-1] = 0;
617 WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
618 sizeof(ici16->szDescription), NULL, NULL );
619 ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
620 /* This just gives garbage for some reason - BB
621 lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
623 HeapFree(GetProcessHeap(), 0, ici);
626 case ICM_DECOMPRESS_QUERY:
629 HeapFree(GetProcessHeap(), 0, x[0]);
631 HeapFree(GetProcessHeap(), 0, x[1]);
636 case ICM_DECOMPRESSEX_QUERY:
637 case ICM_DECOMPRESSEX_BEGIN:
638 case ICM_DECOMPRESSEX:
640 case ICM_DRAW_SUGGESTFORMAT:
642 HeapFree(GetProcessHeap(), 0, data16);
645 ERR("Unmapping unmapped msg %d\n", msg);
650 /***********************************************************************
651 * ICInfo [MSVIDEO.200]
653 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
657 DWORD lParam = (DWORD)lpicinfo;
658 DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
660 /* Use the mapping functions to map the ICINFO structure */
661 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
663 ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
665 MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
670 /******************************************************************
675 static LRESULT CALLBACK IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, LPARAM lp1, LPARAM lp2)
683 lp2 = (DWORD)MapLS((void*)lp2);
686 args[7] = HIWORD(hic);
687 args[6] = LOWORD(hic);
688 args[5] = HDRVR_16(hdrv);
690 args[3] = HIWORD(lp1);
691 args[2] = LOWORD(lp1);
692 args[1] = HIWORD(lp2);
693 args[0] = LOWORD(lp2);
694 WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
705 #define MAX_THUNKS 32
707 #include "pshpack1.h"
708 static struct msvideo_thunk
710 BYTE popl_eax; /* popl %eax (return address) */
711 BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
713 BYTE pushl_eax; /* pushl %eax */
714 BYTE jmp; /* ljmp WDML_InvokeCallback16 */
716 HIC16 hIC16; /* driver's handle */
720 static CRITICAL_SECTION msvideo_cs;
721 static CRITICAL_SECTION_DEBUG critsect_debug =
724 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
725 0, 0, { (DWORD_PTR)(__FILE__ ": msvideo_cs") }
727 static CRITICAL_SECTION msvideo_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
729 static struct msvideo_thunk* MSVIDEO_AddThunk(DWORD pfn16)
731 struct msvideo_thunk* thunk;
735 MSVIDEO_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*MSVIDEO_Thunks), MEM_COMMIT,
736 PAGE_EXECUTE_READWRITE);
737 if (!MSVIDEO_Thunks) return NULL;
738 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
740 thunk->popl_eax = 0x58; /* popl %eax */
741 thunk->pushl_func = 0x68; /* pushl $pfn16 */
743 thunk->pushl_eax = 0x50; /* pushl %eax */
744 thunk->jmp = 0xe9; /* jmp IC_Callback3216 */
745 thunk->callback = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1);
749 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
751 if (thunk->pfn16 == 0)
753 thunk->pfn16 = pfn16;
757 FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
761 static struct msvideo_thunk* MSVIDEO_HasThunk(HIC16 hic)
763 struct msvideo_thunk* thunk;
765 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
767 if (thunk->hIC16 == hic) return thunk;
772 /***********************************************************************
773 * ICOpenFunction [MSVIDEO.206]
775 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
778 struct msvideo_thunk* thunk;
780 EnterCriticalSection(&msvideo_cs);
781 if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler)))
783 LeaveCriticalSection(&msvideo_cs);
786 if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)thunk)))
787 thunk->hIC16 = HIC_16(hic32);
790 LeaveCriticalSection(&msvideo_cs);
791 return HIC_16(hic32);
794 /***********************************************************************
795 * ICSendMessage [MSVIDEO.205]
797 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2)
799 LRESULT ret = ICERR_BADHANDLE;
800 struct msvideo_thunk* thunk;
802 if ((thunk = MSVIDEO_HasThunk(hic)))
807 /* FIXME: original code was passing hdrv first and hic second */
808 /* but this doesn't match what IC_Callback3216 does */
809 args[7] = HIWORD(hic);
810 args[6] = LOWORD(hic);
811 args[5] = 0; /* the 32bit also sets it to NULL */
813 args[3] = HIWORD(lParam1);
814 args[2] = LOWORD(lParam1);
815 args[1] = HIWORD(lParam2);
816 args[0] = LOWORD(lParam2);
817 WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result );
822 /* map the message for a 32 bit infrastructure, and pass it along */
823 void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
825 ret = ICSendMessage(HIC_32(hic), msg, lParam1, lParam2);
827 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
832 /***********************************************************************
833 * ICClose [MSVIDEO.204]
835 LRESULT WINAPI ICClose16(HIC16 hic)
837 BOOL ret = ICClose(HIC_32(hic));
839 EnterCriticalSection(&msvideo_cs);
842 struct msvideo_thunk* thunk;
843 if ((thunk = MSVIDEO_HasThunk(hic)))
850 LeaveCriticalSection(&msvideo_cs);
854 /***********************************************************************
855 * VideoCapDriverDescAndVer [MSVIDEO.22]
857 DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
858 LPSTR buf2, WORD buf2len)
860 static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
864 char *s, buf[2048], fn[260];
867 DWORD i, cnt = 0, lRet;
873 TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
874 lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
875 if (lRet == ERROR_SUCCESS)
877 RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
878 for (i = 0; i < cnt; i++)
880 bufLen = sizeof(buf) / sizeof(buf[0]);
881 lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
882 if (lRet != ERROR_SUCCESS) continue;
883 if (strncasecmp(buf, "vid", 3)) continue;
886 lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
887 if (lRet == ERROR_SUCCESS) found = TRUE;
893 /* search system.ini if not found in the registry */
894 if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
896 for (s = buf; *s; s += strlen(s) + 1)
898 if (strncasecmp(s, "vid", 3)) continue;
900 if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
908 TRACE("No more VID* entries found nr=%d\n", nr);
911 infosize = GetFileVersionInfoSizeA(fn, &verhandle);
914 TRACE("%s has no fileversioninfo.\n", fn);
917 infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
918 if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf))
920 /* Yes, two space behind : */
921 /* FIXME: test for buflen */
922 snprintf(buf2, buf2len, "Version: %d.%d.%d.%d\n",
923 ((WORD*)infobuf)[0x0f],
924 ((WORD*)infobuf)[0x0e],
925 ((WORD*)infobuf)[0x11],
926 ((WORD*)infobuf)[0x10]
928 TRACE("version of %s is %s\n", fn, buf2);
932 TRACE("GetFileVersionInfoA failed for %s.\n", fn);
933 lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
935 /* FIXME: language problem? */
936 if (VerQueryValueA( infobuf,
942 UINT copylen = min(subblocklen,buf1len-1);
943 memcpy(buf1, subblock, copylen);
944 buf1[copylen] = '\0';
945 TRACE("VQA returned %s\n", (LPCSTR)subblock);
949 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
950 lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
952 HeapFree(GetProcessHeap(), 0, infobuf);
956 /**************************************************************************
957 * DllEntryPoint (MSVIDEO.3)
959 * MSVIDEO DLL entry point
962 BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
963 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
967 case DLL_PROCESS_ATTACH:
969 case DLL_PROCESS_DETACH:
970 DeleteCriticalSection(&msvideo_cs);
972 case DLL_THREAD_ATTACH:
973 case DLL_THREAD_DETACH:
979 /***********************************************************************
980 * MCIWndCreate(MSVIDEO.250)
982 HWND16 CDECL MCIWndCreate16(HWND16 hwnd, HINSTANCE16 hinst16,
983 DWORD style, LPSTR file)
985 return HWND_16(MCIWndCreateA(HWND_32(hwnd), 0, style, file));