📄 msvideo16.c
字号:
*lParam2 = sizeof(ICCOMPRESS);
}
break;
case ICM_DECOMPRESS:
{
ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
ICDECOMPRESS *icd16; /* Same structure except for the pointers */
icd16 = MapSL(*lParam1);
ret = icd16;
COPY(icd, dwFlags);
COPYPTR(icd, lpbiInput);
COPYPTR(icd, lpInput);
COPYPTR(icd, lpbiOutput);
COPYPTR(icd, lpOutput);
COPY(icd, ckid);
*lParam1 = (DWORD)(icd);
*lParam2 = sizeof(ICDECOMPRESS);
}
break;
case ICM_COMPRESS_BEGIN:
case ICM_COMPRESS_GET_FORMAT:
case ICM_COMPRESS_GET_SIZE:
case ICM_COMPRESS_QUERY:
case ICM_DECOMPRESS_GET_FORMAT:
case ICM_DECOMPRESS_QUERY:
case ICM_DECOMPRESS_BEGIN:
case ICM_DECOMPRESS_SET_PALETTE:
case ICM_DECOMPRESS_GET_PALETTE:
*lParam1 = (DWORD)MapSL(*lParam1);
*lParam2 = (DWORD)MapSL(*lParam2);
break;
case ICM_DECOMPRESSEX_QUERY:
if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
/* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
* This is because of ICMessage(). Special case it?
{
LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
if (*lParam2)
addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
else
addr[1] = 0;
ret = addr;
}
break;*/
case ICM_DECOMPRESSEX_BEGIN:
case ICM_DECOMPRESSEX:
ret = MSVIDEO_MapICDEX16To32(lParam1);
*lParam2 = sizeof(ICDECOMPRESSEX);
break;
case ICM_DRAW_BEGIN:
{
ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
ret = icdb16;
COPY(icdb, dwFlags);
icdb->hpal = HPALETTE_32(icdb16->hpal);
icdb->hwnd = HWND_32(icdb16->hwnd);
icdb->hdc = HDC_32(icdb16->hdc);
COPY(icdb, xDst);
COPY(icdb, yDst);
COPY(icdb, dxDst);
COPY(icdb, dyDst);
COPYPTR(icdb, lpbi);
COPY(icdb, xSrc);
COPY(icdb, ySrc);
COPY(icdb, dxSrc);
COPY(icdb, dySrc);
COPY(icdb, dwRate);
COPY(icdb, dwScale);
*lParam1 = (DWORD)(icdb);
*lParam2 = sizeof(ICDRAWBEGIN);
}
break;
case ICM_DRAW_SUGGESTFORMAT:
{
ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
ret = icds16;
COPY(icds, dwFlags);
COPYPTR(icds, lpbiIn);
COPYPTR(icds, lpbiSuggest);
COPY(icds, dxSrc);
COPY(icds, dySrc);
COPY(icds, dxDst);
COPY(icds, dyDst);
icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
*lParam1 = (DWORD)(icds);
*lParam2 = sizeof(ICDRAWSUGGEST);
}
break;
case ICM_DRAW:
{
ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
ICDRAW *icd16 = MapSL(*lParam1);
ret = icd16;
COPY(icd, dwFlags);
COPYPTR(icd, lpFormat);
COPYPTR(icd, lpData);
COPY(icd, cbData);
COPY(icd, lTime);
*lParam1 = (DWORD)(icd);
*lParam2 = sizeof(ICDRAW);
}
break;
case ICM_DRAW_START:
case ICM_DRAW_STOP:
break;
default:
FIXME("%d is not yet handled. Expect a crash.\n", msg);
}
return ret;
}
#undef COPY
#undef COPYPTR
/******************************************************************
* MSVIDEO_UnmapMsg16To32
*
*
*/
static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
{
TRACE("Unmapping %d\n", msg);
#define UNCOPY(x, y) (x##16->y = x->y);
switch (msg)
{
case ICM_GETINFO:
{
ICINFO *ici = (ICINFO*)(*lParam1);
ICINFO16 *ici16 = (ICINFO16*)data16;
UNCOPY(ici, fccType);
UNCOPY(ici, fccHandler);
UNCOPY(ici, dwFlags);
UNCOPY(ici, dwVersion);
UNCOPY(ici, dwVersionICM);
WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
sizeof(ici16->szName), NULL, NULL );
ici16->szName[sizeof(ici16->szName)-1] = 0;
WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
sizeof(ici16->szDescription), NULL, NULL );
ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
/* This just gives garbage for some reason - BB
lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
HeapFree(GetProcessHeap(), 0, ici);
}
break;
case ICM_DECOMPRESS_QUERY:
/*{
LPVOID* x = data16;
HeapFree(GetProcessHeap(), 0, x[0]);
if (x[1])
HeapFree(GetProcessHeap(), 0, x[1]);
}
break;*/
case ICM_COMPRESS:
case ICM_DECOMPRESS:
case ICM_DECOMPRESSEX_QUERY:
case ICM_DECOMPRESSEX_BEGIN:
case ICM_DECOMPRESSEX:
case ICM_DRAW_BEGIN:
case ICM_DRAW_SUGGESTFORMAT:
case ICM_DRAW:
HeapFree(GetProcessHeap(), 0, data16);
break;
default:
ERR("Unmapping unmapped msg %d\n", msg);
}
#undef UNCOPY
}
/***********************************************************************
* ICInfo [MSVIDEO.200]
*/
BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
{
BOOL16 ret;
LPVOID lpv;
DWORD lParam = (DWORD)lpicinfo;
DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
/* Use the mapping functions to map the ICINFO structure */
lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
return ret;
}
/******************************************************************
* IC_Callback3216
*
*
*/
static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2)
{
WINE_HIC* whic;
WORD args[8];
whic = MSVIDEO_GetHicPtr(hic);
if (whic)
{
DWORD ret = 0;
switch (msg)
{
case DRV_OPEN:
lp2 = (DWORD)MapLS((void*)lp2);
break;
}
args[7] = HIWORD(hic);
args[6] = LOWORD(hic);
args[5] = HDRVR_16(whic->hdrv);
args[4] = msg;
args[3] = HIWORD(lp1);
args[2] = LOWORD(lp1);
args[1] = HIWORD(lp2);
args[0] = LOWORD(lp2);
WOWCallback16Ex( (DWORD)whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret );
switch (msg)
{
case DRV_OPEN:
UnMapLS(lp2);
break;
}
return ret;
}
else return ICERR_BADHANDLE;
}
/***********************************************************************
* ICOpenFunction [MSVIDEO.206]
*/
HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
{
HIC hic32;
hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode,
(DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler);
return HIC_16(hic32);
}
/***********************************************************************
* ICSendMessage [MSVIDEO.205]
*/
LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2)
{
LRESULT ret = ICERR_BADHANDLE;
WINE_HIC* whic;
whic = MSVIDEO_GetHicPtr(HIC_32(hic));
if (whic)
{
/* we've got a 16 bit driver proc... call it directly */
if (whic->driverproc16)
{
WORD args[8];
DWORD result;
/* FIXME: original code was passing hdrv first and hic second */
/* but this doesn't match what IC_Callback3216 does */
args[7] = HIWORD(hic);
args[6] = LOWORD(hic);
args[5] = HDRVR_16(whic->hdrv);
args[4] = msg;
args[3] = HIWORD(lParam1);
args[2] = LOWORD(lParam1);
args[1] = HIWORD(lParam2);
args[0] = LOWORD(lParam2);
WOWCallback16Ex( (DWORD)whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result );
ret = result;
}
else
{
/* map the message for a 32 bit infrastructure, and pass it along */
void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2);
if (data16)
MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
}
}
return ret;
}
/***********************************************************************
* VideoCapDriverDescAndVer [MSVIDEO.22]
*/
DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
LPSTR buf2, WORD buf2len)
{
static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
DWORD verhandle;
DWORD infosize;
UINT subblocklen;
char *s, buf[2048], fn[260];
LPBYTE infobuf;
LPVOID subblock;
DWORD i, cnt = 0, lRet;
DWORD bufLen, fnLen;
FILETIME lastWrite;
HKEY hKey;
BOOL found = FALSE;
TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
if (lRet == ERROR_SUCCESS)
{
RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
for (i = 0; i < cnt; i++)
{
bufLen = sizeof(buf) / sizeof(buf[0]);
lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
if (lRet != ERROR_SUCCESS) continue;
if (strncasecmp(buf, "vid", 3)) continue;
if (nr--) continue;
fnLen = sizeof(fn);
lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
if (lRet == ERROR_SUCCESS) found = TRUE;
break;
}
RegCloseKey( hKey );
}
/* search system.ini if not found in the registry */
if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
{
for (s = buf; *s; s += strlen(s) + 1)
{
if (strncasecmp(s, "vid", 3)) continue;
if (nr--) continue;
if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
found = TRUE;
break;
}
}
if (nr || !found)
{
TRACE("No more VID* entries found nr=%d\n", nr);
return 20;
}
infosize = GetFileVersionInfoSizeA(fn, &verhandle);
if (!infosize)
{
TRACE("%s has no fileversioninfo.\n", fn);
return 18;
}
infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf))
{
/* Yes, two space behind : */
/* FIXME: test for buflen */
snprintf(buf2, buf2len, "Version: %d.%d.%d.%d\n",
((WORD*)infobuf)[0x0f],
((WORD*)infobuf)[0x0e],
((WORD*)infobuf)[0x11],
((WORD*)infobuf)[0x10]
);
TRACE("version of %s is %s\n", fn, buf2);
}
else
{
TRACE("GetFileVersionInfoA failed for %s.\n", fn);
lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
}
/* FIXME: language problem? */
if (VerQueryValueA( infobuf,
version_info_spec,
&subblock,
&subblocklen
))
{
UINT copylen = min(subblocklen,buf1len-1);
memcpy(buf1, subblock, copylen);
buf1[copylen] = '\0';
TRACE("VQA returned %s\n", (LPCSTR)subblock);
}
else
{
TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
}
HeapFree(GetProcessHeap(), 0, infobuf);
return 0;
}
/******************************************************************
* IC_CallTo16
*
*
*/
static LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2)
{
#if 0
WINE_HIC* whic = IC_GetPtr(hic);
LRESULT ret = 0;
if (whic->driverproc)
{
ret = whic->driverproc(hic, whic->hdrv, msg, lParam1, lParam2);
}
else
{
ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
}
#else
FIXME("No 32=>16 conversion yet\n");
#endif
return 0;
}
/**************************************************************************
* DllEntryPoint (MSVIDEO.3)
*
* MSVIDEO DLL entry point
*
*/
BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
/* hook in our 16 bit management functions */
pFnCallTo16 = IC_CallTo16;
break;
case DLL_PROCESS_DETACH:
/* remove our 16 bit management functions */
pFnCallTo16 = NULL;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -