1985 lines
53 KiB
C
1985 lines
53 KiB
C
|
//==========================================================================;
|
||
|
// COMMENTS DO NOT YET APPLY TO MSVIDEO.DLL/MSVFW32.DLL
|
||
|
// thunk.c
|
||
|
//
|
||
|
// Copyright (c) 1991-1994 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
// Description:
|
||
|
// This module contains routines for thunking the
|
||
|
// ICM APIs (messages) from 16-bit Windows to 32-bit WOW.
|
||
|
//
|
||
|
// History:
|
||
|
//
|
||
|
//==========================================================================;
|
||
|
|
||
|
|
||
|
// This stuff is not going to work 64-bit
|
||
|
#pragma warning(disable:4312)
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
WOW Thunking design:
|
||
|
|
||
|
Thunks are generated as follows :
|
||
|
|
||
|
16-bit :
|
||
|
acmBootDrivers->acmInitThunks :
|
||
|
|
||
|
Generate calls to 32-bit drivers if we're in WOW call across
|
||
|
to KERNEL to find thunking entry points.
|
||
|
|
||
|
If we're thunking 'load' all the 32-bit ACM drivers as well as
|
||
|
the 16-bit ones.
|
||
|
|
||
|
Priority is always to find a 32-bit driver first but this is
|
||
|
done via searching for one on open.
|
||
|
|
||
|
The internal flag ACM_DRIVERADDF_32BIT is specified when
|
||
|
calling IDriverAdd and this flag is stored in the ACMDRIVERID
|
||
|
structure.
|
||
|
|
||
|
IDriverAdd->IDriverLoad->IDriverLoad32
|
||
|
|
||
|
The 16-bit side calls the 32-bit side passing in the driver
|
||
|
alias which is used to compare against the aliases on the 32
|
||
|
bit side and the 32-bit HACMDRIVERID is passed back for the
|
||
|
relevant driver and stored in the hdrvr field of the
|
||
|
ACMDRIVERID structure.
|
||
|
|
||
|
IDriverOpen->IDriverOpen32
|
||
|
|
||
|
The parameters are passed to the 32-bit side using the hdrvr
|
||
|
field deduced from the HACMDRIVERID as the 32-bit HACMDRIVERID.
|
||
|
|
||
|
IDriverMessageId->IDriverMessageId32 :
|
||
|
|
||
|
If the driver is 32-bit (as identified in the ACMDRIVERID
|
||
|
structure) then call IDriverMessageId32. The hadid for
|
||
|
the 32-bit driver is stored in the hdrvr field of ACMDRIVERID
|
||
|
on the 16-bit side.
|
||
|
|
||
|
IDriverMessage->IDriverMessage32
|
||
|
|
||
|
If the driver is 32-bit (as identified in the ACMDRIVERID
|
||
|
structure pointed to by the ACMDRIVER structure) then call
|
||
|
IDriverMessage32. The had for the 32-bit driver is stored
|
||
|
in the hdrvr field of ACMDRIVER on the 16-bit side.
|
||
|
|
||
|
Stream headers
|
||
|
|
||
|
These must be persistent on the 32-bit side too and kept
|
||
|
in synch.
|
||
|
|
||
|
They are allocated on the 32-bit side for ACMDM_STREAM_PREPARE
|
||
|
and freed on ACMDM_STREAM_UNPREPARE. While in existence
|
||
|
the 32-bit stream header is stored in the dwDriver field in
|
||
|
|
||
|
*/
|
||
|
//==========================================================================;
|
||
|
|
||
|
#define _INC_COMPMAN
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <windowsx.h>
|
||
|
#include <mmsystem.h>
|
||
|
#include <mmddk.h>
|
||
|
#include <mmreg.h>
|
||
|
#include <memory.h>
|
||
|
#include <win32.h>
|
||
|
#include <vfw.h>
|
||
|
#include <msviddrv.h>
|
||
|
#ifdef _WIN32
|
||
|
#ifdef DAYTONA
|
||
|
#include <wownt32.h>
|
||
|
#endif
|
||
|
#include <stdlib.h> // for mbstowcs and wcstombs
|
||
|
#endif // _WIN32
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
#include "compmn16.h"
|
||
|
#endif
|
||
|
#include "compmani.h"
|
||
|
#include "thunk.h"
|
||
|
|
||
|
#include "debug.h"
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef NT_THUNK32
|
||
|
|
||
|
//==========================================================================;
|
||
|
//
|
||
|
//
|
||
|
// --- === 32 BIT SIDE === ---
|
||
|
//
|
||
|
//
|
||
|
//==========================================================================;
|
||
|
|
||
|
|
||
|
/* -------------------------------------------------------------------------
|
||
|
** Handle and memory mapping functions.
|
||
|
** -------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
LPWOWHANDLE32 lpWOWHandle32;
|
||
|
LPWOWHANDLE16 lpWOWHandle16;
|
||
|
LPGETVDMPOINTER GetVDMPointer;
|
||
|
LPWOWCALLBACK16 lpWOWCallback16;
|
||
|
int ThunksInitialized;
|
||
|
|
||
|
//
|
||
|
// These wrap around whatever mapping mechanism is used on the platform
|
||
|
// we are compiling for.
|
||
|
//
|
||
|
INLINE PVOID ptrFixMap16To32(const VOID * pv, DWORD cb);
|
||
|
INLINE VOID ptrUnFix16(const VOID * pv);
|
||
|
|
||
|
|
||
|
#ifdef CHICAGO
|
||
|
//
|
||
|
// -= Chicago implementation of memory mapping functions =-
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Thunk helper routines in Chicago kernel
|
||
|
//
|
||
|
extern PVOID WINAPI MapSL(const VOID * pv);
|
||
|
extern PVOID WINAPI MapSLFix(const VOID * pv);
|
||
|
extern VOID WINAPI UnMapSLFixArray(DWORD dwCnt, const VOID * lpSels[]);
|
||
|
|
||
|
PVOID INLINE ptrFixMap16To32(const VOID * pv, DWORD cb)
|
||
|
{
|
||
|
return MapSLFix(pv);
|
||
|
}
|
||
|
|
||
|
VOID INLINE ptrUnFix16(const VOID * pv)
|
||
|
{
|
||
|
UnMapSLFixArray(1, &pv);
|
||
|
}
|
||
|
|
||
|
|
||
|
#else // CHICAGO ELSE
|
||
|
|
||
|
//
|
||
|
// -= Daytona implementation of memory mapping functions =-
|
||
|
//
|
||
|
// Use #define to avoid having a function call
|
||
|
|
||
|
#define ptrFixMap16To32(spv, cb) \
|
||
|
GetVDMPointer( (DWORD) (DWORD_PTR) (spv), (cb), TRUE )
|
||
|
|
||
|
//PVOID ptrFixMap16To32(const VOID * pv, DWORD cb)
|
||
|
//{
|
||
|
// return GetVDMPointer( (DWORD)pv, cb, TRUE );
|
||
|
//}
|
||
|
|
||
|
//
|
||
|
// The unfix routine is a total noop.
|
||
|
// We should really call WOWGetVDMPointerUnfix...
|
||
|
//
|
||
|
|
||
|
#define ptrUnFix16(spv)
|
||
|
|
||
|
//VOID ptrUnFix16(const VOID * pv)
|
||
|
//{
|
||
|
// return;
|
||
|
//}
|
||
|
|
||
|
#endif // !CHICAGO
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
|
||
|
//
|
||
|
// 16-bit structures
|
||
|
//
|
||
|
|
||
|
typedef struct {
|
||
|
DWORD dwDCISize;
|
||
|
LPCSTR lpszDCISectionName;
|
||
|
LPCSTR lpszDCIAliasName;
|
||
|
} DRVCONFIGINFO16;
|
||
|
|
||
|
//
|
||
|
// Useful functions
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// CopyAlloc - allocate a new piece of memory, and copy the data in
|
||
|
// Must use LocalFree to release the memory later
|
||
|
//
|
||
|
PVOID CopyAlloc(PVOID pvSrc, UINT uSize)
|
||
|
{
|
||
|
PVOID pvDest;
|
||
|
|
||
|
pvDest = (PVOID)LocalAlloc(LMEM_FIXED, uSize);
|
||
|
|
||
|
if (pvDest != NULL) {
|
||
|
CopyMemory(pvDest, pvSrc, uSize);
|
||
|
}
|
||
|
|
||
|
return pvDest;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Copy data from source to dest where source is a 32bit pointer
|
||
|
* and dest is a 16bit pointer
|
||
|
*/
|
||
|
void CopyTo16Bit(LPVOID Dest16, LPVOID Src32, DWORD Length)
|
||
|
{
|
||
|
PVOID Dest32;
|
||
|
|
||
|
if (Src32 == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Dest32 = ptrFixMap16To32(Dest16, Length);
|
||
|
|
||
|
CopyMemory(Dest32, Src32, Length);
|
||
|
|
||
|
ptrUnFix16(Dest16);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Copy data from source to dest where source is a 16bit pointer
|
||
|
* and dest is a 32bit pointer
|
||
|
*/
|
||
|
void CopyTo32Bit(LPVOID Dest32, LPVOID Src16, DWORD Length)
|
||
|
{
|
||
|
PVOID Src32;
|
||
|
|
||
|
if (Src16 == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Src32 = ptrFixMap16To32(Src16, Length);
|
||
|
|
||
|
CopyMemory(Dest32, Src32, Length);
|
||
|
|
||
|
ptrUnFix16(Src16);
|
||
|
}
|
||
|
#ifdef _INC_COMPMAN
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*\
|
||
|
| |
|
||
|
| Now thunk the compman functions |
|
||
|
| |
|
||
|
| |
|
||
|
| |
|
||
|
| |
|
||
|
\*--------------------------------------------------------------------------*/
|
||
|
|
||
|
/*
|
||
|
* Convert ICDRAWBEGIN structures
|
||
|
*/
|
||
|
|
||
|
INLINE STATICFN void ConvertICDRAWBEGIN(ICDRAWBEGIN *DrawBegin32,
|
||
|
LPBITMAPINFOHEADER lpBmi,
|
||
|
DWORD dw)
|
||
|
{
|
||
|
ICDRAWBEGIN16 DrawBegin16;
|
||
|
|
||
|
CopyTo32Bit(&DrawBegin16, (LPVOID)dw, sizeof(ICDRAWBEGIN16));
|
||
|
|
||
|
DrawBegin32->dwFlags = DrawBegin16.dwFlags;
|
||
|
DrawBegin32->hpal = ThunkHPAL(DrawBegin16.hpal);
|
||
|
if (DrawBegin16.dwFlags & ICDRAW_HDC) {
|
||
|
DrawBegin32->hwnd = ThunkHWND(DrawBegin16.hwnd);
|
||
|
DrawBegin32->hdc = ThunkHDC(DrawBegin16.hdc);
|
||
|
}
|
||
|
DrawBegin32->xDst = (int)DrawBegin16.xDst;
|
||
|
DrawBegin32->yDst = (int)DrawBegin16.yDst;
|
||
|
DrawBegin32->dxDst = (int)DrawBegin16.dxDst;
|
||
|
DrawBegin32->dyDst = (int)DrawBegin16.dyDst;
|
||
|
|
||
|
CopyTo32Bit(lpBmi, DrawBegin16.lpbi, sizeof(BITMAPINFOHEADER));
|
||
|
|
||
|
DrawBegin32->lpbi = lpBmi;
|
||
|
DrawBegin32->xSrc = (int)DrawBegin16.xSrc;
|
||
|
DrawBegin32->ySrc = (int)DrawBegin16.ySrc;
|
||
|
DrawBegin32->dxSrc = (int)DrawBegin16.dxSrc;
|
||
|
DrawBegin32->dySrc = (int)DrawBegin16.dySrc;
|
||
|
DrawBegin32->dwRate = DrawBegin16.dwRate;
|
||
|
DrawBegin32->dwScale = DrawBegin16.dwScale;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Following logic copied from mvdm\wow32\wstruc.c - however since we
|
||
|
* don't have the usage parameter we're a bit stuck on the size of the
|
||
|
* entries.
|
||
|
*
|
||
|
* See also the video for windows documentation - only a limited range of
|
||
|
* bitmap types are discussed.
|
||
|
*/
|
||
|
|
||
|
INT GetBMI16Size(UNALIGNED BITMAPINFOHEADER *pbmi16)
|
||
|
{
|
||
|
int nHdrSize;
|
||
|
int nEntSize;
|
||
|
int nEntries;
|
||
|
int nBitCount;
|
||
|
DWORD dwClrUsed;
|
||
|
|
||
|
nHdrSize = (int)pbmi16->biSize;
|
||
|
|
||
|
/*
|
||
|
* We don't have some of the info we need so assume RGBQUAD
|
||
|
*/
|
||
|
|
||
|
nEntSize = sizeof(RGBQUAD);
|
||
|
|
||
|
nBitCount = pbmi16->biBitCount;
|
||
|
dwClrUsed = pbmi16->biClrUsed;
|
||
|
|
||
|
/* the following block of code should be this:
|
||
|
*
|
||
|
* if ( nBitCount > 8 ) { // true colour
|
||
|
* nEntries = 0; (ordinary case)
|
||
|
* nEntries = 3; (BI_BITFIELDS case)
|
||
|
* }
|
||
|
* else if ( dwClrUsed ) {
|
||
|
* nEntries = dwClrUsed;
|
||
|
* }
|
||
|
* else {
|
||
|
* nEntries = 1 << nBitCount;
|
||
|
* }
|
||
|
*
|
||
|
* but due to the fact that many apps don't initialize the biBitCount &
|
||
|
* biClrUsed fields (especially biClrUsed) we have to do the following
|
||
|
* sanity checking instead. v-cjones
|
||
|
*/
|
||
|
|
||
|
if ( nBitCount <= 8 ) {
|
||
|
nEntries = 1 << nBitCount;
|
||
|
// sanity check for apps (lots) that don't init the dwClrUsed field
|
||
|
if(dwClrUsed) {
|
||
|
nEntries = (int)min((DWORD)nEntries, dwClrUsed);
|
||
|
}
|
||
|
} else {
|
||
|
if (pbmi16->biCompression == BI_BITFIELDS)
|
||
|
nEntries = 3;
|
||
|
else
|
||
|
nEntries = 0;
|
||
|
}
|
||
|
|
||
|
return ( nHdrSize + (nEntries * nEntSize) );
|
||
|
}
|
||
|
|
||
|
INLINE LPBITMAPINFO CopyBitmapInfo(DWORD Bi16)
|
||
|
{
|
||
|
UNALIGNED BITMAPINFOHEADER *pbmi16;
|
||
|
LPBITMAPINFO lpbmi;
|
||
|
|
||
|
pbmi16 = ptrFixMap16To32((PVOID)Bi16, 0);
|
||
|
|
||
|
if ((int)pbmi16->biSize == 0) {
|
||
|
pbmi16->biSize = sizeof(BITMAPINFOHEADER);
|
||
|
DPF(0, "WARNING: null bitmap info size, setting it correctly");
|
||
|
}
|
||
|
|
||
|
lpbmi = (LPBITMAPINFO)CopyAlloc((LPVOID)pbmi16, GetBMI16Size(pbmi16));
|
||
|
|
||
|
ptrUnFix16((PVOID)Bi16);
|
||
|
|
||
|
return (lpbmi);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Allocate a BITMAPINFO structure to contain 256 colours
|
||
|
*/
|
||
|
INLINE LPBITMAPINFO AllocBitmapInfo()
|
||
|
{
|
||
|
return (PVOID)LocalAlloc(LMEM_FIXED, sizeof(BITMAPINFOHEADER)+
|
||
|
(sizeof(RGBQUAD)*256));
|
||
|
}
|
||
|
|
||
|
INLINE LPBITMAPINFOHEADER CopyBitmapInfoHeader(DWORD Bi16)
|
||
|
{
|
||
|
UNALIGNED BITMAPINFOHEADER *pbmi16;
|
||
|
LPBITMAPINFOHEADER lpbmi;
|
||
|
|
||
|
pbmi16 = ptrFixMap16To32((PVOID)Bi16, 0);
|
||
|
|
||
|
lpbmi = (LPBITMAPINFOHEADER)CopyAlloc((LPVOID)pbmi16, pbmi16->biSize);
|
||
|
|
||
|
ptrUnFix16((PVOID)Bi16);
|
||
|
|
||
|
return (lpbmi);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
DWORD CopyICINFOTo16bit(DWORD dw, ICINFO *IcInfoCopy, DWORD Length)
|
||
|
{
|
||
|
ICINFO16 IcInfo;
|
||
|
LONG ReturnCode;
|
||
|
|
||
|
/*
|
||
|
* Make a copy since the behaviour of wcstombs is undefined
|
||
|
* for overlapping input and output
|
||
|
*/
|
||
|
|
||
|
memcpy(&IcInfo, IcInfoCopy, FIELD_OFFSET(ICINFO, szName[0]));
|
||
|
|
||
|
/*
|
||
|
* Massage the strings
|
||
|
*/
|
||
|
|
||
|
wcstombs(IcInfo.szName,
|
||
|
IcInfoCopy->szName,
|
||
|
sizeof(IcInfo.szName));
|
||
|
// HACK : overwrite the last five characters with "[32]\0"
|
||
|
|
||
|
if ((IcInfo.szName[0]))
|
||
|
{
|
||
|
UINT n = min(sizeof(IcInfo.szName)-5, lstrlenA(IcInfo.szName));
|
||
|
IcInfo.szName[n++] = '[';
|
||
|
IcInfo.szName[n++] = '3';
|
||
|
IcInfo.szName[n++] = '2';
|
||
|
IcInfo.szName[n++] = ']';
|
||
|
IcInfo.szName[n] = '\0';
|
||
|
}
|
||
|
|
||
|
wcstombs(IcInfo.szDescription,
|
||
|
IcInfoCopy->szDescription,
|
||
|
sizeof(IcInfo.szDescription));
|
||
|
// HACK : overwrite the last five characters with "[32]\0"
|
||
|
if ((IcInfo.szDescription[0]))
|
||
|
{
|
||
|
UINT n = min(sizeof(IcInfo.szDescription)-5, lstrlenA(IcInfo.szDescription));
|
||
|
IcInfo.szDescription[n++] = '[';
|
||
|
IcInfo.szDescription[n++] = '3';
|
||
|
IcInfo.szDescription[n++] = '2';
|
||
|
IcInfo.szDescription[n++] = ']';
|
||
|
IcInfo.szDescription[n] = '\0';
|
||
|
}
|
||
|
|
||
|
wcstombs(IcInfo.szDriver,
|
||
|
IcInfoCopy->szDriver,
|
||
|
sizeof(IcInfo.szDriver));
|
||
|
|
||
|
|
||
|
IcInfo.dwSize = sizeof(IcInfo);
|
||
|
|
||
|
ReturnCode = min(Length, IcInfo.dwSize);
|
||
|
|
||
|
CopyTo16Bit((LPVOID)dw, &IcInfo, ReturnCode);
|
||
|
|
||
|
return ReturnCode;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* We need to convert the various fields in the ICDECOMPRESS/EX
|
||
|
* structure(s). Fortunately(?) the EX structure is a simple
|
||
|
* extension.
|
||
|
*/
|
||
|
typedef struct {
|
||
|
//
|
||
|
// same as ICM_DECOMPRESS
|
||
|
//
|
||
|
DWORD dwFlags;
|
||
|
|
||
|
LPBITMAPINFOHEADER lpbiSrc; // BITMAPINFO of compressed data
|
||
|
LPVOID lpSrc; // compressed data
|
||
|
|
||
|
LPBITMAPINFOHEADER lpbiDst; // DIB to decompress to
|
||
|
LPVOID lpDst; // output data
|
||
|
|
||
|
//
|
||
|
// new for ICM_DECOMPRESSEX
|
||
|
//
|
||
|
short xDst; // destination rectangle
|
||
|
short yDst;
|
||
|
short dxDst;
|
||
|
short dyDst;
|
||
|
|
||
|
short xSrc; // source rectangle
|
||
|
short ySrc;
|
||
|
short dxSrc;
|
||
|
short dySrc;
|
||
|
|
||
|
} ICDECOMPRESSEX16;
|
||
|
|
||
|
STATICFN DWORD DoICM_DecompressX(DWORD hic, UINT msg, DWORD_PTR dwP1, DWORD_PTR dwP2)
|
||
|
{
|
||
|
ICDECOMPRESSEX16 UNALIGNED *lpicdmpr16;
|
||
|
ICDECOMPRESSEX ICDecompressEx;
|
||
|
LRESULT l;
|
||
|
BOOL fQuery = TRUE;
|
||
|
|
||
|
/* Copy the standard or extended structure */
|
||
|
lpicdmpr16 = ptrFixMap16To32( (PVOID)dwP1, (DWORD) dwP2 );
|
||
|
ICDecompressEx.dwFlags = lpicdmpr16->dwFlags;
|
||
|
|
||
|
|
||
|
ICDecompressEx.lpbiSrc = (LPBITMAPINFOHEADER)CopyBitmapInfo((DWORD)(DWORD_PTR)lpicdmpr16->lpbiSrc);
|
||
|
if (NULL == ICDecompressEx.lpbiSrc) {
|
||
|
ptrUnFix16( (PVOID)dwP1 );
|
||
|
return (DWORD)ICERR_MEMORY;
|
||
|
}
|
||
|
|
||
|
ICDecompressEx.lpbiDst = (LPBITMAPINFOHEADER)CopyBitmapInfo((DWORD)(DWORD_PTR)lpicdmpr16->lpbiDst);
|
||
|
|
||
|
if ((NULL == ICDecompressEx.lpbiDst) && (msg != ICM_DECOMPRESSEX_QUERY)) {
|
||
|
LocalFree( (HLOCAL)ICDecompressEx.lpbiSrc );
|
||
|
ptrUnFix16( (PVOID)dwP1 );
|
||
|
return (DWORD)ICERR_MEMORY;
|
||
|
}
|
||
|
|
||
|
if (msg == ICM_DECOMPRESSEX || msg == ICM_DECOMPRESS) {
|
||
|
// map the source and destination pointers
|
||
|
ICDecompressEx.lpSrc = ptrFixMap16To32(lpicdmpr16->lpSrc,
|
||
|
ICDecompressEx.lpbiSrc->biSizeImage);
|
||
|
|
||
|
ICDecompressEx.lpDst = ptrFixMap16To32(lpicdmpr16->lpDst,
|
||
|
ICDecompressEx.lpbiDst->biSizeImage);
|
||
|
fQuery = FALSE; // remember
|
||
|
} else { // it is a query and we do not map the pointers
|
||
|
ICDecompressEx.lpSrc = NULL;
|
||
|
ICDecompressEx.lpDst = NULL;
|
||
|
}
|
||
|
|
||
|
if (dwP2 == sizeof(ICDECOMPRESSEX16) ) {
|
||
|
|
||
|
ICDecompressEx.xDst = (int)lpicdmpr16->xDst;
|
||
|
ICDecompressEx.yDst = (int)lpicdmpr16->yDst;
|
||
|
ICDecompressEx.dxDst = (int)lpicdmpr16->dxDst;
|
||
|
ICDecompressEx.dyDst = (int)lpicdmpr16->dyDst;
|
||
|
|
||
|
ICDecompressEx.xSrc = (int)lpicdmpr16->xSrc;
|
||
|
ICDecompressEx.ySrc = (int)lpicdmpr16->ySrc;
|
||
|
ICDecompressEx.dxSrc = (int)lpicdmpr16->dxSrc;
|
||
|
ICDecompressEx.dySrc = (int)lpicdmpr16->dySrc;
|
||
|
dwP2 = sizeof(ICDecompressEx); // Make the size relate to 32 bit
|
||
|
}
|
||
|
|
||
|
|
||
|
l = ICSendMessage( (HIC)hic, (UINT)msg, (LPARAM)&ICDecompressEx, dwP2 );
|
||
|
|
||
|
/* I don't think the following is needed // FrankYe 11/18/94
|
||
|
// If we do, don't just uncomment this. You gotta use biUnMapSL
|
||
|
if ( l == ICERR_OK) {
|
||
|
|
||
|
CopyTo16Bit( lpicdmpr16->lpbiDst, ICDecompressEx.lpbiDst,
|
||
|
sizeof(BITMAPINFOHEADER) );
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
LocalFree( (HLOCAL)ICDecompressEx.lpbiSrc );
|
||
|
if (ICDecompressEx.lpbiDst) {
|
||
|
LocalFree( (HLOCAL)ICDecompressEx.lpbiDst );
|
||
|
}
|
||
|
if (!fQuery) {
|
||
|
ptrUnFix16( lpicdmpr16->lpSrc );
|
||
|
ptrUnFix16( lpicdmpr16->lpDst );
|
||
|
}
|
||
|
ptrUnFix16( (PVOID)dwP1 );
|
||
|
|
||
|
return (DWORD) l;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Generate our thunks - refer to msvideo!compman.c for definitions of
|
||
|
* functions.
|
||
|
*
|
||
|
* NOTE - we often rely here on the fact that most of the message
|
||
|
* parameter structures are identical for 16 and 32-bit - ie they
|
||
|
* contain DWORDs and 32-bit pointers.
|
||
|
*/
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
// LONG thkStatusProc32
|
||
|
//
|
||
|
// When a client calls the 16-bit ICSetStatusProc while using a
|
||
|
// 32-bit codec, this function is set as the StatusProc in 32-bit codec.
|
||
|
// This function will then thunk down to 16-bits and call the
|
||
|
// client's StatusProc.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// LPARAM lParam : contains linear ptr to an ICSTATUSTHUNKDESC. The
|
||
|
// ICSTATUSTHUNKDESC is created during the call to ICSetStatusProc.
|
||
|
//
|
||
|
// UINT uMsg :
|
||
|
//
|
||
|
// LONG l :
|
||
|
//
|
||
|
// Return value:
|
||
|
// LONG :
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
|
||
|
LONG CALLBACK thkStatusProc32(LPARAM lParam, UINT uMsg, LONG l)
|
||
|
{
|
||
|
LPICSTATUSTHUNKDESC lpstd;
|
||
|
LONG lr;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "thkStatusProc32()");
|
||
|
|
||
|
lpstd = (LPICSTATUSTHUNKDESC)lParam;
|
||
|
ASSERT( lpstd->fnStatusProcS );
|
||
|
ASSERT( lpstd->pfnthkStatusProc16S );
|
||
|
|
||
|
|
||
|
lr = 0;
|
||
|
|
||
|
//
|
||
|
// TODO: Thunk error string for ICSTATUS_ERROR. Currently I'm not
|
||
|
// sure if ICSTATUS_ERROR is documented.
|
||
|
//
|
||
|
//#pragma message(REMIND("thkStatusProc32: thunk ICSTATUS_ERROR"))
|
||
|
if (ICSTATUS_ERROR == uMsg) {
|
||
|
//
|
||
|
// Is l supposed to be an LPSTR to an error string???
|
||
|
//
|
||
|
l = (LONG)0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
lpstd->uMsg = uMsg;
|
||
|
lpstd->l = l;
|
||
|
|
||
|
lr = lpWOWCallback16(lpstd->pfnthkStatusProc16S, (DWORD)lpstd->lpstdS);
|
||
|
|
||
|
return (lr);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
// LRESULT thkSetStatusProc
|
||
|
//
|
||
|
// This function is called as a result of thunking up from a call to
|
||
|
// the 16-bit ICSetStatusProc. It will call the 32-bit ICSetStatusProc
|
||
|
// to install thkStatusProc32.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// HIC hic : handle to 32-bit codec
|
||
|
//
|
||
|
// LPARAM lParam : contains linear ptr to an ICSTATUSTHUNKDESC. The
|
||
|
// ICSTATUSTHUNKDESC is created in the call to the 16-bit
|
||
|
// ICSetStatusProc. This will be set as the lParam to be passed
|
||
|
// to our thkStatusProc32.
|
||
|
//
|
||
|
// Return value:
|
||
|
// LRESULT :
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
|
||
|
LRESULT WINAPI thkSetStatusProc(HIC hic, LPICSTATUSTHUNKDESC lpstd)
|
||
|
{
|
||
|
DPFS(dbgThunks, 3, "thkSetStatusProc()");
|
||
|
|
||
|
return ICSetStatusProc(hic, 0L, (LPARAM)lpstd, thkStatusProc32);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
LRESULT FAR PASCAL ICInfo32(DWORD fccType, DWORD fccHandler, ICINFO16 FAR * lpicInfo)
|
||
|
{
|
||
|
ICINFO ReturnedICInfo;
|
||
|
StartThunk(ICInfo);
|
||
|
|
||
|
//DPF2(("Calling ICInfo %4.4hs %4.4hs %8X", &fccType, &fccHandler, lpicInfo));
|
||
|
|
||
|
ReturnedICInfo.fccHandler = 0; // Initialise...
|
||
|
ReturnCode = ICInfo(fccType, fccHandler, &ReturnedICInfo);
|
||
|
|
||
|
CopyICINFOTo16bit((DWORD)(DWORD_PTR)lpicInfo, &ReturnedICInfo, sizeof(ReturnedICInfo));
|
||
|
EndThunk()
|
||
|
}
|
||
|
|
||
|
LRESULT FAR PASCAL ICInfoInternal32(DWORD fccType, DWORD fccHandler, ICINFO16 FAR * lpicInfo, ICINFOI FAR * lpicInfoI)
|
||
|
{
|
||
|
return ICInfo32(fccType, fccHandler, lpicInfo);
|
||
|
#if 0
|
||
|
ICINFO ReturnedICInfo;
|
||
|
ICINFOI ReturnedICInfoI;
|
||
|
|
||
|
StartThunk(ICInfo);
|
||
|
|
||
|
// DPF(1, "Calling ICInfo %4.4hs %4.4hs %8X", &fccType, &fccHandler, lpicInfo);
|
||
|
|
||
|
ReturnedICInfo.fccHandler = 0; // Initialise...
|
||
|
ReturnCode = ICInfoInternal(fccType, fccHandler, &ReturnedICInfo, &ReturnedICInfoI);
|
||
|
|
||
|
if (NULL != lpicInfoI) {
|
||
|
//
|
||
|
// Assuming no members of ICINFOI need special thunking
|
||
|
//
|
||
|
CopyTo16Bit(lpicInfoI, &ReturnedICInfoI, sizeof(*lpicInfoI));
|
||
|
}
|
||
|
|
||
|
CopyICINFOTo16bit((DWORD)(DWORD_PTR)lpicInfo, &ReturnedICInfo, sizeof(ReturnedICInfo));
|
||
|
|
||
|
EndThunk()
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
LRESULT FAR PASCAL ICSendMessage32(DWORD hic, UINT msg, DWORD_PTR dwP1, DWORD_PTR dwP2)
|
||
|
{
|
||
|
StartThunk(ICSendMessage);
|
||
|
DPF(2,"Calling ICSendMessage %4X %4X %8X %8X",
|
||
|
hic, msg, dwP1, dwP2);
|
||
|
|
||
|
switch (msg) {
|
||
|
case ICM_GETSTATE:
|
||
|
case ICM_SETSTATE:
|
||
|
|
||
|
if (dwP1 == 0) {
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
dwP1,
|
||
|
dwP2);
|
||
|
} else {
|
||
|
PVOID pState;
|
||
|
/*
|
||
|
* Create some aligned memory to return or pass on the data
|
||
|
*/
|
||
|
pState = (PVOID)LocalAlloc(LPTR, dwP2);
|
||
|
|
||
|
if (pState == NULL) {
|
||
|
ReturnCode = 0;
|
||
|
} else {
|
||
|
|
||
|
if ((UINT)msg == ICM_SETSTATE) {
|
||
|
// Copy the data from 16 bit land
|
||
|
CopyTo32Bit(pState, (LPVOID)dwP1, (DWORD) dwP2);
|
||
|
}
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic, (UINT)msg,
|
||
|
(DWORD_PTR)pState, dwP2);
|
||
|
|
||
|
/*
|
||
|
* Copy back the state, if the driver returned any data
|
||
|
*/
|
||
|
|
||
|
if (ReturnCode > 0 && (UINT)msg == ICM_GETSTATE) {
|
||
|
CopyTo16Bit((LPVOID)dwP1, pState,
|
||
|
min((DWORD)ReturnCode, (DWORD) dwP2));
|
||
|
}
|
||
|
|
||
|
LocalFree((HLOCAL)pState);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_GETINFO:
|
||
|
{
|
||
|
ICINFO IcInfo;
|
||
|
|
||
|
ReturnCode = ICGetInfo((HIC)(DWORD)hic, &IcInfo, sizeof(IcInfo));
|
||
|
|
||
|
if (ReturnCode != 0) {
|
||
|
ReturnCode = CopyICINFOTo16bit((DWORD) (DWORD_PTR) dwP1, &IcInfo, (DWORD) ReturnCode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
break;
|
||
|
|
||
|
case ICM_CONFIGURE:
|
||
|
case ICM_ABOUT:
|
||
|
|
||
|
/*
|
||
|
* dwP1 = -1 is a special value asking if config is supported,
|
||
|
* otherwise it's a window handle
|
||
|
*/
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
dwP1 == (DWORD_PTR)-1 ?
|
||
|
(DWORD_PTR)-1 :
|
||
|
(DWORD_PTR)ThunkHWND(LOWORD(dwP1)),
|
||
|
dwP2);
|
||
|
|
||
|
|
||
|
break;
|
||
|
|
||
|
case ICM_COMPRESS:
|
||
|
{
|
||
|
if (dwP2 != sizeof(ICCOMPRESS)) { // validation code
|
||
|
ReturnCode = ICERR_BADSIZE;
|
||
|
} else {
|
||
|
|
||
|
DWORD dwFlags;
|
||
|
LPDWORD lpdwFlags16, lpckid16;
|
||
|
LPBITMAPINFOHEADER lpbih16;
|
||
|
|
||
|
LPVOID lpInput, lpOutput, lpPrev;
|
||
|
|
||
|
DWORD ckid;
|
||
|
|
||
|
ICCOMPRESS IcCompress;
|
||
|
|
||
|
ReturnCode = ICERR_OK;
|
||
|
|
||
|
/*
|
||
|
* We need to convert the various fields in the ICCOMPRESS
|
||
|
* structure
|
||
|
*/
|
||
|
|
||
|
CopyTo32Bit( &IcCompress, (LPVOID)dwP1, (DWORD) dwP2 );
|
||
|
|
||
|
IcCompress.lpbiInput = (LPBITMAPINFOHEADER)CopyBitmapInfo((DWORD)(DWORD_PTR)IcCompress.lpbiInput);
|
||
|
if (NULL == IcCompress.lpbiInput) {
|
||
|
ReturnCode = ICERR_MEMORY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
lpbih16 = IcCompress.lpbiOutput;
|
||
|
IcCompress.lpbiOutput = (LPBITMAPINFOHEADER)CopyBitmapInfo((DWORD)(DWORD_PTR)IcCompress.lpbiOutput);
|
||
|
if (NULL == IcCompress.lpbiOutput) {
|
||
|
LocalFree((HLOCAL)IcCompress.lpbiInput);
|
||
|
ReturnCode = ICERR_MEMORY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
lpInput = IcCompress.lpInput;
|
||
|
IcCompress.lpInput = ptrFixMap16To32(IcCompress.lpInput, IcCompress.lpbiInput->biSizeImage);
|
||
|
|
||
|
lpOutput = IcCompress.lpOutput;
|
||
|
IcCompress.lpOutput = ptrFixMap16To32(IcCompress.lpOutput, IcCompress.lpbiOutput->biSizeImage);
|
||
|
|
||
|
lpPrev = NULL;
|
||
|
if (IcCompress.lpbiPrev) {
|
||
|
|
||
|
IcCompress.lpbiPrev = (LPBITMAPINFOHEADER)CopyBitmapInfo((DWORD)(DWORD_PTR)IcCompress.lpbiPrev);
|
||
|
if (NULL == IcCompress.lpbiPrev) {
|
||
|
LocalFree((HLOCAL)IcCompress.lpbiOutput);
|
||
|
LocalFree((HLOCAL)IcCompress.lpbiInput);
|
||
|
ptrUnFix16(lpOutput);
|
||
|
ptrUnFix16(lpInput);
|
||
|
ReturnCode = ICERR_MEMORY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
lpPrev = IcCompress.lpPrev;
|
||
|
IcCompress.lpPrev = ptrFixMap16To32(IcCompress.lpPrev, IcCompress.lpbiPrev->biSizeImage);
|
||
|
}
|
||
|
|
||
|
lpdwFlags16 = IcCompress.lpdwFlags;
|
||
|
if (lpdwFlags16 != NULL) {
|
||
|
CopyTo32Bit(&dwFlags, lpdwFlags16, sizeof(DWORD));
|
||
|
IcCompress.lpdwFlags = &dwFlags;
|
||
|
}
|
||
|
|
||
|
if (IcCompress.lpckid != NULL) {
|
||
|
lpckid16 = IcCompress.lpckid;
|
||
|
IcCompress.lpckid = &ckid;
|
||
|
}
|
||
|
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic, (UINT)msg,
|
||
|
(DWORD_PTR)&IcCompress, dwP2);
|
||
|
|
||
|
if (ReturnCode == ICERR_OK) {
|
||
|
|
||
|
CopyTo16Bit( lpbih16, IcCompress.lpbiOutput,
|
||
|
sizeof(BITMAPINFOHEADER) );
|
||
|
|
||
|
if (lpdwFlags16 != NULL) {
|
||
|
CopyTo16Bit(lpdwFlags16, &dwFlags, sizeof(DWORD));
|
||
|
}
|
||
|
|
||
|
if (IcCompress.lpckid != NULL) {
|
||
|
CopyTo16Bit(lpckid16, &ckid, sizeof(DWORD));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Free the bitmap info storage regardless of the return code
|
||
|
*/
|
||
|
|
||
|
if (NULL != IcCompress.lpbiPrev) {
|
||
|
LocalFree((HLOCAL)IcCompress.lpbiPrev);
|
||
|
}
|
||
|
|
||
|
LocalFree((HLOCAL)IcCompress.lpbiOutput);
|
||
|
LocalFree((HLOCAL)IcCompress.lpbiInput);
|
||
|
|
||
|
if (NULL != lpPrev)
|
||
|
{
|
||
|
ptrUnFix16(lpPrev);
|
||
|
}
|
||
|
ptrUnFix16(lpOutput);
|
||
|
ptrUnFix16(lpInput);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
|
||
|
case ICM_COMPRESS_GET_SIZE:
|
||
|
case ICM_COMPRESS_BEGIN:
|
||
|
case ICM_COMPRESS_QUERY:
|
||
|
|
||
|
case ICM_DECOMPRESS_BEGIN:
|
||
|
case ICM_DECOMPRESS_GET_PALETTE:
|
||
|
case ICM_DECOMPRESS_SET_PALETTE: // only takes one BitmapInfoHeader
|
||
|
case ICM_DECOMPRESS_QUERY:
|
||
|
|
||
|
{
|
||
|
LPBITMAPINFO bmi1, bmi2;
|
||
|
|
||
|
bmi1 = bmi2 = NULL;
|
||
|
if (dwP1 != 0) {
|
||
|
bmi1 = CopyBitmapInfo((DWORD) (DWORD_PTR) dwP1);
|
||
|
}
|
||
|
if (dwP2 != 0) {
|
||
|
bmi2 = CopyBitmapInfo((DWORD) (DWORD_PTR) dwP2);
|
||
|
}
|
||
|
|
||
|
if ( (NULL == bmi1 && 0 != dwP1) || (NULL == bmi2 && 0 != dwP2) )
|
||
|
{
|
||
|
if (NULL != bmi1) LocalFree((HLOCAL)bmi1);
|
||
|
if (NULL != bmi2) LocalFree((HLOCAL)bmi2);
|
||
|
ReturnCode = (UINT)msg == ICM_COMPRESS_GET_SIZE ? 0 : ICERR_MEMORY;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)bmi1,
|
||
|
(DWORD_PTR)bmi2);
|
||
|
|
||
|
if (bmi2 != NULL) {
|
||
|
|
||
|
// We might have to return data to the 16 bit side.
|
||
|
// The messages for which we have to do this are:
|
||
|
// ICM_DECOMPRESS_QUERY (iff retcode == ICERR_OK)
|
||
|
// ICM_DECOMPRESS_GET_PALETTE (iff retcode >= 0)
|
||
|
|
||
|
if (((ReturnCode == ICERR_OK) && (msg == ICM_DECOMPRESS_QUERY))
|
||
|
|| ((ReturnCode >= 0) && (msg == ICM_DECOMPRESS_GET_PALETTE)))
|
||
|
{
|
||
|
CopyTo16Bit((LPVOID)dwP2, bmi2, GetBMI16Size((LPBITMAPINFOHEADER)bmi2));
|
||
|
}
|
||
|
LocalFree((HLOCAL)bmi2);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if (bmi1 != NULL) {
|
||
|
LocalFree((HLOCAL)bmi1);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_COMPRESS_END:
|
||
|
case ICM_DECOMPRESS_END:
|
||
|
case ICM_DECOMPRESSEX_END:
|
||
|
case ICM_DRAW_END:
|
||
|
case ICM_DRAW_FLUSH:
|
||
|
case ICM_DRAW_START: //??
|
||
|
case ICM_DRAW_STOP: //??
|
||
|
case ICM_DRAW_SETTIME:
|
||
|
case ICM_DRAW_RENDERBUFFER:
|
||
|
case ICM_SETQUALITY:
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
dwP1,
|
||
|
dwP2);
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_GETTIME:
|
||
|
case ICM_GETBUFFERSWANTED:
|
||
|
case ICM_GETDEFAULTQUALITY:
|
||
|
case ICM_GETDEFAULTKEYFRAMERATE:
|
||
|
case ICM_GETQUALITY:
|
||
|
{
|
||
|
DWORD dwReturn;
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)&dwReturn,
|
||
|
dwP2);
|
||
|
|
||
|
// Note: although the definition of these messages state
|
||
|
// that dwParam2 is not used, trouble will brew if the
|
||
|
// decompressor ever tries to use dwParam2. We cannot
|
||
|
// thunk non-standard uses of this parameter.
|
||
|
|
||
|
if (ReturnCode == ICERR_OK) {
|
||
|
CopyTo16Bit((LPVOID)dwP1, &dwReturn, sizeof(DWORD));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_COMPRESS_GET_FORMAT:
|
||
|
case ICM_DECOMPRESS_GET_FORMAT:
|
||
|
|
||
|
/*
|
||
|
* This is a tricky one - we first have to find the size of
|
||
|
* the output format so we can get a copy of the (aligned)
|
||
|
* version before passing it back to the app
|
||
|
*/
|
||
|
|
||
|
{
|
||
|
LPBITMAPINFO bmi1, bmi2;
|
||
|
|
||
|
if ( dwP1 == 0L ) {
|
||
|
ReturnCode = ICERR_OK;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
bmi1 = CopyBitmapInfo((DWORD) (DWORD_PTR) dwP1);
|
||
|
|
||
|
if (bmi1 == NULL) {
|
||
|
ReturnCode = ICERR_MEMORY;
|
||
|
} else {
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)bmi1,
|
||
|
0);
|
||
|
|
||
|
if (ReturnCode > 0 && dwP2 != 0) {
|
||
|
bmi2 = LocalAlloc(LMEM_FIXED, ReturnCode);
|
||
|
|
||
|
if (bmi2 == NULL) {
|
||
|
/*
|
||
|
* Can't do anything!!! - there's not good return code
|
||
|
*/
|
||
|
|
||
|
ReturnCode = ICERR_MEMORY;
|
||
|
} else {
|
||
|
DWORD Length;
|
||
|
|
||
|
Length = (DWORD) ReturnCode; /* preserve length */
|
||
|
|
||
|
ReturnCode =
|
||
|
ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)bmi1,
|
||
|
(DWORD_PTR)bmi2);
|
||
|
|
||
|
if (ReturnCode >= 0) {
|
||
|
CopyTo16Bit((LPVOID)dwP2, bmi2, Length);
|
||
|
}
|
||
|
|
||
|
LocalFree((HLOCAL)bmi2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LocalFree((HLOCAL)bmi1);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DECOMPRESS:
|
||
|
if (dwP2 != sizeof(ICDECOMPRESS)) {
|
||
|
ReturnCode = ICERR_BADSIZE;
|
||
|
} else {
|
||
|
ReturnCode = DoICM_DecompressX(hic, msg, dwP1, dwP2);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DECOMPRESSEX:
|
||
|
case ICM_DECOMPRESSEX_BEGIN:
|
||
|
case ICM_DECOMPRESSEX_QUERY:
|
||
|
if (dwP2 != sizeof(ICDECOMPRESSEX16)) {
|
||
|
ReturnCode = ICERR_BADSIZE;
|
||
|
} else {
|
||
|
ReturnCode = DoICM_DecompressX(hic, msg, dwP1, dwP2);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW:
|
||
|
|
||
|
/*
|
||
|
* We can't support unknown extensions
|
||
|
*/
|
||
|
|
||
|
if (dwP2 != sizeof(ICDRAW)) {
|
||
|
ReturnCode = ICERR_BADSIZE;
|
||
|
} else {
|
||
|
ICDRAW ICDraw;
|
||
|
BITMAPINFOHEADER bmi;
|
||
|
LPVOID lpData;
|
||
|
|
||
|
CopyTo32Bit(&ICDraw, (LPVOID)dwP1, (DWORD) dwP2);
|
||
|
|
||
|
/*
|
||
|
* We have to assume this is a draw for video
|
||
|
*/
|
||
|
|
||
|
CopyTo32Bit(&bmi, ICDraw.lpFormat, sizeof(BITMAPINFOHEADER));
|
||
|
|
||
|
ICDraw.lpFormat = (LPVOID)&bmi;
|
||
|
|
||
|
lpData = ICDraw.lpData;
|
||
|
ICDraw.lpData = ptrFixMap16To32(ICDraw.lpData, ICDraw.cbData);
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)&ICDraw,
|
||
|
dwP2);
|
||
|
ptrUnFix16(lpData);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_BEGIN:
|
||
|
{
|
||
|
ICDRAWBEGIN InputFormat;
|
||
|
BITMAPINFOHEADER bmihInput;
|
||
|
|
||
|
ConvertICDRAWBEGIN(&InputFormat, &bmihInput, (DWORD) (DWORD_PTR) dwP1);
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)&InputFormat,
|
||
|
dwP2);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_CHANGEPALETTE:
|
||
|
case ICM_DRAW_QUERY:
|
||
|
{
|
||
|
LPBITMAPINFO lpbi;
|
||
|
|
||
|
lpbi = CopyBitmapInfo((DWORD) (DWORD_PTR) dwP1);
|
||
|
|
||
|
if (lpbi == NULL) {
|
||
|
ReturnCode = ICERR_MEMORY;
|
||
|
} else {
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD_PTR)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)lpbi,
|
||
|
dwP2);
|
||
|
|
||
|
LocalFree((HLOCAL)lpbi);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_REALIZE:
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)ThunkHDC(LOWORD(dwP1)),
|
||
|
dwP2);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_WINDOW:
|
||
|
{
|
||
|
RECT_SHORT SRect;
|
||
|
RECT Rect;
|
||
|
|
||
|
CopyTo32Bit(&SRect, (LPVOID)dwP1, sizeof(SRect));
|
||
|
|
||
|
SHORT_RECT_TO_RECT(Rect, SRect);
|
||
|
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD_PTR)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)&Rect,
|
||
|
dwP2);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
// The next three messages are INTERNAL ones
|
||
|
case ICM_GETERRORTEXT:
|
||
|
break;
|
||
|
|
||
|
case ICM_GETFORMATNAME:
|
||
|
break;
|
||
|
|
||
|
case ICM_ENUMFORMATS:
|
||
|
break;
|
||
|
|
||
|
case ICM_COMPRESS_FRAMES_INFO:
|
||
|
{
|
||
|
ICCOMPRESSFRAMES icf32;
|
||
|
|
||
|
// We might explode if we get too small a length and start treating
|
||
|
// some of the elements as pointers anyway. Just fail the call.
|
||
|
// (WIN95C bug 8615).
|
||
|
// dwP2 is the length of the 16 bit structure and we only know
|
||
|
// the size of the 32 bit structure, but thankfully they're the
|
||
|
// same.
|
||
|
if (dwP2 < sizeof(ICCOMPRESSFRAMES)) {
|
||
|
ReturnCode = ICERR_BADPARAM;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
CopyTo32Bit(&icf32, (LPBYTE)dwP1, (DWORD) dwP2);
|
||
|
|
||
|
// Now fix up the 32 bit structure
|
||
|
icf32.PutData = icf32.GetData = NULL; // For safety. should not be used for this message
|
||
|
|
||
|
if (icf32.lpbiOutput) {
|
||
|
icf32.lpbiOutput = CopyBitmapInfoHeader((DWORD)(DWORD_PTR)icf32.lpbiOutput);
|
||
|
}
|
||
|
if (icf32.lpbiInput) {
|
||
|
icf32.lpbiInput = CopyBitmapInfoHeader((DWORD)(DWORD_PTR)icf32.lpbiInput);
|
||
|
}
|
||
|
|
||
|
// According to the documentation, lInput and lOutput are undefined. Treating
|
||
|
// them as pointers is as scary as a really scary thing.
|
||
|
#if 0
|
||
|
lInput = icf32.lInput;
|
||
|
icf32.lInput = (LPARAM)ptrFixMap16To32((LPVOID)icf32.lInput, icf32.lpbiInput->biSizeImage);
|
||
|
|
||
|
lOutput = icf32.lOutput;
|
||
|
icf32.lOutput = (LPARAM)ptrFixMap16To32((LPVOID)icf32.lOutput, icf32.lpbiOutput->biSizeImage);
|
||
|
#endif
|
||
|
// After the fixups have been done, call the actual routine
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD_PTR)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)&icf32,
|
||
|
dwP2);
|
||
|
|
||
|
#if 0
|
||
|
ptrUnFix16((LPVOID)lOutput);
|
||
|
ptrUnFix16((LPVOID)lInput);
|
||
|
#endif
|
||
|
|
||
|
if (icf32.lpbiOutput) {
|
||
|
LocalFree(icf32.lpbiOutput);
|
||
|
}
|
||
|
if (icf32.lpbiInput) {
|
||
|
LocalFree(icf32.lpbiInput);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_GET_PALETTE:
|
||
|
{
|
||
|
ReturnCode = ICSendMessage((HIC) hic,
|
||
|
(UINT)msg,
|
||
|
dwP1,
|
||
|
dwP2);
|
||
|
if ((ReturnCode != 0L) && (ReturnCode != ICERR_UNSUPPORTED)) {
|
||
|
#ifdef CHICAGO
|
||
|
ReturnCode = (LRESULT)(WORD)ReturnCode;
|
||
|
#else
|
||
|
|
||
|
FARPROC lpWOWHandle16;
|
||
|
HMODULE hmodWow;
|
||
|
|
||
|
if ( (hmodWow = GetModuleHandle( GET_MAPPING_MODULE_NAME ))
|
||
|
&& (lpWOWHandle16 = GetProcAddress(hmodWow, "WOWHandle16"))) {
|
||
|
ReturnCode = (WORD)(lpWOWHandle16((HANDLE)ReturnCode, (WOW_HANDLE_TYPE)WOW_TYPE_HPALETTE));
|
||
|
} else {
|
||
|
ReturnCode = ICERR_ERROR;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_DRAW_SUGGESTFORMAT:
|
||
|
{
|
||
|
ICDRAWSUGGEST icdrwsug;
|
||
|
LPBITMAPINFOHEADER lpbiSuggest16;
|
||
|
LPBITMAPINFOHEADER lpbiSuggest;
|
||
|
|
||
|
DPF(4, "!ICMSendMessage32: ICM_DRAW_SUGGESTFORMAT: dwP1=%08lXh, dwP2=%08lXh", dwP1, dwP2);
|
||
|
|
||
|
//
|
||
|
CopyTo32Bit(&icdrwsug, (LPBYTE)dwP1, (DWORD) dwP2);
|
||
|
|
||
|
lpbiSuggest = NULL;
|
||
|
lpbiSuggest16 = icdrwsug.lpbiSuggest;
|
||
|
if (lpbiSuggest16) {
|
||
|
lpbiSuggest = ptrFixMap16To32(lpbiSuggest16, 0);
|
||
|
}
|
||
|
|
||
|
// Now fix up the 32 bit structure
|
||
|
|
||
|
if (icdrwsug.lpbiIn) {
|
||
|
icdrwsug.lpbiIn = CopyBitmapInfoHeader((DWORD)(DWORD_PTR)icdrwsug.lpbiIn);
|
||
|
}
|
||
|
|
||
|
if (icdrwsug.lpbiSuggest) {
|
||
|
icdrwsug.lpbiSuggest = CopyBitmapInfoHeader((DWORD)(DWORD_PTR)icdrwsug.lpbiSuggest);
|
||
|
}
|
||
|
|
||
|
// After the fixups have been done, call the actual routine
|
||
|
ReturnCode = ICSendMessage((HIC)(DWORD)hic,
|
||
|
(UINT)msg,
|
||
|
(DWORD_PTR)&icdrwsug,
|
||
|
dwP2);
|
||
|
if (icdrwsug.lpbiIn) {
|
||
|
LocalFree(icdrwsug.lpbiIn);
|
||
|
}
|
||
|
|
||
|
// We must return the 32 bit suggested format to 16 bit land
|
||
|
if (icdrwsug.lpbiSuggest) {
|
||
|
if (ReturnCode == ICERR_OK) {
|
||
|
CopyMemory( lpbiSuggest, icdrwsug.lpbiSuggest,
|
||
|
lpbiSuggest->biSize);
|
||
|
}
|
||
|
LocalFree(icdrwsug.lpbiSuggest);
|
||
|
ptrUnFix16(lpbiSuggest16);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ICM_SET_STATUS_PROC:
|
||
|
// We do not need to support this under NT. It is much
|
||
|
// easier not to add the callback support... even if we could
|
||
|
// guarantee to be on the right thread to actually do the callback.
|
||
|
|
||
|
//
|
||
|
// This message has its own thunk!
|
||
|
//
|
||
|
ASSERT( FALSE );
|
||
|
|
||
|
|
||
|
default:
|
||
|
ReturnCode = ICERR_UNSUPPORTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
EndThunk()
|
||
|
}
|
||
|
|
||
|
INLINE LRESULT FAR PASCAL ICOpen32(DWORD fccType, DWORD fccHandler, UINT wMode)
|
||
|
{
|
||
|
StartThunk(ICOpen);
|
||
|
|
||
|
DPF(1, "Calling ICOpen %4.4hs %4.4hs %4X", &fccType, &fccHandler, wMode);
|
||
|
ReturnCode = (LONG_PTR)ICOpen(fccType, fccHandler, (UINT)wMode);
|
||
|
EndThunk();
|
||
|
}
|
||
|
|
||
|
INLINE LRESULT FAR PASCAL ICClose32(DWORD hic)
|
||
|
{
|
||
|
StartThunk(ICClose);
|
||
|
ReturnCode = ICClose((HIC)hic);
|
||
|
EndThunk();
|
||
|
}
|
||
|
|
||
|
#endif // _INC_COMPMAN
|
||
|
|
||
|
|
||
|
DWORD ICMThunk32(DWORD dwThunkId,DWORD dw1,DWORD dw2,DWORD dw3,DWORD dw4)
|
||
|
{
|
||
|
//
|
||
|
// Make sure we've got thunking functionality
|
||
|
//
|
||
|
|
||
|
#if 0
|
||
|
{
|
||
|
char szBuffer[80];
|
||
|
char szMsg[32];
|
||
|
|
||
|
|
||
|
switch (dwThunkId) {
|
||
|
|
||
|
case compThunkICSendMessage32:
|
||
|
lstrcpyA( szMsg, "ICSendMessage32" );
|
||
|
break;
|
||
|
|
||
|
case compThunkICInfoInternal32:
|
||
|
lstrcpyA( szMsg, "ICInfoInternal32" );
|
||
|
break;
|
||
|
|
||
|
case compThunkICOpen32:
|
||
|
lstrcpyA( szMsg, "ICOpen32" );
|
||
|
break;
|
||
|
|
||
|
case compThunkICClose32:
|
||
|
lstrcpyA( szMsg, "ICClose32" );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
lstrcpyA( szMsg, "Unknown" );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
wsprintfA( szBuffer, "%18.18s 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
|
||
|
szMsg, dw1, dw2, dw3, dw4);
|
||
|
|
||
|
OutputDebugStringA( szBuffer );
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (ThunksInitialized <= 0) {
|
||
|
|
||
|
HMODULE hMod;
|
||
|
|
||
|
if (ThunksInitialized == -1) {
|
||
|
return (DWORD)ICERR_ERROR;
|
||
|
}
|
||
|
|
||
|
hMod = GetModuleHandle(GET_MAPPING_MODULE_NAME);
|
||
|
if (hMod != NULL) {
|
||
|
|
||
|
GetVDMPointer =
|
||
|
(LPGETVDMPOINTER)GetProcAddress(hMod, GET_VDM_POINTER_NAME);
|
||
|
lpWOWHandle32 =
|
||
|
(LPWOWHANDLE32)GetProcAddress(hMod, GET_HANDLE_MAPPER32 );
|
||
|
lpWOWHandle16 =
|
||
|
(LPWOWHANDLE16)GetProcAddress(hMod, GET_HANDLE_MAPPER16 );
|
||
|
lpWOWCallback16 =
|
||
|
(LPWOWCALLBACK16)GetProcAddress(hMod, GET_CALLBACK16);
|
||
|
}
|
||
|
|
||
|
if ( GetVDMPointer == NULL ||
|
||
|
lpWOWHandle16 == NULL ||
|
||
|
lpWOWHandle32 == NULL ||
|
||
|
lpWOWCallback16 == NULL ) {
|
||
|
|
||
|
ThunksInitialized = -1;
|
||
|
return (DWORD)ICERR_ERROR;
|
||
|
|
||
|
} else {
|
||
|
ThunksInitialized = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Perform the requested function
|
||
|
//
|
||
|
|
||
|
switch (dwThunkId) {
|
||
|
|
||
|
case compThunkICSendMessage32:
|
||
|
return (DWORD) ICSendMessage32(dw1, (UINT)dw2, dw3, dw4);
|
||
|
break;
|
||
|
|
||
|
case compThunkICInfoInternal32:
|
||
|
return (DWORD) ICInfoInternal32(dw1, dw2, (ICINFOA FAR * )dw3, (ICINFOI FAR *)dw4);
|
||
|
break;
|
||
|
|
||
|
case compThunkICOpen32:
|
||
|
return (DWORD) ICOpen32(dw1, dw2, (UINT)dw3);
|
||
|
break;
|
||
|
|
||
|
case compThunkICClose32:
|
||
|
return (DWORD) ICClose32(dw1);
|
||
|
break;
|
||
|
|
||
|
case compThunkICOpenFunction32:
|
||
|
{
|
||
|
DWORD fccType;
|
||
|
DWORD fccHandler;
|
||
|
UINT uMode;
|
||
|
FARPROC lpfnHandler;
|
||
|
|
||
|
fccType = dw1;
|
||
|
fccHandler = dw2;
|
||
|
uMode = (UINT)dw3;
|
||
|
lpfnHandler = (FARPROC)dw4;
|
||
|
|
||
|
// !!! this won't work
|
||
|
return (DWORD) (DWORD_PTR) ICOpenFunction( fccType, fccHandler, uMode, lpfnHandler );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case compThunkICSetStatusProc32:
|
||
|
{
|
||
|
DWORD lpstdS;
|
||
|
DWORD cbStruct;
|
||
|
HIC hic;
|
||
|
LPICSTATUSTHUNKDESC lpstd;
|
||
|
LRESULT lr;
|
||
|
|
||
|
hic = (HIC)dw1;
|
||
|
lpstdS = dw2;
|
||
|
cbStruct = dw3;
|
||
|
|
||
|
lpstd = ptrFixMap16To32((LPVOID)lpstdS, sizeof(*lpstd));
|
||
|
|
||
|
lr = thkSetStatusProc(hic, lpstd);
|
||
|
|
||
|
ptrUnFix16((LPVOID)lpstdS);
|
||
|
|
||
|
return (DWORD)lr;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // NT_THUNK32
|
||
|
|
||
|
#ifdef NT_THUNK16
|
||
|
|
||
|
//==========================================================================;
|
||
|
//
|
||
|
//
|
||
|
// --- === 16 BIT SIDE === ---
|
||
|
//
|
||
|
//
|
||
|
//==========================================================================;
|
||
|
|
||
|
//
|
||
|
// --== Global garbage ==--
|
||
|
//
|
||
|
DWORD (FAR PASCAL *lpfnCallproc32W)(DWORD, DWORD, DWORD,
|
||
|
DWORD, DWORD,
|
||
|
LPVOID, DWORD, DWORD);
|
||
|
DWORD (FAR PASCAL *lpfnFreeLibrary32W)(DWORD);
|
||
|
TCHAR gszKernel[] = TEXT("KERNEL");
|
||
|
|
||
|
TCHAR gszLoadLibraryEx32W[] = TEXT("LoadLibraryEx32W");
|
||
|
TCHAR gszFreeLibrary32W[] = TEXT("FreeLibrary32W");
|
||
|
TCHAR gszGetProcAddress32W[] = TEXT("GetProcAddress32W");
|
||
|
TCHAR gszCallproc32W[] = TEXT("CallProc32W");
|
||
|
|
||
|
TCHAR gszThunkEntry[] = TEXT("ICMThunk32");
|
||
|
TCHAR gszMsvfw32[] = TEXT("msvfw32.dll");
|
||
|
|
||
|
//
|
||
|
// --== ==--
|
||
|
//
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
// PICMGARB thunkInitialize
|
||
|
//
|
||
|
// Description:
|
||
|
// Thunk initialization under NT WOW or Chicago 16-bit.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Return (PICMGARB):
|
||
|
// NULL if thunks are not functional. Otherwise, a pointer to the
|
||
|
// ICMGARB structure for the current process is returned.
|
||
|
//
|
||
|
// History:
|
||
|
// 07/07/94 frankye
|
||
|
//
|
||
|
// Notes:
|
||
|
// The lack of a pig for the current process implies that a thunk
|
||
|
// is being called in the context of a process in which we were never
|
||
|
// loaded. If this happens, we allocate a new pig for this process
|
||
|
// and continue the thunk initialization. Since we were never
|
||
|
// loaded in the process, we *probably* will never be freed. We
|
||
|
// cannot reliably determine when we can thunkTerminate in the process.
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
PICMGARB WINAPI thunkInitialize(VOID)
|
||
|
{
|
||
|
HMODULE hmodKernel;
|
||
|
DWORD (FAR PASCAL *lpfnLoadLibraryEx32W)(LPCSTR, DWORD, DWORD);
|
||
|
LPVOID (FAR PASCAL *lpfnGetProcAddress32W)(DWORD, LPCSTR);
|
||
|
|
||
|
PICMGARB pig;
|
||
|
|
||
|
|
||
|
if (NULL == (pig = pigFind()))
|
||
|
{
|
||
|
DPF(0, "thunkInitialize: WARNING: ICM called from process %08lXh in which it was never loaded.", GetCurrentProcessId());
|
||
|
DebugErr(DBF_WARNING, "thunkInitialize: WARNING: ICM called from process in which it was never loaded.");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If we've already tried and failed...
|
||
|
//
|
||
|
if (pig->fThunkError)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If we already successfully initialized thunks...
|
||
|
//
|
||
|
if (pig->fThunksInitialized)
|
||
|
{
|
||
|
return pig;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Try to initialize our connection the the 32-bit side...
|
||
|
//
|
||
|
DPFS(dbgInit, 1, "thunkInitialize()");
|
||
|
|
||
|
//
|
||
|
// For now, we'll assume we hit an error...
|
||
|
//
|
||
|
pig->fThunkError = TRUE;
|
||
|
|
||
|
//
|
||
|
// See if we can find the thunking routine entry points in KERNEL
|
||
|
//
|
||
|
hmodKernel = GetModuleHandle(gszKernel);
|
||
|
|
||
|
if (hmodKernel == NULL)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't GetModuleHandle(kernel)");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
*(FARPROC *)&lpfnLoadLibraryEx32W =
|
||
|
GetProcAddress(hmodKernel, gszLoadLibraryEx32W);
|
||
|
|
||
|
if (lpfnLoadLibraryEx32W == NULL)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't GetProcAddress(kernel, LoadLibraryEx32W)");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
*(FARPROC *)&lpfnFreeLibrary32W =
|
||
|
GetProcAddress(hmodKernel, gszFreeLibrary32W);
|
||
|
|
||
|
if (lpfnFreeLibrary32W == NULL)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't GetProcAddress(kernel, FreeLibrary32W)");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
*(FARPROC *)&lpfnGetProcAddress32W = GetProcAddress(hmodKernel, gszGetProcAddress32W);
|
||
|
|
||
|
if (lpfnGetProcAddress32W == NULL)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't GetProcAddress(kernel, GetProcAddress32W)");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
*(FARPROC *)&lpfnCallproc32W = GetProcAddress(hmodKernel, gszCallproc32W);
|
||
|
|
||
|
if (lpfnCallproc32W == NULL)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't GetProcAddress(kernel, CallProc32W)");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// See if we can get a pointer to our thunking entry points
|
||
|
//
|
||
|
pig->dwMsvfw32Handle = (*lpfnLoadLibraryEx32W)(gszMsvfw32, 0L, 0L);
|
||
|
|
||
|
if (pig->dwMsvfw32Handle == 0)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't LoadLibraryEx32W(msvfw32.dll)");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
pig->lpvThunkEntry = (*lpfnGetProcAddress32W)(pig->dwMsvfw32Handle, gszThunkEntry);
|
||
|
|
||
|
if (pig->lpvThunkEntry == NULL)
|
||
|
{
|
||
|
DPFS(dbgInit, 0, "thunkInitialize: Couldn't GetProcAddress32W(msvfw32, ICMThunk32)");
|
||
|
(*lpfnFreeLibrary32W)(pig->dwMsvfw32Handle);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
pig->fThunkError = FALSE;
|
||
|
pig->fThunksInitialized = TRUE;
|
||
|
|
||
|
DPFS(dbgInit, 4, "thunkInitialize: Done!");
|
||
|
|
||
|
return pig;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
// VOID thunkTerminate
|
||
|
//
|
||
|
// Description:
|
||
|
// Thunk termination under NT WOW or Chicago. Called for each process
|
||
|
// by 16-bit side to terminate thunks.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// PICMGARB pig:
|
||
|
//
|
||
|
// Return (VOID):
|
||
|
//
|
||
|
// History:
|
||
|
// 07/07/94 frankye
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
VOID WINAPI thunkTerminate(PICMGARB pig)
|
||
|
{
|
||
|
ASSERT( NULL != pig );
|
||
|
|
||
|
if (pig->fThunksInitialized)
|
||
|
{
|
||
|
lpfnFreeLibrary32W(pig->dwMsvfw32Handle);
|
||
|
pig->fThunksInitialized = FALSE;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
|
||
|
/*
|
||
|
* Generate our thunks - refer to msvideo!compman.c for definitions of
|
||
|
* functions.
|
||
|
*
|
||
|
* NOTE - we often rely here on the fact that most of the message
|
||
|
* parameter structures are identical for 16 and 32-bit - ie they
|
||
|
* contain DWORDs and 32-bit pointers.
|
||
|
*/
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
// LONG thkStatusProc
|
||
|
//
|
||
|
// This is reached by thunking down from the 32-bit thkStatusProc32.
|
||
|
// It will call the client's StatusProc.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// DWORD dwParam : contains segmented ptr to an ICSTATUSTHUNKDESC.
|
||
|
// The ICSTATUSTHUNKDESC is created during the call to ICSetStatusProc.
|
||
|
//
|
||
|
// Return value:
|
||
|
// LONG :
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
|
||
|
LONG FAR PASCAL _loadds thkStatusProc(DWORD dwParam)
|
||
|
{
|
||
|
LPICSTATUSTHUNKDESC lpstd;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "thkStatusProc()");
|
||
|
|
||
|
lpstd = (LPICSTATUSTHUNKDESC)dwParam;
|
||
|
ASSERT( NULL != lpstd );
|
||
|
ASSERT( NULL != lpstd->fnStatusProcS );
|
||
|
|
||
|
return (lpstd->fnStatusProcS)(lpstd->lParam, (UINT)lpstd->uMsg, lpstd->l);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------;
|
||
|
//
|
||
|
// LRESULT ICSendSetStatusProc32
|
||
|
//
|
||
|
// Called from 16-bit ICSendMessage to thunk the ICM_SET_STATUS_PROC
|
||
|
// message to 32-bits
|
||
|
//
|
||
|
// Arguments:
|
||
|
// HIC hic :
|
||
|
//
|
||
|
// LPICSETSTATUSPROC lpissp :
|
||
|
//
|
||
|
// DWORD : cbStruct
|
||
|
//
|
||
|
// Return value:
|
||
|
// LRESULT :
|
||
|
//
|
||
|
// Notes:
|
||
|
// !!! For Daytona, we fail this. If we ever decide to support this
|
||
|
// on Daytona, then I think we have much more work to do since linear
|
||
|
// addresses in use by the 32-bit codec may change when the status
|
||
|
// callback thunks down to 16-bits. On Chicago, all the linear addresses
|
||
|
// our fixed when we convert from the segmented address to the linear
|
||
|
// address. WHY DOESN'T NT GIVE US AN EASY WAY TO FIX LINEAR ADDRESSES?
|
||
|
//
|
||
|
//--------------------------------------------------------------------------;
|
||
|
|
||
|
LRESULT WINAPI ICSendSetStatusProc32(HIC hic, ICSETSTATUSPROC FAR* lpissp, DWORD cbStruct)
|
||
|
{
|
||
|
#ifdef DAYTONA
|
||
|
return ICERR_UNSUPPORTED;
|
||
|
#else
|
||
|
PICMGARB pig;
|
||
|
PIC pic;
|
||
|
LPICSTATUSTHUNKDESC lpstd;
|
||
|
LRESULT lr;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "ICSendSetStatusProc32()");
|
||
|
|
||
|
if (NULL == (pig = thunkInitialize())) {
|
||
|
return ICERR_ERROR;
|
||
|
}
|
||
|
|
||
|
pic = (PIC)hic;
|
||
|
|
||
|
//
|
||
|
// This should never fail since the structure was allocated by
|
||
|
// our own code in the ICSetStatusProc macro.
|
||
|
//
|
||
|
if (cbStruct < sizeof(*lpissp)) {
|
||
|
ASSERT( FALSE );
|
||
|
return ICERR_BADPARAM;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
if (NULL != pic->lpstd) {
|
||
|
DPFS(dbgThunks, 1, "ICSendSetStatusProc32: replacing existing status proc!");
|
||
|
GlobalUnfix(GlobalPtrHandle(pic->lpstd));
|
||
|
GlobalFreePtr(pic->lpstd);
|
||
|
pic->lpstd = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate a ICSTATUSTHUNKDESC status thunk descriptor. We fix it
|
||
|
// in linear memory here so that it's linear address remains constant
|
||
|
// throughout it use. It's linear address will be given to the 32-bit
|
||
|
// codec which will cache it for use in callbacks.
|
||
|
//
|
||
|
lpstd = (LPICSTATUSTHUNKDESC)GlobalAllocPtr(GHND, sizeof(*lpstd));
|
||
|
if (NULL == lpstd) {
|
||
|
return (ICERR_MEMORY);
|
||
|
}
|
||
|
GlobalFix(GlobalPtrHandle(lpstd));
|
||
|
|
||
|
pic->lpstd = lpstd;
|
||
|
|
||
|
lpstd->lpstdS = lpstd;
|
||
|
lpstd->dwFlags = lpissp->dwFlags;
|
||
|
lpstd->lParam = lpissp->lParam;
|
||
|
lpstd->fnStatusProcS = lpissp->Status;
|
||
|
lpstd->pfnthkStatusProc16S = thkStatusProc;
|
||
|
|
||
|
lr = (LRESULT)(*lpfnCallproc32W)(compThunkICSetStatusProc32,
|
||
|
(DWORD)pic->h32,
|
||
|
(DWORD)lpstd,
|
||
|
(DWORD)0,
|
||
|
(DWORD)0,
|
||
|
pig->lpvThunkEntry,
|
||
|
0L, // Don't map pointers
|
||
|
5L);
|
||
|
|
||
|
if (0 != lr) {
|
||
|
DPFS(dbgThunks, 1, "ICSendSetStatusProc32: fail");
|
||
|
GlobalUnfix(GlobalPtrHandle(pic->lpstd));
|
||
|
GlobalFreePtr(pic->lpstd);
|
||
|
pic->lpstd = NULL;
|
||
|
}
|
||
|
|
||
|
return lr;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL FAR PASCAL ICInfoInternal32(DWORD fccType, DWORD fccHandler, ICINFO FAR * lpicInfo, ICINFOI FAR * lpicInfoI)
|
||
|
{
|
||
|
PICMGARB pig;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "ICInfoInternal32");
|
||
|
|
||
|
if (NULL == (pig = thunkInitialize()))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return (BOOL)(*lpfnCallproc32W)(compThunkICInfoInternal32,
|
||
|
(DWORD)fccType,
|
||
|
(DWORD)fccHandler,
|
||
|
(DWORD)lpicInfo,
|
||
|
(DWORD)lpicInfoI,
|
||
|
pig->lpvThunkEntry,
|
||
|
0L, // Don't map pointers
|
||
|
5L);
|
||
|
}
|
||
|
|
||
|
LRESULT FAR PASCAL ICSendMessage32(DWORD hic, UINT msg, DWORD dwP1, DWORD dwP2)
|
||
|
{
|
||
|
PICMGARB pig;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "ICSendMessage32(hic=%08lXh, msg=%04Xh, dwP1=%08lXh, dwP2=%08lXh)", hic, msg, dwP1, dwP2);
|
||
|
|
||
|
if (NULL == (pig = thunkInitialize()))
|
||
|
{
|
||
|
switch (msg) {
|
||
|
case ICM_GETSTATE:
|
||
|
case ICM_SETSTATE:
|
||
|
case ICM_GETINFO:
|
||
|
case ICM_COMPRESS_GET_SIZE:
|
||
|
return 0;
|
||
|
}
|
||
|
return (LRESULT)ICERR_ERROR;
|
||
|
}
|
||
|
|
||
|
return (LRESULT)(*lpfnCallproc32W)(compThunkICSendMessage32,
|
||
|
(DWORD)hic,
|
||
|
(DWORD)msg,
|
||
|
(DWORD)dwP1,
|
||
|
(DWORD)dwP2,
|
||
|
pig->lpvThunkEntry,
|
||
|
0L, // Don't map pointers
|
||
|
5L);
|
||
|
}
|
||
|
|
||
|
LRESULT FAR PASCAL ICOpen32(DWORD fccType, DWORD fccHandler, UINT wMode)
|
||
|
{
|
||
|
PICMGARB pig;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "ICOpen32");
|
||
|
|
||
|
if (NULL == (pig = thunkInitialize()))
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return (DWORD)(lpfnCallproc32W)(compThunkICOpen32,
|
||
|
(DWORD)fccType,
|
||
|
(DWORD)fccHandler,
|
||
|
(DWORD)wMode,
|
||
|
(DWORD)0L,
|
||
|
pig->lpvThunkEntry,
|
||
|
0L, // Don't map pointers
|
||
|
5L);
|
||
|
}
|
||
|
|
||
|
LRESULT FAR PASCAL ICOpenFunction32(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler)
|
||
|
{
|
||
|
PICMGARB pig;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "ICOpenFunction32");
|
||
|
|
||
|
if (NULL == (pig = thunkInitialize()))
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return (LRESULT)(lpfnCallproc32W)(compThunkICOpenFunction32,
|
||
|
(DWORD)fccType,
|
||
|
(DWORD)fccHandler,
|
||
|
(DWORD)wMode,
|
||
|
(DWORD)lpfnHandler,
|
||
|
pig->lpvThunkEntry,
|
||
|
0L, // Don't map pointers
|
||
|
5L);
|
||
|
}
|
||
|
|
||
|
LRESULT FAR PASCAL ICClose32(DWORD hic)
|
||
|
{
|
||
|
PICMGARB pig;
|
||
|
|
||
|
DPFS(dbgThunks, 4, "ICClose32");
|
||
|
|
||
|
if (NULL == (pig = thunkInitialize()))
|
||
|
{
|
||
|
return (LRESULT)ICERR_ERROR;
|
||
|
}
|
||
|
|
||
|
return (DWORD)(lpfnCallproc32W)(compThunkICClose32,
|
||
|
(DWORD)hic,
|
||
|
(DWORD)0L,
|
||
|
(DWORD)0L,
|
||
|
(DWORD)0L,
|
||
|
pig->lpvThunkEntry,
|
||
|
0L, // Don't map pointers
|
||
|
5L);
|
||
|
}
|
||
|
|
||
|
#endif // NT_THUNK16
|
||
|
|