jscript: Add missing port.h include for isnan.
[wine/multimedia.git] / dlls / msvideo.dll16 / msvideo16.c
blobb729ccc870eea1ac6cb616f4af7939459f05d649
1 /*
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
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winver.h"
29 #include "winnls.h"
30 #include "winreg.h"
31 #include "winuser.h"
32 #include "wine/winbase16.h"
33 #include "wownt32.h"
34 #include "vfw16.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,
118 BOOL16 fBackground)
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 )
152 LPWORD lpData;
153 SEGPTR segData;
154 LRESULT ret;
155 UINT16 i;
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);
168 UnMapLS(segData);
169 HeapFree(GetProcessHeap(), 0, lpData);
170 return ret;
173 /***********************************************************************
174 * ICGetInfo [MSVIDEO.212]
176 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
178 LRESULT ret;
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);
183 return ret;
186 /***********************************************************************
187 * ICLocate [MSVIDEO.213]
189 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
190 LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
191 WORD wFlags)
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,
205 LPVOID lpPrev)
207 DWORD ret;
208 ICCOMPRESS iccmp;
209 SEGPTR seg_iccmp;
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));
230 UnMapLS(seg_iccmp);
231 return ret;
234 /***********************************************************************
235 * _ICDecompress [MSVIDEO.230]
237 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
238 LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
239 LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
241 ICDECOMPRESS icd;
242 SEGPTR segptr;
243 DWORD ret;
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;
253 icd.ckid = 0;
254 segptr = MapLS(&icd);
255 ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
256 UnMapLS(segptr);
257 return ret;
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] */
280 DWORD ret;
281 ICDRAWBEGIN16 icdb;
282 SEGPTR seg_icdb;
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,
287 dwScale);
289 icdb.dwFlags = dwFlags;
290 icdb.hpal = hpal;
291 icdb.hwnd = hwnd;
292 icdb.hdc = hdc;
293 icdb.xDst = xDst;
294 icdb.yDst = yDst;
295 icdb.dxDst = dxDst;
296 icdb.dyDst = dyDst;
297 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
298 icdb.xSrc = xSrc;
299 icdb.ySrc = ySrc;
300 icdb.dxSrc = dxSrc;
301 icdb.dySrc = dySrc;
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));
307 UnMapLS(seg_icdb);
308 return ret;
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)
319 DWORD ret;
320 ICDRAW icd;
321 SEGPTR seg_icd;
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;
327 icd.lpData = lpData;
328 icd.cbData = cbData;
329 icd.lTime = lTime;
330 seg_icd = MapLS(&icd);
331 ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
332 UnMapLS(seg_icd);
333 return ret;
336 /***********************************************************************
337 * ICGetDisplayFormat [MSVIDEO.239]
339 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
340 LPBITMAPINFOHEADER lpbiOut, INT16 depth,
341 INT16 dx, INT16 dy)
343 return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
344 dx, dy));
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)
357 LPVOID ret;
359 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
360 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
361 ret = icdx16;
363 COPY(icdx, dwFlags);
364 COPYPTR(icdx, lpbiSrc);
365 COPYPTR(icdx, lpSrc);
366 COPYPTR(icdx, lpbiDst);
367 COPYPTR(icdx, lpDst);
368 COPY(icdx, xDst);
369 COPY(icdx, yDst);
370 COPY(icdx, dxDst);
371 COPY(icdx, dyDst);
372 COPY(icdx, xSrc);
373 COPY(icdx, ySrc);
374 COPY(icdx, dxSrc);
375 COPY(icdx, dySrc);
377 *lParam = (DWORD)(icdx);
378 return ret;
381 /******************************************************************
382 * MSVIDEO_MapMsg16To32
386 static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
388 LPVOID ret = 0;
390 TRACE("Mapping %d\n", msg);
392 switch (msg)
394 case DRV_LOAD:
395 case DRV_ENABLE:
396 case DRV_CLOSE:
397 case DRV_DISABLE:
398 case DRV_FREE:
399 case ICM_ABOUT:
400 case ICM_CONFIGURE:
401 case ICM_COMPRESS_END:
402 case ICM_DECOMPRESS_END:
403 case ICM_DECOMPRESSEX_END:
404 case ICM_SETQUALITY:
405 case ICM_DRAW_START_PLAY:
406 case ICM_DRAW_STOP_PLAY:
407 case ICM_DRAW_REALIZE:
408 case ICM_DRAW_RENDERBUFFER:
409 case ICM_DRAW_END:
410 break;
411 case DRV_OPEN:
412 case ICM_GETDEFAULTQUALITY:
413 case ICM_GETQUALITY:
414 case ICM_SETSTATE:
415 case ICM_DRAW_WINDOW:
416 case ICM_GETBUFFERSWANTED:
417 *lParam1 = (DWORD)MapSL(*lParam1);
418 break;
419 case ICM_GETINFO:
421 ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
422 ICINFO16 *ici16;
424 ici16 = MapSL(*lParam1);
425 ret = ici16;
427 ici->dwSize = sizeof(ICINFO);
428 COPY(ici, fccType);
429 COPY(ici, fccHandler);
430 COPY(ici, dwFlags);
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);
439 break;
440 case ICM_COMPRESS:
442 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
443 ICCOMPRESS *icc16;
445 icc16 = MapSL(*lParam1);
446 ret = icc16;
448 COPY(icc, dwFlags);
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);
464 break;
465 case ICM_DECOMPRESS:
467 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
468 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
470 icd16 = MapSL(*lParam1);
471 ret = icd16;
473 COPY(icd, dwFlags);
474 COPYPTR(icd, lpbiInput);
475 COPYPTR(icd, lpInput);
476 COPYPTR(icd, lpbiOutput);
477 COPYPTR(icd, lpOutput);
478 COPY(icd, ckid);
480 *lParam1 = (DWORD)(icd);
481 *lParam2 = sizeof(ICDECOMPRESS);
483 break;
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);
495 break;
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);
504 if (*lParam2)
505 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
506 else
507 addr[1] = 0;
509 ret = addr;
511 break;*/
512 case ICM_DECOMPRESSEX_BEGIN:
513 case ICM_DECOMPRESSEX:
514 ret = MSVIDEO_MapICDEX16To32(lParam1);
515 *lParam2 = sizeof(ICDECOMPRESSEX);
516 break;
517 case ICM_DRAW_BEGIN:
519 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
520 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
521 ret = icdb16;
523 COPY(icdb, dwFlags);
524 icdb->hpal = HPALETTE_32(icdb16->hpal);
525 icdb->hwnd = HWND_32(icdb16->hwnd);
526 icdb->hdc = HDC_32(icdb16->hdc);
527 COPY(icdb, xDst);
528 COPY(icdb, yDst);
529 COPY(icdb, dxDst);
530 COPY(icdb, dyDst);
531 COPYPTR(icdb, lpbi);
532 COPY(icdb, xSrc);
533 COPY(icdb, ySrc);
534 COPY(icdb, dxSrc);
535 COPY(icdb, dySrc);
536 COPY(icdb, dwRate);
537 COPY(icdb, dwScale);
539 *lParam1 = (DWORD)(icdb);
540 *lParam2 = sizeof(ICDRAWBEGIN);
542 break;
543 case ICM_DRAW_SUGGESTFORMAT:
545 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
546 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
548 ret = icds16;
550 COPY(icds, dwFlags);
551 COPYPTR(icds, lpbiIn);
552 COPYPTR(icds, lpbiSuggest);
553 COPY(icds, dxSrc);
554 COPY(icds, dySrc);
555 COPY(icds, dxDst);
556 COPY(icds, dyDst);
557 icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
559 *lParam1 = (DWORD)(icds);
560 *lParam2 = sizeof(ICDRAWSUGGEST);
562 break;
563 case ICM_DRAW:
565 ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
566 ICDRAW *icd16 = MapSL(*lParam1);
567 ret = icd16;
569 COPY(icd, dwFlags);
570 COPYPTR(icd, lpFormat);
571 COPYPTR(icd, lpData);
572 COPY(icd, cbData);
573 COPY(icd, lTime);
575 *lParam1 = (DWORD)(icd);
576 *lParam2 = sizeof(ICDRAW);
578 break;
579 case ICM_DRAW_START:
580 case ICM_DRAW_STOP:
581 break;
582 default:
583 FIXME("%d is not yet handled. Expect a crash.\n", msg);
585 return ret;
588 #undef COPY
589 #undef COPYPTR
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);
602 switch (msg)
604 case ICM_GETINFO:
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);
625 break;
626 case ICM_DECOMPRESS_QUERY:
628 LPVOID* x = data16;
629 HeapFree(GetProcessHeap(), 0, x[0]);
630 if (x[1])
631 HeapFree(GetProcessHeap(), 0, x[1]);
633 break;*/
634 case ICM_COMPRESS:
635 case ICM_DECOMPRESS:
636 case ICM_DECOMPRESSEX_QUERY:
637 case ICM_DECOMPRESSEX_BEGIN:
638 case ICM_DECOMPRESSEX:
639 case ICM_DRAW_BEGIN:
640 case ICM_DRAW_SUGGESTFORMAT:
641 case ICM_DRAW:
642 HeapFree(GetProcessHeap(), 0, data16);
643 break;
644 default:
645 ERR("Unmapping unmapped msg %d\n", msg);
647 #undef UNCOPY
650 /***********************************************************************
651 * ICInfo [MSVIDEO.200]
653 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
655 BOOL16 ret;
656 LPVOID lpv;
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);
667 return ret;
670 /******************************************************************
671 * IC_Callback3216
675 static LRESULT CALLBACK IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, LPARAM lp1, LPARAM lp2)
677 WORD args[8];
678 DWORD ret = 0;
680 switch (msg)
682 case DRV_OPEN:
683 lp2 = (DWORD)MapLS((void*)lp2);
684 break;
686 args[7] = HIWORD(hic);
687 args[6] = LOWORD(hic);
688 args[5] = HDRVR_16(hdrv);
689 args[4] = msg;
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 );
696 switch (msg)
698 case DRV_OPEN:
699 UnMapLS(lp2);
700 break;
702 return 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) */
712 DWORD pfn16;
713 BYTE pushl_eax; /* pushl %eax */
714 BYTE jmp; /* ljmp WDML_InvokeCallback16 */
715 DWORD callback;
716 HIC16 hIC16; /* driver's handle */
717 } *MSVIDEO_Thunks;
718 #include "poppack.h"
720 static CRITICAL_SECTION msvideo_cs;
721 static CRITICAL_SECTION_DEBUG critsect_debug =
723 0, 0, &msvideo_cs,
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;
733 if (!MSVIDEO_Thunks)
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 */
742 thunk->pfn16 = 0;
743 thunk->pushl_eax = 0x50; /* pushl %eax */
744 thunk->jmp = 0xe9; /* jmp IC_Callback3216 */
745 thunk->callback = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1);
746 thunk->hIC16 = 0;
749 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
751 if (thunk->pfn16 == 0)
753 thunk->pfn16 = pfn16;
754 return thunk;
757 FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
758 return NULL;
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;
769 return NULL;
772 /***********************************************************************
773 * ICOpenFunction [MSVIDEO.206]
775 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
777 HIC hic32;
778 struct msvideo_thunk* thunk;
780 EnterCriticalSection(&msvideo_cs);
781 if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler)))
783 LeaveCriticalSection(&msvideo_cs);
784 return 0;
786 if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)thunk)))
787 thunk->hIC16 = HIC_16(hic32);
788 else
789 thunk->pfn16 = 0;
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)))
804 WORD args[8];
805 DWORD result;
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 */
812 args[4] = msg;
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 );
818 ret = result;
820 else
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);
826 if (data16)
827 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
829 return ret;
832 /***********************************************************************
833 * ICClose [MSVIDEO.204]
835 LRESULT WINAPI ICClose16(HIC16 hic)
837 BOOL ret = ICClose(HIC_32(hic));
839 EnterCriticalSection(&msvideo_cs);
840 if (ret)
842 struct msvideo_thunk* thunk;
843 if ((thunk = MSVIDEO_HasThunk(hic)))
845 thunk->pfn16 = 0;
846 thunk->hIC16 = 0;
848 else ret = FALSE;
850 LeaveCriticalSection(&msvideo_cs);
851 return ret;
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";
861 DWORD verhandle;
862 DWORD infosize;
863 UINT subblocklen;
864 char *s, buf[2048], fn[260];
865 LPBYTE infobuf;
866 LPVOID subblock;
867 DWORD i, cnt = 0, lRet;
868 DWORD bufLen, fnLen;
869 FILETIME lastWrite;
870 HKEY hKey;
871 BOOL found = FALSE;
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;
884 if (nr--) continue;
885 fnLen = sizeof(fn);
886 lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
887 if (lRet == ERROR_SUCCESS) found = TRUE;
888 break;
890 RegCloseKey( hKey );
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;
899 if (nr--) continue;
900 if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
901 found = TRUE;
902 break;
906 if (!found)
908 TRACE("No more VID* entries found nr=%d\n", nr);
909 return 20;
911 infosize = GetFileVersionInfoSizeA(fn, &verhandle);
912 if (!infosize)
914 TRACE("%s has no fileversioninfo.\n", fn);
915 return 18;
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);
930 else
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,
937 version_info_spec,
938 &subblock,
939 &subblocklen
942 UINT copylen = min(subblocklen,buf1len-1);
943 memcpy(buf1, subblock, copylen);
944 buf1[copylen] = '\0';
945 TRACE("VQA returned %s\n", (LPCSTR)subblock);
947 else
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);
953 return 0;
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)
965 switch (fdwReason)
967 case DLL_PROCESS_ATTACH:
968 break;
969 case DLL_PROCESS_DETACH:
970 DeleteCriticalSection(&msvideo_cs);
971 break;
972 case DLL_THREAD_ATTACH:
973 case DLL_THREAD_DETACH:
974 break;
976 return TRUE;
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));