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 * DrawDibProfileDisplay [MSVIDEO.114]
126 BOOL16 VFWAPI
DrawDibProfileDisplay16(LPBITMAPINFOHEADER lpbi
)
128 TRACE("(%p)\n", lpbi
);
129 return DrawDibProfileDisplay(lpbi
);
132 /*************************************************************************
133 * DrawDibStart [MSVIDEO.118]
135 BOOL16 VFWAPI
DrawDibStart16(HDRAWDIB16 hdd
, DWORD rate
)
137 return DrawDibStart(HDRAWDIB_32(hdd
), rate
);
140 /*************************************************************************
141 * DrawDibStop [MSVIDEO.119]
143 BOOL16 VFWAPI
DrawDibStop16(HDRAWDIB16 hdd
)
145 return DrawDibStop(HDRAWDIB_32(hdd
));
148 /***********************************************************************
149 * ICOpen [MSVIDEO.203]
151 HIC16 VFWAPI
ICOpen16(DWORD fccType
, DWORD fccHandler
, UINT16 wMode
)
153 return HIC_16(ICOpen(fccType
, fccHandler
, wMode
));
156 /***********************************************************************
157 * _ICMessage [MSVIDEO.207]
159 LRESULT VFWAPIV
ICMessage16( HIC16 hic
, UINT16 msg
, UINT16 cb
, VA_LIST16 valist
)
166 lpData
= HeapAlloc(GetProcessHeap(), 0, cb
);
168 TRACE("0x%08x, %u, %u, ...)\n", (DWORD
) hic
, msg
, cb
);
170 for (i
= 0; i
< cb
/ sizeof(WORD
); i
++)
172 lpData
[i
] = VA_ARG16(valist
, WORD
);
175 segData
= MapLS(lpData
);
176 ret
= ICSendMessage16(hic
, msg
, segData
, (DWORD
) cb
);
178 HeapFree(GetProcessHeap(), 0, lpData
);
182 /***********************************************************************
183 * ICGetInfo [MSVIDEO.212]
185 LRESULT VFWAPI
ICGetInfo16(HIC16 hic
, ICINFO16
* picinfo
, DWORD cb
)
189 TRACE("(0x%08x,%p,%d)\n", (DWORD
) hic
, picinfo
, cb
);
190 ret
= ICSendMessage16(hic
, ICM_GETINFO
, (DWORD
) picinfo
, cb
);
191 TRACE(" -> 0x%08lx\n", ret
);
195 /***********************************************************************
196 * ICLocate [MSVIDEO.213]
198 HIC16 VFWAPI
ICLocate16(DWORD fccType
, DWORD fccHandler
,
199 LPBITMAPINFOHEADER lpbiIn
, LPBITMAPINFOHEADER lpbiOut
,
202 return HIC_16(ICLocate(fccType
, fccHandler
, lpbiIn
, lpbiOut
, wFlags
));
205 /***********************************************************************
206 * _ICCompress [MSVIDEO.224]
208 DWORD VFWAPIV
ICCompress16(HIC16 hic
, DWORD dwFlags
,
209 LPBITMAPINFOHEADER lpbiOutput
, LPVOID lpData
,
210 LPBITMAPINFOHEADER lpbiInput
, LPVOID lpBits
,
211 LPDWORD lpckid
, LPDWORD lpdwFlags
,
212 LONG lFrameNum
, DWORD dwFrameSize
,
213 DWORD dwQuality
, LPBITMAPINFOHEADER lpbiPrev
,
220 TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD
) hic
, dwFlags
,
221 lpbiOutput
, lpData
, lpbiInput
, lpBits
);
223 iccmp
.dwFlags
= dwFlags
;
225 iccmp
.lpbiOutput
= lpbiOutput
;
226 iccmp
.lpOutput
= lpData
;
227 iccmp
.lpbiInput
= lpbiInput
;
228 iccmp
.lpInput
= lpBits
;
230 iccmp
.lpckid
= lpckid
;
231 iccmp
.lpdwFlags
= lpdwFlags
;
232 iccmp
.lFrameNum
= lFrameNum
;
233 iccmp
.dwFrameSize
= dwFrameSize
;
234 iccmp
.dwQuality
= dwQuality
;
235 iccmp
.lpbiPrev
= lpbiPrev
;
236 iccmp
.lpPrev
= lpPrev
;
237 seg_iccmp
= MapLS(&iccmp
);
238 ret
= ICSendMessage16(hic
, ICM_COMPRESS
, seg_iccmp
, sizeof(ICCOMPRESS
));
243 /***********************************************************************
244 * _ICDecompress [MSVIDEO.230]
246 DWORD VFWAPIV
ICDecompress16(HIC16 hic
, DWORD dwFlags
,
247 LPBITMAPINFOHEADER lpbiFormat
, LPVOID lpData
,
248 LPBITMAPINFOHEADER lpbi
, LPVOID lpBits
)
254 TRACE("(0x%08x,%d,%p,%p,%p,%p)\n", (DWORD
) hic
, dwFlags
, lpbiFormat
,
255 lpData
, lpbi
, lpBits
);
257 icd
.dwFlags
= dwFlags
;
258 icd
.lpbiInput
= lpbiFormat
;
259 icd
.lpInput
= lpData
;
260 icd
.lpbiOutput
= lpbi
;
261 icd
.lpOutput
= lpBits
;
263 segptr
= MapLS(&icd
);
264 ret
= ICSendMessage16(hic
, ICM_DECOMPRESS
, segptr
, sizeof(ICDECOMPRESS
));
269 /***********************************************************************
270 * _ICDrawBegin [MSVIDEO.232]
272 DWORD VFWAPIV
ICDrawBegin16(HIC16 hic
, /* [in] */
273 DWORD dwFlags
, /* [in] flags */
274 HPALETTE16 hpal
, /* [in] palette to draw with */
275 HWND16 hwnd
, /* [in] window to draw to */
276 HDC16 hdc
, /* [in] HDC to draw to */
277 INT16 xDst
, /* [in] destination rectangle */
278 INT16 yDst
, /* [in] */
279 INT16 dxDst
, /* [in] */
280 INT16 dyDst
, /* [in] */
281 LPBITMAPINFOHEADER lpbi
, /* [in] format of frame to draw NOTE: SEGPTR */
282 INT16 xSrc
, /* [in] source rectangle */
283 INT16 ySrc
, /* [in] */
284 INT16 dxSrc
, /* [in] */
285 INT16 dySrc
, /* [in] */
286 DWORD dwRate
, /* [in] frames/second = (dwRate/dwScale) */
287 DWORD dwScale
) /* [in] */
293 TRACE ("(0x%08x,%d,0x%08x,0x%08x,0x%08x,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
294 (DWORD
) hic
, dwFlags
, (DWORD
) hpal
, (DWORD
) hwnd
, (DWORD
) hdc
,
295 xDst
, yDst
, dxDst
, dyDst
, lpbi
, xSrc
, ySrc
, dxSrc
, dySrc
, dwRate
,
298 icdb
.dwFlags
= dwFlags
;
306 icdb
.lpbi
= lpbi
; /* Keep this as SEGPTR for the mapping code to deal with */
311 icdb
.dwRate
= dwRate
;
312 icdb
.dwScale
= dwScale
;
313 seg_icdb
= MapLS(&icdb
);
314 ret
= (DWORD
) ICSendMessage16(hic
, ICM_DRAW_BEGIN
, seg_icdb
,
315 sizeof(ICDRAWBEGIN16
));
320 /***********************************************************************
321 * _ICDraw [MSVIDEO.234]
323 DWORD VFWAPIV
ICDraw16(HIC16 hic
, DWORD dwFlags
,
324 LPVOID lpFormat
, /* [???] NOTE: SEGPTR */
325 LPVOID lpData
, /* [???] NOTE: SEGPTR */
326 DWORD cbData
, LONG lTime
)
332 TRACE("(0x%08x,0x%08x,%p,%p,%d,%d)\n", (DWORD
) hic
, dwFlags
,
333 lpFormat
, lpData
, cbData
, lTime
);
334 icd
.dwFlags
= dwFlags
;
335 icd
.lpFormat
= lpFormat
;
339 seg_icd
= MapLS(&icd
);
340 ret
= ICSendMessage16(hic
, ICM_DRAW
, seg_icd
, sizeof(ICDRAW
));
345 /***********************************************************************
346 * ICGetDisplayFormat [MSVIDEO.239]
348 HIC16 VFWAPI
ICGetDisplayFormat16(HIC16 hic
, LPBITMAPINFOHEADER lpbiIn
,
349 LPBITMAPINFOHEADER lpbiOut
, INT16 depth
,
352 return HIC_16(ICGetDisplayFormat(HIC_32(hic
), lpbiIn
, lpbiOut
, depth
,
356 #define COPY(x,y) (x->y = x##16->y);
357 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
359 /******************************************************************
360 * MSVIDEO_MapICDEX16To32
364 static LPVOID
MSVIDEO_MapICDEX16To32(LPDWORD lParam
)
368 ICDECOMPRESSEX
*icdx
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX
));
369 ICDECOMPRESSEX16
*icdx16
= MapSL(*lParam
);
373 COPYPTR(icdx
, lpbiSrc
);
374 COPYPTR(icdx
, lpSrc
);
375 COPYPTR(icdx
, lpbiDst
);
376 COPYPTR(icdx
, lpDst
);
386 *lParam
= (DWORD
)(icdx
);
390 /******************************************************************
391 * MSVIDEO_MapMsg16To32
395 static LPVOID
MSVIDEO_MapMsg16To32(UINT msg
, LPDWORD lParam1
, LPDWORD lParam2
)
399 TRACE("Mapping %d\n", msg
);
410 case ICM_COMPRESS_END
:
411 case ICM_DECOMPRESS_END
:
412 case ICM_DECOMPRESSEX_END
:
414 case ICM_DRAW_START_PLAY
:
415 case ICM_DRAW_STOP_PLAY
:
416 case ICM_DRAW_REALIZE
:
417 case ICM_DRAW_RENDERBUFFER
:
421 case ICM_GETDEFAULTQUALITY
:
424 case ICM_DRAW_WINDOW
:
425 case ICM_GETBUFFERSWANTED
:
426 *lParam1
= (DWORD
)MapSL(*lParam1
);
430 ICINFO
*ici
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO
));
433 ici16
= MapSL(*lParam1
);
436 ici
->dwSize
= sizeof(ICINFO
);
438 COPY(ici
, fccHandler
);
440 COPY(ici
, dwVersion
);
441 COPY(ici
, dwVersionICM
);
442 MultiByteToWideChar( CP_ACP
, 0, ici16
->szName
, -1, ici
->szName
, 16 );
443 MultiByteToWideChar( CP_ACP
, 0, ici16
->szDescription
, -1, ici
->szDescription
, 128 );
444 MultiByteToWideChar( CP_ACP
, 0, ici16
->szDriver
, -1, ici
->szDriver
, 128 );
445 *lParam1
= (DWORD
)(ici
);
446 *lParam2
= sizeof(ICINFO
);
451 ICCOMPRESS
*icc
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS
));
454 icc16
= MapSL(*lParam1
);
458 COPYPTR(icc
, lpbiOutput
);
459 COPYPTR(icc
, lpOutput
);
460 COPYPTR(icc
, lpbiInput
);
461 COPYPTR(icc
, lpInput
);
462 COPYPTR(icc
, lpckid
);
463 COPYPTR(icc
, lpdwFlags
);
464 COPY(icc
, lFrameNum
);
465 COPY(icc
, dwFrameSize
);
466 COPY(icc
, dwQuality
);
467 COPYPTR(icc
, lpbiPrev
);
468 COPYPTR(icc
, lpPrev
);
470 *lParam1
= (DWORD
)(icc
);
471 *lParam2
= sizeof(ICCOMPRESS
);
476 ICDECOMPRESS
*icd
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS
));
477 ICDECOMPRESS
*icd16
; /* Same structure except for the pointers */
479 icd16
= MapSL(*lParam1
);
483 COPYPTR(icd
, lpbiInput
);
484 COPYPTR(icd
, lpInput
);
485 COPYPTR(icd
, lpbiOutput
);
486 COPYPTR(icd
, lpOutput
);
489 *lParam1
= (DWORD
)(icd
);
490 *lParam2
= sizeof(ICDECOMPRESS
);
493 case ICM_COMPRESS_BEGIN
:
494 case ICM_COMPRESS_GET_FORMAT
:
495 case ICM_COMPRESS_GET_SIZE
:
496 case ICM_COMPRESS_QUERY
:
497 case ICM_DECOMPRESS_GET_FORMAT
:
498 case ICM_DECOMPRESS_QUERY
:
499 case ICM_DECOMPRESS_BEGIN
:
500 case ICM_DECOMPRESS_SET_PALETTE
:
501 case ICM_DECOMPRESS_GET_PALETTE
:
502 *lParam1
= (DWORD
)MapSL(*lParam1
);
503 *lParam2
= (DWORD
)MapSL(*lParam2
);
505 case ICM_DECOMPRESSEX_QUERY
:
506 if ((*lParam2
!= sizeof(ICDECOMPRESSEX16
)) && (*lParam2
!= 0))
507 WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16
*)*lParam2
);
508 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
509 * This is because of ICMessage(). Special case it?
511 LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
512 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
514 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
521 case ICM_DECOMPRESSEX_BEGIN
:
522 case ICM_DECOMPRESSEX
:
523 ret
= MSVIDEO_MapICDEX16To32(lParam1
);
524 *lParam2
= sizeof(ICDECOMPRESSEX
);
528 ICDRAWBEGIN
*icdb
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN
));
529 ICDRAWBEGIN16
*icdb16
= MapSL(*lParam1
);
533 icdb
->hpal
= HPALETTE_32(icdb16
->hpal
);
534 icdb
->hwnd
= HWND_32(icdb16
->hwnd
);
535 icdb
->hdc
= HDC_32(icdb16
->hdc
);
548 *lParam1
= (DWORD
)(icdb
);
549 *lParam2
= sizeof(ICDRAWBEGIN
);
552 case ICM_DRAW_SUGGESTFORMAT
:
554 ICDRAWSUGGEST
*icds
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST
));
555 ICDRAWSUGGEST16
*icds16
= MapSL(*lParam1
);
560 COPYPTR(icds
, lpbiIn
);
561 COPYPTR(icds
, lpbiSuggest
);
566 icds
->hicDecompressor
= HIC_32(icds16
->hicDecompressor
);
568 *lParam1
= (DWORD
)(icds
);
569 *lParam2
= sizeof(ICDRAWSUGGEST
);
574 ICDRAW
*icd
= HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW
));
575 ICDRAW
*icd16
= MapSL(*lParam1
);
579 COPYPTR(icd
, lpFormat
);
580 COPYPTR(icd
, lpData
);
584 *lParam1
= (DWORD
)(icd
);
585 *lParam2
= sizeof(ICDRAW
);
592 FIXME("%d is not yet handled. Expect a crash.\n", msg
);
600 /******************************************************************
601 * MSVIDEO_UnmapMsg16To32
605 static void MSVIDEO_UnmapMsg16To32(UINT msg
, LPVOID data16
, LPDWORD lParam1
, LPDWORD lParam2
)
607 TRACE("Unmapping %d\n", msg
);
609 #define UNCOPY(x, y) (x##16->y = x->y);
615 ICINFO
*ici
= (ICINFO
*)(*lParam1
);
616 ICINFO16
*ici16
= data16
;
618 UNCOPY(ici
, fccType
);
619 UNCOPY(ici
, fccHandler
);
620 UNCOPY(ici
, dwFlags
);
621 UNCOPY(ici
, dwVersion
);
622 UNCOPY(ici
, dwVersionICM
);
623 WideCharToMultiByte( CP_ACP
, 0, ici
->szName
, -1, ici16
->szName
,
624 sizeof(ici16
->szName
), NULL
, NULL
);
625 ici16
->szName
[sizeof(ici16
->szName
)-1] = 0;
626 WideCharToMultiByte( CP_ACP
, 0, ici
->szDescription
, -1, ici16
->szDescription
,
627 sizeof(ici16
->szDescription
), NULL
, NULL
);
628 ici16
->szDescription
[sizeof(ici16
->szDescription
)-1] = 0;
629 /* This just gives garbage for some reason - BB
630 lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
632 HeapFree(GetProcessHeap(), 0, ici
);
635 case ICM_DECOMPRESS_QUERY
:
638 HeapFree(GetProcessHeap(), 0, x[0]);
640 HeapFree(GetProcessHeap(), 0, x[1]);
645 case ICM_DECOMPRESSEX_QUERY
:
646 case ICM_DECOMPRESSEX_BEGIN
:
647 case ICM_DECOMPRESSEX
:
649 case ICM_DRAW_SUGGESTFORMAT
:
651 HeapFree(GetProcessHeap(), 0, data16
);
654 ERR("Unmapping unmapped msg %d\n", msg
);
659 /***********************************************************************
660 * ICInfo [MSVIDEO.200]
662 BOOL16 VFWAPI
ICInfo16(DWORD fccType
, DWORD fccHandler
, ICINFO16
*lpicinfo
)
666 DWORD lParam
= (DWORD
)lpicinfo
;
667 DWORD size
= ((ICINFO
*)(MapSL((SEGPTR
)lpicinfo
)))->dwSize
;
669 /* Use the mapping functions to map the ICINFO structure */
670 lpv
= MSVIDEO_MapMsg16To32(ICM_GETINFO
, &lParam
, &size
);
672 ret
= ICInfo(fccType
, fccHandler
, (ICINFO
*)lParam
);
674 MSVIDEO_UnmapMsg16To32(ICM_GETINFO
, lpv
, &lParam
, &size
);
679 /******************************************************************
684 static LRESULT CALLBACK
IC_Callback3216(DWORD pfn16
, HIC hic
, HDRVR hdrv
, UINT msg
, LPARAM lp1
, LPARAM lp2
)
692 lp2
= (DWORD
)MapLS((void*)lp2
);
695 args
[7] = HIWORD(hic
);
696 args
[6] = LOWORD(hic
);
697 args
[5] = HDRVR_16(hdrv
);
699 args
[3] = HIWORD(lp1
);
700 args
[2] = LOWORD(lp1
);
701 args
[1] = HIWORD(lp2
);
702 args
[0] = LOWORD(lp2
);
703 WOWCallback16Ex( pfn16
, WCB16_PASCAL
, sizeof(args
), args
, &ret
);
714 #define MAX_THUNKS 32
716 #include "pshpack1.h"
717 static struct msvideo_thunk
719 BYTE popl_eax
; /* popl %eax (return address) */
720 BYTE pushl_func
; /* pushl $pfn16 (16bit callback function) */
722 BYTE pushl_eax
; /* pushl %eax */
723 BYTE jmp
; /* ljmp WDML_InvokeCallback16 */
725 HIC16 hIC16
; /* driver's handle */
729 static CRITICAL_SECTION msvideo_cs
;
730 static CRITICAL_SECTION_DEBUG critsect_debug
=
733 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
734 0, 0, { (DWORD_PTR
)(__FILE__
": msvideo_cs") }
736 static CRITICAL_SECTION msvideo_cs
= { &critsect_debug
, -1, 0, 0, 0, 0 };
738 static struct msvideo_thunk
* MSVIDEO_AddThunk(DWORD pfn16
)
740 struct msvideo_thunk
* thunk
;
744 MSVIDEO_Thunks
= VirtualAlloc(NULL
, MAX_THUNKS
* sizeof(*MSVIDEO_Thunks
), MEM_COMMIT
,
745 PAGE_EXECUTE_READWRITE
);
746 if (!MSVIDEO_Thunks
) return NULL
;
747 for (thunk
= MSVIDEO_Thunks
; thunk
< &MSVIDEO_Thunks
[MAX_THUNKS
]; thunk
++)
749 thunk
->popl_eax
= 0x58; /* popl %eax */
750 thunk
->pushl_func
= 0x68; /* pushl $pfn16 */
752 thunk
->pushl_eax
= 0x50; /* pushl %eax */
753 thunk
->jmp
= 0xe9; /* jmp IC_Callback3216 */
754 thunk
->callback
= (char *)IC_Callback3216
- (char *)(&thunk
->callback
+ 1);
758 for (thunk
= MSVIDEO_Thunks
; thunk
< &MSVIDEO_Thunks
[MAX_THUNKS
]; thunk
++)
760 if (thunk
->pfn16
== 0)
762 thunk
->pfn16
= pfn16
;
766 FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
770 static struct msvideo_thunk
* MSVIDEO_HasThunk(HIC16 hic
)
772 struct msvideo_thunk
* thunk
;
777 for (thunk
= MSVIDEO_Thunks
; thunk
< &MSVIDEO_Thunks
[MAX_THUNKS
]; thunk
++)
779 if (thunk
->hIC16
== hic
) return thunk
;
784 /***********************************************************************
785 * ICOpenFunction [MSVIDEO.206]
787 HIC16 VFWAPI
ICOpenFunction16(DWORD fccType
, DWORD fccHandler
, UINT16 wMode
, FARPROC16 lpfnHandler
)
790 struct msvideo_thunk
* thunk
;
792 EnterCriticalSection(&msvideo_cs
);
793 if (!(thunk
= MSVIDEO_AddThunk((DWORD
)lpfnHandler
)))
795 LeaveCriticalSection(&msvideo_cs
);
798 if ((hic32
= ICOpenFunction(fccType
, fccHandler
, wMode
, (DRIVERPROC
)thunk
)))
799 thunk
->hIC16
= HIC_16(hic32
);
802 LeaveCriticalSection(&msvideo_cs
);
803 return HIC_16(hic32
);
806 /***********************************************************************
807 * ICSendMessage [MSVIDEO.205]
809 LRESULT VFWAPI
ICSendMessage16(HIC16 hic
, UINT16 msg
, DWORD lParam1
, DWORD lParam2
)
811 LRESULT ret
= ICERR_BADHANDLE
;
812 struct msvideo_thunk
* thunk
;
814 if ((thunk
= MSVIDEO_HasThunk(hic
)))
819 /* FIXME: original code was passing hdrv first and hic second */
820 /* but this doesn't match what IC_Callback3216 does */
821 args
[7] = HIWORD(hic
);
822 args
[6] = LOWORD(hic
);
823 args
[5] = 0; /* the 32bit also sets it to NULL */
825 args
[3] = HIWORD(lParam1
);
826 args
[2] = LOWORD(lParam1
);
827 args
[1] = HIWORD(lParam2
);
828 args
[0] = LOWORD(lParam2
);
829 WOWCallback16Ex( thunk
->pfn16
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
834 /* map the message for a 32 bit infrastructure, and pass it along */
835 void* data16
= MSVIDEO_MapMsg16To32(msg
, &lParam1
, &lParam2
);
837 ret
= ICSendMessage(HIC_32(hic
), msg
, lParam1
, lParam2
);
839 MSVIDEO_UnmapMsg16To32(msg
, data16
, &lParam1
, &lParam2
);
844 /***********************************************************************
845 * ICClose [MSVIDEO.204]
847 LRESULT WINAPI
ICClose16(HIC16 hic
)
849 BOOL ret
= ICClose(HIC_32(hic
));
851 EnterCriticalSection(&msvideo_cs
);
854 struct msvideo_thunk
* thunk
;
855 if ((thunk
= MSVIDEO_HasThunk(hic
)))
862 LeaveCriticalSection(&msvideo_cs
);
866 /***********************************************************************
867 * VideoCapDriverDescAndVer [MSVIDEO.22]
869 DWORD WINAPI
VideoCapDriverDescAndVer16(WORD nr
, LPSTR buf1
, WORD buf1len
,
870 LPSTR buf2
, WORD buf2len
)
872 static const char version_info_spec
[] = "\\StringFileInfo\\040904E4\\FileDescription";
876 char *s
, buf
[2048], fn
[260];
879 DWORD i
, cnt
= 0, lRet
;
885 TRACE("(%d,%p,%d,%p,%d)\n", nr
, buf1
, buf1len
, buf2
, buf2len
);
886 lRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, HKLM_DRIVERS32
, 0, KEY_QUERY_VALUE
, &hKey
);
887 if (lRet
== ERROR_SUCCESS
)
889 RegQueryInfoKeyA( hKey
, 0, 0, 0, &cnt
, 0, 0, 0, 0, 0, 0, 0);
890 for (i
= 0; i
< cnt
; i
++)
892 bufLen
= ARRAY_SIZE(buf
);
893 lRet
= RegEnumKeyExA(hKey
, i
, buf
, &bufLen
, 0, 0, 0, &lastWrite
);
894 if (lRet
!= ERROR_SUCCESS
) continue;
895 if (strncasecmp(buf
, "vid", 3)) continue;
898 lRet
= RegQueryValueExA(hKey
, buf
, 0, 0, (LPBYTE
)fn
, &fnLen
);
899 if (lRet
== ERROR_SUCCESS
) found
= TRUE
;
905 /* search system.ini if not found in the registry */
906 if (!found
&& GetPrivateProfileStringA("drivers32", NULL
, NULL
, buf
, sizeof(buf
), "system.ini"))
908 for (s
= buf
; *s
; s
+= strlen(s
) + 1)
910 if (strncasecmp(s
, "vid", 3)) continue;
912 if (GetPrivateProfileStringA("drivers32", s
, NULL
, fn
, sizeof(fn
), "system.ini"))
920 TRACE("No more VID* entries found nr=%d\n", nr
);
923 infosize
= GetFileVersionInfoSizeA(fn
, &verhandle
);
926 TRACE("%s has no fileversioninfo.\n", fn
);
929 infobuf
= HeapAlloc(GetProcessHeap(), 0, infosize
);
930 if (GetFileVersionInfoA(fn
, verhandle
, infosize
, infobuf
))
932 /* Yes, two space behind : */
933 /* FIXME: test for buflen */
934 snprintf(buf2
, buf2len
, "Version: %d.%d.%d.%d\n",
935 ((WORD
*)infobuf
)[0x0f],
936 ((WORD
*)infobuf
)[0x0e],
937 ((WORD
*)infobuf
)[0x11],
938 ((WORD
*)infobuf
)[0x10]
940 TRACE("version of %s is %s\n", fn
, buf2
);
944 TRACE("GetFileVersionInfoA failed for %s.\n", fn
);
945 lstrcpynA(buf2
, fn
, buf2len
); /* msvideo.dll appears to copy fn*/
947 /* FIXME: language problem? */
948 if (VerQueryValueA( infobuf
,
954 UINT copylen
= min(subblocklen
,buf1len
-1);
955 memcpy(buf1
, subblock
, copylen
);
956 buf1
[copylen
] = '\0';
957 TRACE("VQA returned %s\n", (LPCSTR
)subblock
);
961 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
962 lstrcpynA(buf1
, fn
, buf1len
); /* msvideo.dll appears to copy fn*/
964 HeapFree(GetProcessHeap(), 0, infobuf
);
968 /**************************************************************************
969 * DllEntryPoint (MSVIDEO.3)
971 * MSVIDEO DLL entry point
974 BOOL WINAPI
VIDEO_LibMain(DWORD fdwReason
, HINSTANCE hinstDLL
, WORD ds
,
975 WORD wHeapSize
, DWORD dwReserved1
, WORD wReserved2
)
979 case DLL_PROCESS_ATTACH
:
981 case DLL_PROCESS_DETACH
:
982 DeleteCriticalSection(&msvideo_cs
);
988 /***********************************************************************
989 * MCIWndRegisterClass(MSVIDEO.251)
991 BOOL CDECL
MCIWndRegisterClass16(void)
993 return MCIWndRegisterClass();
996 static LRESULT (WINAPI
*pMCIWndProc
)(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
);
998 static LRESULT WINAPI
MCIWndProc16(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1002 case MCIWNDM_SENDSTRINGA
:
1003 case MCIWNDM_SETTIMEFORMATA
:
1004 lparam
= (ULONG_PTR
)MapSL(lparam
);
1011 return CallWindowProcA(pMCIWndProc
, hwnd
, msg
, wparam
, lparam
);
1014 /***********************************************************************
1015 * MCIWndCreate(MSVIDEO.250)
1017 HWND16 CDECL
MCIWndCreate16(HWND16 parent
, HINSTANCE16 hinst16
,
1018 DWORD style
, LPSTR file
)
1020 HWND hwnd
= MCIWndCreateA(HWND_32(parent
), 0, style
, file
);
1022 pMCIWndProc
= (void *)SetWindowLongPtrA(hwnd
, GWLP_WNDPROC
, (ULONG_PTR
)MCIWndProc16
);
1023 return HWND_16(hwnd
);