winedbg: Don't dereference possibly NULL thread pointer.
[wine/zf.git] / dlls / msvideo.dll16 / msvideo16.c
blob840de2efa8cdd5bee2cfb198a51c6e9ca6c9796c
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 "winternl.h"
32 #include "winuser.h"
33 #include "wine/winbase16.h"
34 #include "wownt32.h"
35 #include "vfw16.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
40 /* Drivers32 settings */
41 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
43 /* handle16 --> handle conversions */
44 #define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16))
45 #define HIC_32(h16) ((HIC)(ULONG_PTR)(h16))
47 /* handle --> handle16 conversions */
48 #define HDRVR_16(h32) (LOWORD(h32))
49 #define HDRAWDIB_16(h32) (LOWORD(h32))
50 #define HIC_16(h32) (LOWORD(h32))
52 /***********************************************************************
53 * DrawDibOpen [MSVIDEO.102]
55 HDRAWDIB16 VFWAPI DrawDibOpen16(void)
57 return HDRAWDIB_16(DrawDibOpen());
60 /***********************************************************************
61 * DrawDibClose [MSVIDEO.103]
63 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd)
65 return DrawDibClose(HDRAWDIB_32(hdd));
68 /************************************************************************
69 * DrawDibBegin [MSVIDEO.104]
71 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst,
72 INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc,
73 INT16 dySrc, UINT16 wFlags)
75 return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi,
76 dxSrc, dySrc, wFlags);
79 /***********************************************************************
80 * DrawDibEnd [MSVIDEO.105]
82 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd)
84 return DrawDibEnd(HDRAWDIB_32(hdd));
87 /**********************************************************************
88 * DrawDibDraw [MSVIDEO.106]
90 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst,
91 INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi,
92 LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc,
93 INT16 dySrc, UINT16 wFlags)
95 return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst,
96 dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
99 /***********************************************************************
100 * DrawDibGetPalette [MSVIDEO.108]
102 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd)
104 return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd)));
107 /***********************************************************************
108 * DrawDibSetPalette [MSVIDEO.110]
110 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
112 return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal));
115 /***********************************************************************
116 * DrawDibRealize [MSVIDEO.112]
118 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
119 BOOL16 fBackground)
121 return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
124 /*************************************************************************
125 * DrawDibProfileDisplay [MSVIDEO.114]
127 BOOL16 VFWAPI DrawDibProfileDisplay16(LPBITMAPINFOHEADER lpbi)
129 TRACE("(%p)\n", lpbi);
130 return DrawDibProfileDisplay(lpbi);
133 /*************************************************************************
134 * DrawDibStart [MSVIDEO.118]
136 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate)
138 return DrawDibStart(HDRAWDIB_32(hdd), rate);
141 /*************************************************************************
142 * DrawDibStop [MSVIDEO.119]
144 BOOL16 VFWAPI DrawDibStop16(HDRAWDIB16 hdd)
146 return DrawDibStop(HDRAWDIB_32(hdd));
149 /***********************************************************************
150 * ICOpen [MSVIDEO.203]
152 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
154 return HIC_16(ICOpen(fccType, fccHandler, wMode));
157 /***********************************************************************
158 * _ICMessage [MSVIDEO.207]
160 LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
162 LPWORD lpData;
163 SEGPTR segData;
164 LRESULT ret;
165 UINT16 i;
167 lpData = HeapAlloc(GetProcessHeap(), 0, cb);
169 TRACE("0x%08x, %u, %u, ...)\n", (DWORD) hic, msg, cb);
171 for (i = 0; i < cb / sizeof(WORD); i++)
173 lpData[i] = VA_ARG16(valist, WORD);
176 segData = MapLS(lpData);
177 ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
178 UnMapLS(segData);
179 HeapFree(GetProcessHeap(), 0, lpData);
180 return ret;
183 /***********************************************************************
184 * ICGetInfo [MSVIDEO.212]
186 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
188 LRESULT ret;
190 TRACE("(0x%08x,%p,%d)\n", (DWORD) hic, picinfo, cb);
191 ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb);
192 TRACE(" -> 0x%08lx\n", ret);
193 return ret;
196 /***********************************************************************
197 * ICLocate [MSVIDEO.213]
199 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
200 LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
201 WORD wFlags)
203 return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags));
206 /***********************************************************************
207 * _ICCompress [MSVIDEO.224]
209 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags,
210 LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
211 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits,
212 LPDWORD lpckid, LPDWORD lpdwFlags,
213 LONG lFrameNum, DWORD dwFrameSize,
214 DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev,
215 LPVOID lpPrev)
217 DWORD ret;
218 ICCOMPRESS iccmp;
219 SEGPTR seg_iccmp;
221 TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags,
222 lpbiOutput, lpData, lpbiInput, lpBits);
224 iccmp.dwFlags = dwFlags;
226 iccmp.lpbiOutput = lpbiOutput;
227 iccmp.lpOutput = lpData;
228 iccmp.lpbiInput = lpbiInput;
229 iccmp.lpInput = lpBits;
231 iccmp.lpckid = lpckid;
232 iccmp.lpdwFlags = lpdwFlags;
233 iccmp.lFrameNum = lFrameNum;
234 iccmp.dwFrameSize = dwFrameSize;
235 iccmp.dwQuality = dwQuality;
236 iccmp.lpbiPrev = lpbiPrev;
237 iccmp.lpPrev = lpPrev;
238 seg_iccmp = MapLS(&iccmp);
239 ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS));
240 UnMapLS(seg_iccmp);
241 return ret;
244 /***********************************************************************
245 * _ICDecompress [MSVIDEO.230]
247 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
248 LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
249 LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
251 ICDECOMPRESS icd;
252 SEGPTR segptr;
253 DWORD ret;
255 TRACE("(0x%08x,%d,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat,
256 lpData, lpbi, lpBits);
258 icd.dwFlags = dwFlags;
259 icd.lpbiInput = lpbiFormat;
260 icd.lpInput = lpData;
261 icd.lpbiOutput = lpbi;
262 icd.lpOutput = lpBits;
263 icd.ckid = 0;
264 segptr = MapLS(&icd);
265 ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
266 UnMapLS(segptr);
267 return ret;
270 /***********************************************************************
271 * _ICDrawBegin [MSVIDEO.232]
273 DWORD VFWAPIV ICDrawBegin16(HIC16 hic, /* [in] */
274 DWORD dwFlags, /* [in] flags */
275 HPALETTE16 hpal, /* [in] palette to draw with */
276 HWND16 hwnd, /* [in] window to draw to */
277 HDC16 hdc, /* [in] HDC to draw to */
278 INT16 xDst, /* [in] destination rectangle */
279 INT16 yDst, /* [in] */
280 INT16 dxDst, /* [in] */
281 INT16 dyDst, /* [in] */
282 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */
283 INT16 xSrc, /* [in] source rectangle */
284 INT16 ySrc, /* [in] */
285 INT16 dxSrc, /* [in] */
286 INT16 dySrc, /* [in] */
287 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
288 DWORD dwScale) /* [in] */
290 DWORD ret;
291 ICDRAWBEGIN16 icdb;
292 SEGPTR seg_icdb;
294 TRACE ("(0x%08x,%d,0x%08x,0x%08x,0x%08x,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
295 (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc,
296 xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate,
297 dwScale);
299 icdb.dwFlags = dwFlags;
300 icdb.hpal = hpal;
301 icdb.hwnd = hwnd;
302 icdb.hdc = hdc;
303 icdb.xDst = xDst;
304 icdb.yDst = yDst;
305 icdb.dxDst = dxDst;
306 icdb.dyDst = dyDst;
307 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
308 icdb.xSrc = xSrc;
309 icdb.ySrc = ySrc;
310 icdb.dxSrc = dxSrc;
311 icdb.dySrc = dySrc;
312 icdb.dwRate = dwRate;
313 icdb.dwScale = dwScale;
314 seg_icdb = MapLS(&icdb);
315 ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb,
316 sizeof(ICDRAWBEGIN16));
317 UnMapLS(seg_icdb);
318 return ret;
321 /***********************************************************************
322 * _ICDraw [MSVIDEO.234]
324 DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags,
325 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
326 LPVOID lpData, /* [???] NOTE: SEGPTR */
327 DWORD cbData, LONG lTime)
329 DWORD ret;
330 ICDRAW icd;
331 SEGPTR seg_icd;
333 TRACE("(0x%08x,0x%08x,%p,%p,%d,%d)\n", (DWORD) hic, dwFlags,
334 lpFormat, lpData, cbData, lTime);
335 icd.dwFlags = dwFlags;
336 icd.lpFormat = lpFormat;
337 icd.lpData = lpData;
338 icd.cbData = cbData;
339 icd.lTime = lTime;
340 seg_icd = MapLS(&icd);
341 ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
342 UnMapLS(seg_icd);
343 return ret;
346 /***********************************************************************
347 * ICGetDisplayFormat [MSVIDEO.239]
349 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
350 LPBITMAPINFOHEADER lpbiOut, INT16 depth,
351 INT16 dx, INT16 dy)
353 return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
354 dx, dy));
357 #define COPY(x,y) (x->y = x##16->y);
358 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
360 /******************************************************************
361 * MSVIDEO_MapICDEX16To32
365 static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam)
367 LPVOID ret;
369 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
370 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
371 ret = icdx16;
373 COPY(icdx, dwFlags);
374 COPYPTR(icdx, lpbiSrc);
375 COPYPTR(icdx, lpSrc);
376 COPYPTR(icdx, lpbiDst);
377 COPYPTR(icdx, lpDst);
378 COPY(icdx, xDst);
379 COPY(icdx, yDst);
380 COPY(icdx, dxDst);
381 COPY(icdx, dyDst);
382 COPY(icdx, xSrc);
383 COPY(icdx, ySrc);
384 COPY(icdx, dxSrc);
385 COPY(icdx, dySrc);
387 *lParam = (DWORD)(icdx);
388 return ret;
391 /******************************************************************
392 * MSVIDEO_MapMsg16To32
396 static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
398 LPVOID ret = 0;
400 TRACE("Mapping %d\n", msg);
402 switch (msg)
404 case DRV_LOAD:
405 case DRV_ENABLE:
406 case DRV_CLOSE:
407 case DRV_DISABLE:
408 case DRV_FREE:
409 case ICM_ABOUT:
410 case ICM_CONFIGURE:
411 case ICM_COMPRESS_END:
412 case ICM_DECOMPRESS_END:
413 case ICM_DECOMPRESSEX_END:
414 case ICM_SETQUALITY:
415 case ICM_DRAW_START_PLAY:
416 case ICM_DRAW_STOP_PLAY:
417 case ICM_DRAW_REALIZE:
418 case ICM_DRAW_RENDERBUFFER:
419 case ICM_DRAW_END:
420 break;
421 case DRV_OPEN:
422 case ICM_GETDEFAULTQUALITY:
423 case ICM_GETQUALITY:
424 case ICM_SETSTATE:
425 case ICM_DRAW_WINDOW:
426 case ICM_GETBUFFERSWANTED:
427 *lParam1 = (DWORD)MapSL(*lParam1);
428 break;
429 case ICM_GETINFO:
431 ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
432 ICINFO16 *ici16;
434 ici16 = MapSL(*lParam1);
435 ret = ici16;
437 ici->dwSize = sizeof(ICINFO);
438 COPY(ici, fccType);
439 COPY(ici, fccHandler);
440 COPY(ici, dwFlags);
441 COPY(ici, dwVersion);
442 COPY(ici, dwVersionICM);
443 MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
444 MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
445 MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
446 *lParam1 = (DWORD)(ici);
447 *lParam2 = sizeof(ICINFO);
449 break;
450 case ICM_COMPRESS:
452 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
453 ICCOMPRESS *icc16;
455 icc16 = MapSL(*lParam1);
456 ret = icc16;
458 COPY(icc, dwFlags);
459 COPYPTR(icc, lpbiOutput);
460 COPYPTR(icc, lpOutput);
461 COPYPTR(icc, lpbiInput);
462 COPYPTR(icc, lpInput);
463 COPYPTR(icc, lpckid);
464 COPYPTR(icc, lpdwFlags);
465 COPY(icc, lFrameNum);
466 COPY(icc, dwFrameSize);
467 COPY(icc, dwQuality);
468 COPYPTR(icc, lpbiPrev);
469 COPYPTR(icc, lpPrev);
471 *lParam1 = (DWORD)(icc);
472 *lParam2 = sizeof(ICCOMPRESS);
474 break;
475 case ICM_DECOMPRESS:
477 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
478 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
480 icd16 = MapSL(*lParam1);
481 ret = icd16;
483 COPY(icd, dwFlags);
484 COPYPTR(icd, lpbiInput);
485 COPYPTR(icd, lpInput);
486 COPYPTR(icd, lpbiOutput);
487 COPYPTR(icd, lpOutput);
488 COPY(icd, ckid);
490 *lParam1 = (DWORD)(icd);
491 *lParam2 = sizeof(ICDECOMPRESS);
493 break;
494 case ICM_COMPRESS_BEGIN:
495 case ICM_COMPRESS_GET_FORMAT:
496 case ICM_COMPRESS_GET_SIZE:
497 case ICM_COMPRESS_QUERY:
498 case ICM_DECOMPRESS_GET_FORMAT:
499 case ICM_DECOMPRESS_QUERY:
500 case ICM_DECOMPRESS_BEGIN:
501 case ICM_DECOMPRESS_SET_PALETTE:
502 case ICM_DECOMPRESS_GET_PALETTE:
503 *lParam1 = (DWORD)MapSL(*lParam1);
504 *lParam2 = (DWORD)MapSL(*lParam2);
505 break;
506 case ICM_DECOMPRESSEX_QUERY:
507 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
508 WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
509 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
510 * This is because of ICMessage(). Special case it?
512 LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
513 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
514 if (*lParam2)
515 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
516 else
517 addr[1] = 0;
519 ret = addr;
521 break;*/
522 case ICM_DECOMPRESSEX_BEGIN:
523 case ICM_DECOMPRESSEX:
524 ret = MSVIDEO_MapICDEX16To32(lParam1);
525 *lParam2 = sizeof(ICDECOMPRESSEX);
526 break;
527 case ICM_DRAW_BEGIN:
529 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
530 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
531 ret = icdb16;
533 COPY(icdb, dwFlags);
534 icdb->hpal = HPALETTE_32(icdb16->hpal);
535 icdb->hwnd = HWND_32(icdb16->hwnd);
536 icdb->hdc = HDC_32(icdb16->hdc);
537 COPY(icdb, xDst);
538 COPY(icdb, yDst);
539 COPY(icdb, dxDst);
540 COPY(icdb, dyDst);
541 COPYPTR(icdb, lpbi);
542 COPY(icdb, xSrc);
543 COPY(icdb, ySrc);
544 COPY(icdb, dxSrc);
545 COPY(icdb, dySrc);
546 COPY(icdb, dwRate);
547 COPY(icdb, dwScale);
549 *lParam1 = (DWORD)(icdb);
550 *lParam2 = sizeof(ICDRAWBEGIN);
552 break;
553 case ICM_DRAW_SUGGESTFORMAT:
555 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
556 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
558 ret = icds16;
560 COPY(icds, dwFlags);
561 COPYPTR(icds, lpbiIn);
562 COPYPTR(icds, lpbiSuggest);
563 COPY(icds, dxSrc);
564 COPY(icds, dySrc);
565 COPY(icds, dxDst);
566 COPY(icds, dyDst);
567 icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
569 *lParam1 = (DWORD)(icds);
570 *lParam2 = sizeof(ICDRAWSUGGEST);
572 break;
573 case ICM_DRAW:
575 ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
576 ICDRAW *icd16 = MapSL(*lParam1);
577 ret = icd16;
579 COPY(icd, dwFlags);
580 COPYPTR(icd, lpFormat);
581 COPYPTR(icd, lpData);
582 COPY(icd, cbData);
583 COPY(icd, lTime);
585 *lParam1 = (DWORD)(icd);
586 *lParam2 = sizeof(ICDRAW);
588 break;
589 case ICM_DRAW_START:
590 case ICM_DRAW_STOP:
591 break;
592 default:
593 FIXME("%d is not yet handled. Expect a crash.\n", msg);
595 return ret;
598 #undef COPY
599 #undef COPYPTR
601 /******************************************************************
602 * MSVIDEO_UnmapMsg16To32
606 static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
608 TRACE("Unmapping %d\n", msg);
610 #define UNCOPY(x, y) (x##16->y = x->y);
612 switch (msg)
614 case ICM_GETINFO:
616 ICINFO *ici = (ICINFO*)(*lParam1);
617 ICINFO16 *ici16 = data16;
619 UNCOPY(ici, fccType);
620 UNCOPY(ici, fccHandler);
621 UNCOPY(ici, dwFlags);
622 UNCOPY(ici, dwVersion);
623 UNCOPY(ici, dwVersionICM);
624 WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
625 sizeof(ici16->szName), NULL, NULL );
626 ici16->szName[sizeof(ici16->szName)-1] = 0;
627 WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
628 sizeof(ici16->szDescription), NULL, NULL );
629 ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
630 /* This just gives garbage for some reason - BB
631 lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
633 HeapFree(GetProcessHeap(), 0, ici);
635 break;
636 case ICM_DECOMPRESS_QUERY:
638 LPVOID* x = data16;
639 HeapFree(GetProcessHeap(), 0, x[0]);
640 if (x[1])
641 HeapFree(GetProcessHeap(), 0, x[1]);
643 break;*/
644 case ICM_COMPRESS:
645 case ICM_DECOMPRESS:
646 case ICM_DECOMPRESSEX_QUERY:
647 case ICM_DECOMPRESSEX_BEGIN:
648 case ICM_DECOMPRESSEX:
649 case ICM_DRAW_BEGIN:
650 case ICM_DRAW_SUGGESTFORMAT:
651 case ICM_DRAW:
652 HeapFree(GetProcessHeap(), 0, data16);
653 break;
654 default:
655 ERR("Unmapping unmapped msg %d\n", msg);
657 #undef UNCOPY
660 /***********************************************************************
661 * ICInfo [MSVIDEO.200]
663 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
665 BOOL16 ret;
666 LPVOID lpv;
667 DWORD lParam = (DWORD)lpicinfo;
668 DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
670 /* Use the mapping functions to map the ICINFO structure */
671 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
673 ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
675 MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
677 return ret;
680 /******************************************************************
681 * IC_Callback3216
685 static LRESULT CALLBACK IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, LPARAM lp1, LPARAM lp2)
687 WORD args[8];
688 DWORD ret = 0;
690 switch (msg)
692 case DRV_OPEN:
693 lp2 = (DWORD)MapLS((void*)lp2);
694 break;
696 args[7] = HIWORD(hic);
697 args[6] = LOWORD(hic);
698 args[5] = HDRVR_16(hdrv);
699 args[4] = msg;
700 args[3] = HIWORD(lp1);
701 args[2] = LOWORD(lp1);
702 args[1] = HIWORD(lp2);
703 args[0] = LOWORD(lp2);
704 WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
706 switch (msg)
708 case DRV_OPEN:
709 UnMapLS(lp2);
710 break;
712 return ret;
715 #define MAX_THUNKS 32
717 #include "pshpack1.h"
718 static struct msvideo_thunk
720 BYTE popl_eax; /* popl %eax (return address) */
721 BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
722 DWORD pfn16;
723 BYTE pushl_eax; /* pushl %eax */
724 BYTE jmp; /* ljmp WDML_InvokeCallback16 */
725 DWORD callback;
726 HIC16 hIC16; /* driver's handle */
727 } *MSVIDEO_Thunks;
728 #include "poppack.h"
730 static CRITICAL_SECTION msvideo_cs;
731 static CRITICAL_SECTION_DEBUG critsect_debug =
733 0, 0, &msvideo_cs,
734 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
735 0, 0, { (DWORD_PTR)(__FILE__ ": msvideo_cs") }
737 static CRITICAL_SECTION msvideo_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
739 static struct msvideo_thunk* MSVIDEO_AddThunk(DWORD pfn16)
741 struct msvideo_thunk* thunk;
743 if (!MSVIDEO_Thunks)
745 MSVIDEO_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*MSVIDEO_Thunks), MEM_COMMIT,
746 PAGE_EXECUTE_READWRITE);
747 if (!MSVIDEO_Thunks) return NULL;
748 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
750 thunk->popl_eax = 0x58; /* popl %eax */
751 thunk->pushl_func = 0x68; /* pushl $pfn16 */
752 thunk->pfn16 = 0;
753 thunk->pushl_eax = 0x50; /* pushl %eax */
754 thunk->jmp = 0xe9; /* jmp IC_Callback3216 */
755 thunk->callback = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1);
756 thunk->hIC16 = 0;
759 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
761 if (thunk->pfn16 == 0)
763 thunk->pfn16 = pfn16;
764 return thunk;
767 FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
768 return NULL;
771 static struct msvideo_thunk* MSVIDEO_HasThunk(HIC16 hic)
773 struct msvideo_thunk* thunk;
775 if (!MSVIDEO_Thunks)
776 return NULL;
778 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
780 if (thunk->hIC16 == hic) return thunk;
782 return NULL;
785 /***********************************************************************
786 * ICOpenFunction [MSVIDEO.206]
788 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
790 HIC hic32;
791 struct msvideo_thunk* thunk;
793 EnterCriticalSection(&msvideo_cs);
794 if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler)))
796 LeaveCriticalSection(&msvideo_cs);
797 return 0;
799 if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)thunk)))
800 thunk->hIC16 = HIC_16(hic32);
801 else
802 thunk->pfn16 = 0;
803 LeaveCriticalSection(&msvideo_cs);
804 return HIC_16(hic32);
807 /***********************************************************************
808 * ICSendMessage [MSVIDEO.205]
810 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2)
812 LRESULT ret = ICERR_BADHANDLE;
813 struct msvideo_thunk* thunk;
815 if ((thunk = MSVIDEO_HasThunk(hic)))
817 WORD args[8];
818 DWORD result;
820 /* FIXME: original code was passing hdrv first and hic second */
821 /* but this doesn't match what IC_Callback3216 does */
822 args[7] = HIWORD(hic);
823 args[6] = LOWORD(hic);
824 args[5] = 0; /* the 32bit also sets it to NULL */
825 args[4] = msg;
826 args[3] = HIWORD(lParam1);
827 args[2] = LOWORD(lParam1);
828 args[1] = HIWORD(lParam2);
829 args[0] = LOWORD(lParam2);
830 WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result );
831 ret = result;
833 else
835 /* map the message for a 32 bit infrastructure, and pass it along */
836 void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
838 ret = ICSendMessage(HIC_32(hic), msg, lParam1, lParam2);
839 if (data16)
840 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
842 return ret;
845 /***********************************************************************
846 * ICClose [MSVIDEO.204]
848 LRESULT WINAPI ICClose16(HIC16 hic)
850 BOOL ret = ICClose(HIC_32(hic));
852 EnterCriticalSection(&msvideo_cs);
853 if (ret)
855 struct msvideo_thunk* thunk;
856 if ((thunk = MSVIDEO_HasThunk(hic)))
858 thunk->pfn16 = 0;
859 thunk->hIC16 = 0;
861 else ret = FALSE;
863 LeaveCriticalSection(&msvideo_cs);
864 return ret;
867 /***********************************************************************
868 * VideoCapDriverDescAndVer [MSVIDEO.22]
870 DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
871 LPSTR buf2, WORD buf2len)
873 static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
874 DWORD verhandle;
875 DWORD infosize;
876 UINT subblocklen;
877 char *s, buf[2048], fn[260];
878 LPBYTE infobuf;
879 LPVOID subblock;
880 DWORD i, cnt = 0, lRet;
881 DWORD bufLen, fnLen;
882 FILETIME lastWrite;
883 HKEY hKey;
884 BOOL found = FALSE;
886 TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
887 lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
888 if (lRet == ERROR_SUCCESS)
890 RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
891 for (i = 0; i < cnt; i++)
893 bufLen = ARRAY_SIZE(buf);
894 lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
895 if (lRet != ERROR_SUCCESS) continue;
896 if (_strnicmp(buf, "vid", 3)) continue;
897 if (nr--) continue;
898 fnLen = sizeof(fn);
899 lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
900 if (lRet == ERROR_SUCCESS) found = TRUE;
901 break;
903 RegCloseKey( hKey );
906 /* search system.ini if not found in the registry */
907 if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
909 for (s = buf; *s; s += strlen(s) + 1)
911 if (_strnicmp(s, "vid", 3)) continue;
912 if (nr--) continue;
913 if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
914 found = TRUE;
915 break;
919 if (!found)
921 TRACE("No more VID* entries found nr=%d\n", nr);
922 return 20;
924 infosize = GetFileVersionInfoSizeA(fn, &verhandle);
925 if (!infosize)
927 TRACE("%s has no fileversioninfo.\n", fn);
928 return 18;
930 infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
931 if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf))
933 /* Yes, two space behind : */
934 /* FIXME: test for buflen */
935 snprintf(buf2, buf2len, "Version: %d.%d.%d.%d\n",
936 ((WORD*)infobuf)[0x0f],
937 ((WORD*)infobuf)[0x0e],
938 ((WORD*)infobuf)[0x11],
939 ((WORD*)infobuf)[0x10]
941 TRACE("version of %s is %s\n", fn, buf2);
943 else
945 TRACE("GetFileVersionInfoA failed for %s.\n", fn);
946 lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
948 /* FIXME: language problem? */
949 if (VerQueryValueA( infobuf,
950 version_info_spec,
951 &subblock,
952 &subblocklen
955 UINT copylen = min(subblocklen,buf1len-1);
956 memcpy(buf1, subblock, copylen);
957 buf1[copylen] = '\0';
958 TRACE("VQA returned %s\n", (LPCSTR)subblock);
960 else
962 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
963 lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
965 HeapFree(GetProcessHeap(), 0, infobuf);
966 return 0;
969 /**************************************************************************
970 * DllEntryPoint (MSVIDEO.3)
972 * MSVIDEO DLL entry point
975 BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
976 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
978 switch (fdwReason)
980 case DLL_PROCESS_ATTACH:
981 break;
982 case DLL_PROCESS_DETACH:
983 DeleteCriticalSection(&msvideo_cs);
984 break;
986 return TRUE;
989 /***********************************************************************
990 * MCIWndRegisterClass(MSVIDEO.251)
992 BOOL CDECL MCIWndRegisterClass16(void)
994 return MCIWndRegisterClass();
997 static LRESULT (WINAPI *pMCIWndProc)(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
999 static LRESULT WINAPI MCIWndProc16(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
1001 switch (msg)
1003 case MCIWNDM_SENDSTRINGA:
1004 case MCIWNDM_SETTIMEFORMATA:
1005 lparam = (ULONG_PTR)MapSL(lparam);
1006 break;
1008 default:
1009 break;
1012 return CallWindowProcA(pMCIWndProc, hwnd, msg, wparam, lparam);
1015 /***********************************************************************
1016 * MCIWndCreate(MSVIDEO.250)
1018 HWND16 CDECL MCIWndCreate16(HWND16 parent, HINSTANCE16 hinst16,
1019 DWORD style, LPSTR file)
1021 HWND hwnd = MCIWndCreateA(HWND_32(parent), 0, style, file);
1022 if (hwnd)
1023 pMCIWndProc = (void *)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (ULONG_PTR)MCIWndProc16);
1024 return HWND_16(hwnd);