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"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
38 /* Drivers32 settings */
39 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
41 /* handle16 --> handle conversions */
42 #define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16))
43 #define HIC_32(h16) ((HIC)(ULONG_PTR)(h16))
45 /* handle --> handle16 conversions */
46 #define HDRVR_16(h32) (LOWORD(h32))
47 #define HDRAWDIB_16(h32) (LOWORD(h32))
48 #define HIC_16(h32) (LOWORD(h32))
50 /***********************************************************************
51 * DrawDibOpen [MSVIDEO.102]
53 HDRAWDIB16 VFWAPI DrawDibOpen16(void)
55 return HDRAWDIB_16(DrawDibOpen());
58 /***********************************************************************
59 * DrawDibClose [MSVIDEO.103]
61 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd)
63 return DrawDibClose(HDRAWDIB_32(hdd));
66 /************************************************************************
67 * DrawDibBegin [MSVIDEO.104]
69 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst,
70 INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc,
71 INT16 dySrc, UINT16 wFlags)
73 return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi,
74 dxSrc, dySrc, wFlags);
77 /***********************************************************************
78 * DrawDibEnd [MSVIDEO.105]
80 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd)
82 return DrawDibEnd(HDRAWDIB_32(hdd));
85 /**********************************************************************
86 * DrawDibDraw [MSVIDEO.106]
88 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst,
89 INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi,
90 LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc,
91 INT16 dySrc, UINT16 wFlags)
93 return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst,
94 dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
97 /***********************************************************************
98 * DrawDibGetPalette [MSVIDEO.108]
100 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd)
102 return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd)));
105 /***********************************************************************
106 * DrawDibSetPalette [MSVIDEO.110]
108 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
110 return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal));
113 /***********************************************************************
114 * DrawDibRealize [MSVIDEO.112]
116 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
119 return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
122 /*************************************************************************
123 * DrawDibStart [MSVIDEO.118]
125 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate)
127 return DrawDibStart(HDRAWDIB_32(hdd), rate);
130 /*************************************************************************
131 * DrawDibStop [MSVIDEO.119]
133 BOOL16 VFWAPI DrawDibStop16(HDRAWDIB16 hdd)
135 return DrawDibStop(HDRAWDIB_32(hdd));
138 /***********************************************************************
139 * ICOpen [MSVIDEO.203]
141 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
143 return HIC_16(ICOpen(fccType, fccHandler, wMode));
146 /***********************************************************************
147 * _ICMessage [MSVIDEO.207]
149 LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
156 lpData = HeapAlloc(GetProcessHeap(), 0, cb);
158 TRACE("0x%08x, %u, %u, ...)\n", (DWORD) hic, msg, cb);
160 for (i = 0; i < cb / sizeof(WORD); i++)
162 lpData[i] = VA_ARG16(valist, WORD);
165 segData = MapLS(lpData);
166 ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
168 HeapFree(GetProcessHeap(), 0, lpData);
172 /***********************************************************************
173 * ICGetInfo [MSVIDEO.212]
175 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
179 TRACE("(0x%08x,%p,%d)\n", (DWORD) hic, picinfo, cb);
180 ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb);
181 TRACE(" -> 0x%08lx\n", ret);
185 /***********************************************************************
186 * ICLocate [MSVIDEO.213]
188 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
189 LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
192 return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags));
195 /***********************************************************************
196 * _ICCompress [MSVIDEO.224]
198 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags,
199 LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
200 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits,
201 LPDWORD lpckid, LPDWORD lpdwFlags,
202 LONG lFrameNum, DWORD dwFrameSize,
203 DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev,
210 TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags,
211 lpbiOutput, lpData, lpbiInput, lpBits);
213 iccmp.dwFlags = dwFlags;
215 iccmp.lpbiOutput = lpbiOutput;
216 iccmp.lpOutput = lpData;
217 iccmp.lpbiInput = lpbiInput;
218 iccmp.lpInput = lpBits;
220 iccmp.lpckid = lpckid;
221 iccmp.lpdwFlags = lpdwFlags;
222 iccmp.lFrameNum = lFrameNum;
223 iccmp.dwFrameSize = dwFrameSize;
224 iccmp.dwQuality = dwQuality;
225 iccmp.lpbiPrev = lpbiPrev;
226 iccmp.lpPrev = lpPrev;
227 seg_iccmp = MapLS(&iccmp);
228 ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS));
233 /***********************************************************************
234 * _ICDecompress [MSVIDEO.230]
236 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
237 LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
238 LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
244 TRACE("(0x%08x,%d,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat,
245 lpData, lpbi, lpBits);
247 icd.dwFlags = dwFlags;
248 icd.lpbiInput = lpbiFormat;
249 icd.lpInput = lpData;
250 icd.lpbiOutput = lpbi;
251 icd.lpOutput = lpBits;
253 segptr = MapLS(&icd);
254 ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
259 /***********************************************************************
260 * _ICDrawBegin [MSVIDEO.232]
262 DWORD VFWAPIV ICDrawBegin16(HIC16 hic, /* [in] */
263 DWORD dwFlags, /* [in] flags */
264 HPALETTE16 hpal, /* [in] palette to draw with */
265 HWND16 hwnd, /* [in] window to draw to */
266 HDC16 hdc, /* [in] HDC to draw to */
267 INT16 xDst, /* [in] destination rectangle */
268 INT16 yDst, /* [in] */
269 INT16 dxDst, /* [in] */
270 INT16 dyDst, /* [in] */
271 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */
272 INT16 xSrc, /* [in] source rectangle */
273 INT16 ySrc, /* [in] */
274 INT16 dxSrc, /* [in] */
275 INT16 dySrc, /* [in] */
276 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
277 DWORD dwScale) /* [in] */
283 TRACE ("(0x%08x,%d,0x%08x,0x%08x,0x%08x,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
284 (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc,
285 xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate,
288 icdb.dwFlags = dwFlags;
296 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
301 icdb.dwRate = dwRate;
302 icdb.dwScale = dwScale;
303 seg_icdb = MapLS(&icdb);
304 ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb,
305 sizeof(ICDRAWBEGIN16));
310 /***********************************************************************
311 * _ICDraw [MSVIDEO.234]
313 DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags,
314 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
315 LPVOID lpData, /* [???] NOTE: SEGPTR */
316 DWORD cbData, LONG lTime)
322 TRACE("(0x%08x,0x%08x,%p,%p,%d,%d)\n", (DWORD) hic, dwFlags,
323 lpFormat, lpData, cbData, lTime);
324 icd.dwFlags = dwFlags;
325 icd.lpFormat = lpFormat;
329 seg_icd = MapLS(&icd);
330 ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
335 /***********************************************************************
336 * ICGetDisplayFormat [MSVIDEO.239]
338 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
339 LPBITMAPINFOHEADER lpbiOut, INT16 depth,
342 return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
346 #define COPY(x,y) (x->y = x##16->y);
347 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
349 /******************************************************************
350 * MSVIDEO_MapICDEX16To32
354 static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam)
358 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
359 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
363 COPYPTR(icdx, lpbiSrc);
364 COPYPTR(icdx, lpSrc);
365 COPYPTR(icdx, lpbiDst);
366 COPYPTR(icdx, lpDst);
376 *lParam = (DWORD)(icdx);
380 /******************************************************************
381 * MSVIDEO_MapMsg16To32
385 static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
389 TRACE("Mapping %d\n", msg);
400 case ICM_COMPRESS_END:
401 case ICM_DECOMPRESS_END:
402 case ICM_DECOMPRESSEX_END:
404 case ICM_DRAW_START_PLAY:
405 case ICM_DRAW_STOP_PLAY:
406 case ICM_DRAW_REALIZE:
407 case ICM_DRAW_RENDERBUFFER:
411 case ICM_GETDEFAULTQUALITY:
414 case ICM_DRAW_WINDOW:
415 case ICM_GETBUFFERSWANTED:
416 *lParam1 = (DWORD)MapSL(*lParam1);
420 ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
423 ici16 = MapSL(*lParam1);
426 ici->dwSize = sizeof(ICINFO);
428 COPY(ici, fccHandler);
430 COPY(ici, dwVersion);
431 COPY(ici, dwVersionICM);
432 MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
433 MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
434 MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
435 *lParam1 = (DWORD)(ici);
436 *lParam2 = sizeof(ICINFO);
441 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
444 icc16 = MapSL(*lParam1);
448 COPYPTR(icc, lpbiOutput);
449 COPYPTR(icc, lpOutput);
450 COPYPTR(icc, lpbiInput);
451 COPYPTR(icc, lpInput);
452 COPYPTR(icc, lpckid);
453 COPYPTR(icc, lpdwFlags);
454 COPY(icc, lFrameNum);
455 COPY(icc, dwFrameSize);
456 COPY(icc, dwQuality);
457 COPYPTR(icc, lpbiPrev);
458 COPYPTR(icc, lpPrev);
460 *lParam1 = (DWORD)(icc);
461 *lParam2 = sizeof(ICCOMPRESS);
466 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
467 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
469 icd16 = MapSL(*lParam1);
473 COPYPTR(icd, lpbiInput);
474 COPYPTR(icd, lpInput);
475 COPYPTR(icd, lpbiOutput);
476 COPYPTR(icd, lpOutput);
479 *lParam1 = (DWORD)(icd);
480 *lParam2 = sizeof(ICDECOMPRESS);
483 case ICM_COMPRESS_BEGIN:
484 case ICM_COMPRESS_GET_FORMAT:
485 case ICM_COMPRESS_GET_SIZE:
486 case ICM_COMPRESS_QUERY:
487 case ICM_DECOMPRESS_GET_FORMAT:
488 case ICM_DECOMPRESS_QUERY:
489 case ICM_DECOMPRESS_BEGIN:
490 case ICM_DECOMPRESS_SET_PALETTE:
491 case ICM_DECOMPRESS_GET_PALETTE:
492 *lParam1 = (DWORD)MapSL(*lParam1);
493 *lParam2 = (DWORD)MapSL(*lParam2);
495 case ICM_DECOMPRESSEX_QUERY:
496 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
497 WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
498 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
499 * This is because of ICMessage(). Special case it?
501 LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
502 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
504 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
511 case ICM_DECOMPRESSEX_BEGIN:
512 case ICM_DECOMPRESSEX:
513 ret = MSVIDEO_MapICDEX16To32(lParam1);
514 *lParam2 = sizeof(ICDECOMPRESSEX);
518 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
519 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
523 icdb->hpal = HPALETTE_32(icdb16->hpal);
524 icdb->hwnd = HWND_32(icdb16->hwnd);
525 icdb->hdc = HDC_32(icdb16->hdc);
538 *lParam1 = (DWORD)(icdb);
539 *lParam2 = sizeof(ICDRAWBEGIN);
542 case ICM_DRAW_SUGGESTFORMAT:
544 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
545 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
550 COPYPTR(icds, lpbiIn);
551 COPYPTR(icds, lpbiSuggest);
556 icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
558 *lParam1 = (DWORD)(icds);
559 *lParam2 = sizeof(ICDRAWSUGGEST);
564 ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
565 ICDRAW *icd16 = MapSL(*lParam1);
569 COPYPTR(icd, lpFormat);
570 COPYPTR(icd, lpData);
574 *lParam1 = (DWORD)(icd);
575 *lParam2 = sizeof(ICDRAW);
582 FIXME("%d is not yet handled. Expect a crash.\n", msg);
590 /******************************************************************
591 * MSVIDEO_UnmapMsg16To32
595 static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
597 TRACE("Unmapping %d\n", msg);
599 #define UNCOPY(x, y) (x##16->y = x->y);
605 ICINFO *ici = (ICINFO*)(*lParam1);
606 ICINFO16 *ici16 = data16;
608 UNCOPY(ici, fccType);
609 UNCOPY(ici, fccHandler);
610 UNCOPY(ici, dwFlags);
611 UNCOPY(ici, dwVersion);
612 UNCOPY(ici, dwVersionICM);
613 WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
614 sizeof(ici16->szName), NULL, NULL );
615 ici16->szName[sizeof(ici16->szName)-1] = 0;
616 WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
617 sizeof(ici16->szDescription), NULL, NULL );
618 ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
619 /* This just gives garbage for some reason - BB
620 lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
622 HeapFree(GetProcessHeap(), 0, ici);
625 case ICM_DECOMPRESS_QUERY:
628 HeapFree(GetProcessHeap(), 0, x[0]);
630 HeapFree(GetProcessHeap(), 0, x[1]);
635 case ICM_DECOMPRESSEX_QUERY:
636 case ICM_DECOMPRESSEX_BEGIN:
637 case ICM_DECOMPRESSEX:
639 case ICM_DRAW_SUGGESTFORMAT:
641 HeapFree(GetProcessHeap(), 0, data16);
644 ERR("Unmapping unmapped msg %d\n", msg);
649 /***********************************************************************
650 * ICInfo [MSVIDEO.200]
652 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
656 DWORD lParam = (DWORD)lpicinfo;
657 DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
659 /* Use the mapping functions to map the ICINFO structure */
660 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
662 ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
664 MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
669 /******************************************************************
674 static LRESULT CALLBACK IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, LPARAM lp1, LPARAM lp2)
682 lp2 = (DWORD)MapLS((void*)lp2);
685 args[7] = HIWORD(hic);
686 args[6] = LOWORD(hic);
687 args[5] = HDRVR_16(hdrv);
689 args[3] = HIWORD(lp1);
690 args[2] = LOWORD(lp1);
691 args[1] = HIWORD(lp2);
692 args[0] = LOWORD(lp2);
693 WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
704 #define MAX_THUNKS 32
706 #include "pshpack1.h"
707 static struct msvideo_thunk
709 BYTE popl_eax; /* popl %eax (return address) */
710 BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
712 BYTE pushl_eax; /* pushl %eax */
713 BYTE jmp; /* ljmp WDML_InvokeCallback16 */
715 HIC16 hIC16; /* driver's handle */
719 static CRITICAL_SECTION msvideo_cs;
720 static CRITICAL_SECTION_DEBUG critsect_debug =
723 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
724 0, 0, { (DWORD_PTR)(__FILE__ ": msvideo_cs") }
726 static CRITICAL_SECTION msvideo_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
728 static struct msvideo_thunk* MSVIDEO_AddThunk(DWORD pfn16)
730 struct msvideo_thunk* thunk;
734 MSVIDEO_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*MSVIDEO_Thunks), MEM_COMMIT,
735 PAGE_EXECUTE_READWRITE);
736 if (!MSVIDEO_Thunks) return NULL;
737 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
739 thunk->popl_eax = 0x58; /* popl %eax */
740 thunk->pushl_func = 0x68; /* pushl $pfn16 */
742 thunk->pushl_eax = 0x50; /* pushl %eax */
743 thunk->jmp = 0xe9; /* jmp IC_Callback3216 */
744 thunk->callback = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1);
748 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
750 if (thunk->pfn16 == 0)
752 thunk->pfn16 = pfn16;
756 FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
760 static struct msvideo_thunk* MSVIDEO_HasThunk(HIC16 hic)
762 struct msvideo_thunk* thunk;
764 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
766 if (thunk->hIC16 == hic) return thunk;
771 /***********************************************************************
772 * ICOpenFunction [MSVIDEO.206]
774 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
777 struct msvideo_thunk* thunk;
779 EnterCriticalSection(&msvideo_cs);
780 if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler)))
782 LeaveCriticalSection(&msvideo_cs);
785 if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)thunk)))
786 thunk->hIC16 = HIC_16(hic32);
789 LeaveCriticalSection(&msvideo_cs);
790 return HIC_16(hic32);
793 /***********************************************************************
794 * ICSendMessage [MSVIDEO.205]
796 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2)
798 LRESULT ret = ICERR_BADHANDLE;
799 struct msvideo_thunk* thunk;
801 if ((thunk = MSVIDEO_HasThunk(hic)))
806 /* FIXME: original code was passing hdrv first and hic second */
807 /* but this doesn't match what IC_Callback3216 does */
808 args[7] = HIWORD(hic);
809 args[6] = LOWORD(hic);
810 args[5] = 0; /* the 32bit also sets it to NULL */
812 args[3] = HIWORD(lParam1);
813 args[2] = LOWORD(lParam1);
814 args[1] = HIWORD(lParam2);
815 args[0] = LOWORD(lParam2);
816 WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result );
821 /* map the message for a 32 bit infrastructure, and pass it along */
822 void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
824 ret = ICSendMessage(HIC_32(hic), msg, lParam1, lParam2);
826 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
831 /***********************************************************************
832 * ICClose [MSVIDEO.204]
834 LRESULT WINAPI ICClose16(HIC16 hic)
836 BOOL ret = ICClose(HIC_32(hic));
838 EnterCriticalSection(&msvideo_cs);
841 struct msvideo_thunk* thunk;
842 if ((thunk = MSVIDEO_HasThunk(hic)))
849 LeaveCriticalSection(&msvideo_cs);
853 /***********************************************************************
854 * VideoCapDriverDescAndVer [MSVIDEO.22]
856 DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
857 LPSTR buf2, WORD buf2len)
859 static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
863 char *s, buf[2048], fn[260];
866 DWORD i, cnt = 0, lRet;
872 TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
873 lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
874 if (lRet == ERROR_SUCCESS)
876 RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
877 for (i = 0; i < cnt; i++)
879 bufLen = sizeof(buf) / sizeof(buf[0]);
880 lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
881 if (lRet != ERROR_SUCCESS) continue;
882 if (strncasecmp(buf, "vid", 3)) continue;
885 lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
886 if (lRet == ERROR_SUCCESS) found = TRUE;
892 /* search system.ini if not found in the registry */
893 if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
895 for (s = buf; *s; s += strlen(s) + 1)
897 if (strncasecmp(s, "vid", 3)) continue;
899 if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
907 TRACE("No more VID* entries found nr=%d\n", nr);
910 infosize = GetFileVersionInfoSizeA(fn, &verhandle);
913 TRACE("%s has no fileversioninfo.\n", fn);
916 infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
917 if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf))
919 /* Yes, two space behind : */
920 /* FIXME: test for buflen */
921 snprintf(buf2, buf2len, "Version: %d.%d.%d.%d\n",
922 ((WORD*)infobuf)[0x0f],
923 ((WORD*)infobuf)[0x0e],
924 ((WORD*)infobuf)[0x11],
925 ((WORD*)infobuf)[0x10]
927 TRACE("version of %s is %s\n", fn, buf2);
931 TRACE("GetFileVersionInfoA failed for %s.\n", fn);
932 lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
934 /* FIXME: language problem? */
935 if (VerQueryValueA( infobuf,
941 UINT copylen = min(subblocklen,buf1len-1);
942 memcpy(buf1, subblock, copylen);
943 buf1[copylen] = '\0';
944 TRACE("VQA returned %s\n", (LPCSTR)subblock);
948 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
949 lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
951 HeapFree(GetProcessHeap(), 0, infobuf);
955 /**************************************************************************
956 * DllEntryPoint (MSVIDEO.3)
958 * MSVIDEO DLL entry point
961 BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
962 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
966 case DLL_PROCESS_ATTACH:
968 case DLL_PROCESS_DETACH:
970 case DLL_THREAD_ATTACH:
971 case DLL_THREAD_DETACH: