Look up driver info in the registry as well as in system.ini.
Cleanup handling of driver enumeration and fourCC.
This commit is contained in:
parent
6e160f14dd
commit
ed78e4f3a7
@ -3,7 +3,7 @@ TOPOBJDIR = ../..
|
|||||||
SRCDIR = @srcdir@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = msvfw32.dll
|
MODULE = msvfw32.dll
|
||||||
IMPORTS = winmm comctl32 version user32 gdi32 kernel32 ntdll
|
IMPORTS = winmm comctl32 version user32 gdi32 advapi32 kernel32 ntdll
|
||||||
ALTNAMES = msvideo.dll
|
ALTNAMES = msvideo.dll
|
||||||
EXTRALIBS = $(LIBUNICODE)
|
EXTRALIBS = $(LIBUNICODE)
|
||||||
|
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
#include "msvideo_private.h"
|
#include "msvideo_private.h"
|
||||||
#include "winver.h"
|
#include "winver.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
#include "winreg.h"
|
||||||
#include "vfw16.h"
|
#include "vfw16.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
|
WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
|
||||||
|
|
||||||
|
/* Drivers32 settings */
|
||||||
|
#define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DrawDibOpen [MSVIDEO.102]
|
* DrawDibOpen [MSVIDEO.102]
|
||||||
@ -760,35 +763,55 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
|
|||||||
LPSTR buf2, WORD buf2len)
|
LPSTR buf2, WORD buf2len)
|
||||||
{
|
{
|
||||||
DWORD verhandle;
|
DWORD verhandle;
|
||||||
WORD xnr = nr;
|
|
||||||
DWORD infosize;
|
DWORD infosize;
|
||||||
UINT subblocklen;
|
UINT subblocklen;
|
||||||
char *s, buf[2000], fn[260];
|
char *s, buf[2048], fn[260];
|
||||||
LPBYTE infobuf;
|
LPBYTE infobuf;
|
||||||
LPVOID subblock;
|
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);
|
TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
|
||||||
if (GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
|
lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
|
||||||
|
if (lRet == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
s = buf;
|
RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
|
||||||
while (*s)
|
for (i = 0; i < cnt; i++)
|
||||||
{
|
{
|
||||||
if (!strncasecmp(s, "vid", 3))
|
bufLen = sizeof(buf) / sizeof(buf[0]);
|
||||||
{
|
lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
|
||||||
if (!xnr) break;
|
if (lRet != ERROR_SUCCESS) continue;
|
||||||
xnr--;
|
if (strncasecmp(buf, "vid", 3)) continue;
|
||||||
}
|
if (nr--) continue;
|
||||||
s = s + strlen(s) + 1; /* either next char or \0 */
|
fnLen = sizeof(fn);
|
||||||
}
|
lRet = RegQueryValueExA(hKey, buf, 0, 0, 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return 20; /* hmm, out of entries even if we don't have any */
|
if (nr || !found)
|
||||||
if (xnr)
|
|
||||||
{
|
{
|
||||||
FIXME("No more VID* entries found\n");
|
TRACE("No more VID* entries found nr=%d\n", nr);
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini");
|
|
||||||
infosize = GetFileVersionInfoSizeA(fn, &verhandle);
|
infosize = GetFileVersionInfoSizeA(fn, &verhandle);
|
||||||
if (!infosize)
|
if (!infosize)
|
||||||
{
|
{
|
||||||
|
@ -32,11 +32,15 @@
|
|||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
#include "winreg.h"
|
||||||
|
|
||||||
#include "windowsx.h"
|
#include "windowsx.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
/* Drivers32 settings */
|
||||||
|
#define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
|
WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
|
||||||
|
|
||||||
static inline const char *wine_dbgstr_fcc( DWORD fcc )
|
static inline const char *wine_dbgstr_fcc( DWORD fcc )
|
||||||
@ -62,6 +66,14 @@ struct _reg_driver
|
|||||||
|
|
||||||
static reg_driver* reg_driver_list = NULL;
|
static reg_driver* reg_driver_list = NULL;
|
||||||
|
|
||||||
|
/* This one is a macro such that it works for both ASCII and Unicode */
|
||||||
|
#define fourcc_to_string(str, fcc) do { \
|
||||||
|
(str)[0] = LOBYTE(LOWORD(fcc)); \
|
||||||
|
(str)[1] = HIBYTE(LOWORD(fcc)); \
|
||||||
|
(str)[2] = LOBYTE(HIWORD(fcc)); \
|
||||||
|
(str)[3] = HIBYTE(HIWORD(fcc)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
HMODULE MSVFW32_hModule;
|
HMODULE MSVFW32_hModule;
|
||||||
|
|
||||||
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||||
@ -80,20 +92,54 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
|||||||
|
|
||||||
static int compare_fourcc(DWORD fcc1, DWORD fcc2)
|
static int compare_fourcc(DWORD fcc1, DWORD fcc2)
|
||||||
{
|
{
|
||||||
char fcc_str1[5];
|
char fcc_str1[4];
|
||||||
char fcc_str2[5];
|
char fcc_str2[4];
|
||||||
fcc_str1[0] = LOBYTE(LOWORD(fcc1));
|
fourcc_to_string(fcc_str1, fcc1);
|
||||||
fcc_str1[1] = HIBYTE(LOWORD(fcc1));
|
fourcc_to_string(fcc_str2, fcc2);
|
||||||
fcc_str1[2] = LOBYTE(HIWORD(fcc1));
|
return strncasecmp(fcc_str1, fcc_str2, 4);
|
||||||
fcc_str1[3] = HIBYTE(HIWORD(fcc1));
|
}
|
||||||
fcc_str1[4] = 0;
|
|
||||||
fcc_str2[0] = LOBYTE(LOWORD(fcc2));
|
|
||||||
fcc_str2[1] = HIBYTE(LOWORD(fcc2));
|
|
||||||
fcc_str2[2] = LOBYTE(HIWORD(fcc2));
|
|
||||||
fcc_str2[3] = HIBYTE(HIWORD(fcc2));
|
|
||||||
fcc_str2[4] = 0;
|
|
||||||
|
|
||||||
return strcasecmp(fcc_str1,fcc_str2);
|
typedef BOOL (*enum_handler_t)(const char*, int, void*);
|
||||||
|
|
||||||
|
static BOOL enum_drivers(DWORD fccType, enum_handler_t handler, void* param)
|
||||||
|
{
|
||||||
|
CHAR buf[2048], fccTypeStr[5], *s;
|
||||||
|
DWORD i, cnt = 0, bufLen, lRet;
|
||||||
|
BOOL result = FALSE;
|
||||||
|
FILETIME lastWrite;
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
fourcc_to_string(fccTypeStr, fccType);
|
||||||
|
fccTypeStr[4] = '.';
|
||||||
|
|
||||||
|
/* first, go through the registry entries */
|
||||||
|
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, fccTypeStr, 5) || buf[9] != '=') continue;
|
||||||
|
if ((result = handler(buf, i, param))) break;
|
||||||
|
}
|
||||||
|
RegCloseKey( hKey );
|
||||||
|
}
|
||||||
|
if (result) return result;
|
||||||
|
|
||||||
|
/* if that didn't work, go through the values in system.ini */
|
||||||
|
if (GetPrivateProfileSectionA("drivers32", buf, sizeof(buf), "system.ini"))
|
||||||
|
{
|
||||||
|
for (s = buf; *s; cnt++, s += strlen(s) + 1)
|
||||||
|
{
|
||||||
|
if (strncasecmp(s, fccTypeStr, 5) || s[9] != '=') continue;
|
||||||
|
if ((result = handler(s, cnt, param))) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
@ -120,60 +166,45 @@ DWORD WINAPI VideoForWindowsVersion(void)
|
|||||||
return 0x040003B6; /* 4.950 */
|
return 0x040003B6; /* 4.950 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* system.ini: [drivers] */
|
static BOOL ICInfo_enum_handler(const char *drv, int nr, void *param)
|
||||||
|
{
|
||||||
|
ICINFO *lpicinfo = (ICINFO *)param;
|
||||||
|
DWORD fccHandler = mmioStringToFOURCCA(drv + 5, 0);
|
||||||
|
|
||||||
|
/* exact match of fccHandler or nth driver found */
|
||||||
|
if ((lpicinfo->fccHandler != nr) && (lpicinfo->fccHandler != fccHandler))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpicinfo->fccType = mmioStringToFOURCCA(drv, 0);
|
||||||
|
lpicinfo->fccHandler = fccHandler;
|
||||||
|
lpicinfo->dwFlags = 0;
|
||||||
|
lpicinfo->dwVersion = 0;
|
||||||
|
lpicinfo->dwVersionICM = 0x104;
|
||||||
|
lpicinfo->szName[0] = 0;
|
||||||
|
lpicinfo->szDescription[0] = 0;
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, drv + 10, -1, lpicinfo->szDriver,
|
||||||
|
sizeof(lpicinfo->szDriver)/sizeof(WCHAR));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ICInfo [MSVFW32.@]
|
* ICInfo [MSVFW32.@]
|
||||||
* Get information about an installable compressor. Return TRUE if there
|
* Get information about an installable compressor. Return TRUE if there
|
||||||
* is one.
|
* is one.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* fccType [I] type of compressor (e.g. 'vidc')
|
||||||
|
* fccHandler [I] real fcc for handler or <n>th compressor
|
||||||
|
* lpicinfo [O] information about compressor
|
||||||
*/
|
*/
|
||||||
BOOL VFWAPI ICInfo(
|
BOOL VFWAPI ICInfo( DWORD fccType, DWORD fccHandler, ICINFO *lpicinfo)
|
||||||
DWORD fccType, /* [in] type of compressor ('vidc') */
|
|
||||||
DWORD fccHandler, /* [in] real fcc for handler or <n>th compressor */
|
|
||||||
ICINFO *lpicinfo) /* [out] information about compressor */
|
|
||||||
{
|
{
|
||||||
char buf[2000];
|
|
||||||
|
|
||||||
TRACE("(%s,%s/%08lx,%p)\n",
|
TRACE("(%s,%s/%08lx,%p)\n",
|
||||||
wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), fccHandler, lpicinfo);
|
wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), fccHandler, lpicinfo);
|
||||||
|
|
||||||
if (GetPrivateProfileSectionA("drivers32", buf, sizeof(buf), "system.ini"))
|
lpicinfo->fccHandler = fccHandler;
|
||||||
{
|
return enum_drivers(fccType, ICInfo_enum_handler, lpicinfo);
|
||||||
char fccTypeStr[4];
|
|
||||||
char fccHandlerStr[4];
|
|
||||||
char* s;
|
|
||||||
|
|
||||||
fccTypeStr[0] = LOBYTE(LOWORD(fccType));
|
|
||||||
fccTypeStr[1] = HIBYTE(LOWORD(fccType));
|
|
||||||
fccTypeStr[2] = LOBYTE(HIWORD(fccType));
|
|
||||||
fccTypeStr[3] = HIBYTE(HIWORD(fccType));
|
|
||||||
|
|
||||||
fccHandlerStr[0] = LOBYTE(LOWORD(fccHandler));
|
|
||||||
fccHandlerStr[1] = HIBYTE(LOWORD(fccHandler));
|
|
||||||
fccHandlerStr[2] = LOBYTE(HIWORD(fccHandler));
|
|
||||||
fccHandlerStr[3] = HIBYTE(HIWORD(fccHandler));
|
|
||||||
|
|
||||||
for (s = buf; *s; s += strlen(s) + 1)
|
|
||||||
{
|
|
||||||
if (!strncasecmp(fccTypeStr, s, 4) && s[4] == '.' && s[9] == '=' &&
|
|
||||||
(!fccHandler-- || !strncasecmp(fccHandlerStr, s + 5, 4)))
|
|
||||||
{
|
|
||||||
/* exact match of fccHandler or nth driver found ?? */
|
|
||||||
lpicinfo->fccType = fccType;
|
|
||||||
lpicinfo->fccHandler = mmioStringToFOURCCA(s + 5, 0);
|
|
||||||
lpicinfo->dwFlags = 0;
|
|
||||||
lpicinfo->dwVersion = 0;
|
|
||||||
lpicinfo->dwVersionICM = 0x104;
|
|
||||||
lpicinfo->szName[0] = 0;
|
|
||||||
lpicinfo->szDescription[0] = 0;
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, s + 10, -1,
|
|
||||||
lpicinfo->szDriver,
|
|
||||||
sizeof(lpicinfo->szDriver)/sizeof(WCHAR));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD IC_HandleRef = 1;
|
static DWORD IC_HandleRef = 1;
|
||||||
@ -305,15 +336,9 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
|
|||||||
|
|
||||||
if (!driver) {
|
if (!driver) {
|
||||||
/* The driver is registered in the registry */
|
/* The driver is registered in the registry */
|
||||||
codecname[0] = LOBYTE(LOWORD(fccType));
|
fourcc_to_string(codecname, fccType);
|
||||||
codecname[1] = HIBYTE(LOWORD(fccType));
|
|
||||||
codecname[2] = LOBYTE(HIWORD(fccType));
|
|
||||||
codecname[3] = HIBYTE(HIWORD(fccType));
|
|
||||||
codecname[4] = '.';
|
codecname[4] = '.';
|
||||||
codecname[5] = LOBYTE(LOWORD(fccHandler));
|
fourcc_to_string(codecname + 5, fccHandler);
|
||||||
codecname[6] = HIBYTE(LOWORD(fccHandler));
|
|
||||||
codecname[7] = LOBYTE(HIWORD(fccHandler));
|
|
||||||
codecname[8] = HIBYTE(HIWORD(fccHandler));
|
|
||||||
codecname[9] = '\0';
|
codecname[9] = '\0';
|
||||||
|
|
||||||
hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
|
hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
|
||||||
@ -321,10 +346,10 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
|
|||||||
{
|
{
|
||||||
if (fccType == streamtypeVIDEO)
|
if (fccType == streamtypeVIDEO)
|
||||||
{
|
{
|
||||||
codecname[0] = 'v';
|
codecname[0] = 'v';
|
||||||
codecname[1] = 'i';
|
codecname[1] = 'i';
|
||||||
codecname[2] = 'd';
|
codecname[2] = 'd';
|
||||||
codecname[3] = 'c';
|
codecname[3] = 'c';
|
||||||
|
|
||||||
fccType = ICTYPE_VIDEO;
|
fccType = ICTYPE_VIDEO;
|
||||||
hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
|
hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
|
||||||
@ -476,31 +501,66 @@ LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DWORD fccType;
|
||||||
|
DWORD fccHandler;
|
||||||
|
LPBITMAPINFOHEADER lpbiIn;
|
||||||
|
LPBITMAPINFOHEADER lpbiOut;
|
||||||
|
WORD wMode;
|
||||||
|
DWORD querymsg;
|
||||||
|
HIC hic;
|
||||||
|
} driver_info_t;
|
||||||
|
|
||||||
|
static HIC try_driver(driver_info_t *info)
|
||||||
|
{
|
||||||
|
HIC hic;
|
||||||
|
|
||||||
|
if ((hic = ICOpen(info->fccType, info->fccHandler, info->wMode)))
|
||||||
|
{
|
||||||
|
if (!ICSendMessage(hic, info->querymsg, (DWORD)info->lpbiIn, (DWORD)info->lpbiOut))
|
||||||
|
return hic;
|
||||||
|
ICClose(hic);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL ICLocate_enum_handler(const char *drv, int nr, void *param)
|
||||||
|
{
|
||||||
|
driver_info_t *info = (driver_info_t *)param;
|
||||||
|
info->fccHandler = mmioStringToFOURCCA(drv + 5, 0);
|
||||||
|
info->hic = try_driver(info);
|
||||||
|
return info->hic != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ICLocate [MSVFW32.@]
|
* ICLocate [MSVFW32.@]
|
||||||
*/
|
*/
|
||||||
HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
|
HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
|
||||||
LPBITMAPINFOHEADER lpbiOut, WORD wMode)
|
LPBITMAPINFOHEADER lpbiOut, WORD wMode)
|
||||||
{
|
{
|
||||||
HIC hic;
|
driver_info_t info;
|
||||||
DWORD querymsg;
|
|
||||||
LPSTR pszBuffer;
|
|
||||||
|
|
||||||
TRACE("(%s,%s,%p,%p,0x%04x)\n",
|
TRACE("(%s,%s,%p,%p,0x%04x)\n",
|
||||||
wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode);
|
wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode);
|
||||||
|
|
||||||
|
info.fccType = fccType;
|
||||||
|
info.fccHandler = fccHandler;
|
||||||
|
info.lpbiIn = lpbiIn;
|
||||||
|
info.lpbiOut = lpbiOut;
|
||||||
|
info.wMode = wMode;
|
||||||
|
|
||||||
switch (wMode)
|
switch (wMode)
|
||||||
{
|
{
|
||||||
case ICMODE_FASTCOMPRESS:
|
case ICMODE_FASTCOMPRESS:
|
||||||
case ICMODE_COMPRESS:
|
case ICMODE_COMPRESS:
|
||||||
querymsg = ICM_COMPRESS_QUERY;
|
info.querymsg = ICM_COMPRESS_QUERY;
|
||||||
break;
|
break;
|
||||||
case ICMODE_FASTDECOMPRESS:
|
case ICMODE_FASTDECOMPRESS:
|
||||||
case ICMODE_DECOMPRESS:
|
case ICMODE_DECOMPRESS:
|
||||||
querymsg = ICM_DECOMPRESS_QUERY;
|
info.querymsg = ICM_DECOMPRESS_QUERY;
|
||||||
break;
|
break;
|
||||||
case ICMODE_DRAW:
|
case ICMODE_DRAW:
|
||||||
querymsg = ICM_DRAW_QUERY;
|
info.querymsg = ICM_DRAW_QUERY;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN("Unknown mode (%d)\n", wMode);
|
WARN("Unknown mode (%d)\n", wMode);
|
||||||
@ -508,55 +568,16 @@ HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Easy case: handler/type match, we just fire a query and return */
|
/* Easy case: handler/type match, we just fire a query and return */
|
||||||
hic = ICOpen(fccType, fccHandler, wMode);
|
info.hic = try_driver(&info);
|
||||||
if (hic)
|
/* If it didn't work, try each driver in turn. 32 bit codecs only. */
|
||||||
{
|
|
||||||
if (!ICSendMessage(hic, querymsg, (DWORD)lpbiIn, (DWORD)lpbiOut))
|
|
||||||
{
|
|
||||||
TRACE("=> %p\n", hic);
|
|
||||||
return hic;
|
|
||||||
}
|
|
||||||
ICClose(hic);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now try each driver in turn. 32 bit codecs only. */
|
|
||||||
/* FIXME: Move this to an init routine? */
|
/* FIXME: Move this to an init routine? */
|
||||||
|
if (!info.hic) enum_drivers(fccType, ICLocate_enum_handler, &info);
|
||||||
pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(), 0, 1024);
|
|
||||||
if (GetPrivateProfileSectionA("drivers32", pszBuffer, 1024, "system.ini"))
|
|
||||||
{
|
|
||||||
char* s = pszBuffer;
|
|
||||||
char fcc[4];
|
|
||||||
|
|
||||||
while (*s)
|
if (info.hic)
|
||||||
{
|
{
|
||||||
fcc[0] = LOBYTE(LOWORD(fccType));
|
TRACE("=> %p\n", info.hic);
|
||||||
fcc[1] = HIBYTE(LOWORD(fccType));
|
return info.hic;
|
||||||
fcc[2] = LOBYTE(HIWORD(fccType));
|
|
||||||
fcc[3] = HIBYTE(HIWORD(fccType));
|
|
||||||
if (!strncasecmp(fcc, s, 4) && s[4] == '.' && s[9] == '=')
|
|
||||||
{
|
|
||||||
char *s2 = s;
|
|
||||||
while (*s2 != '\0' && *s2 != '.') s2++;
|
|
||||||
if (*s2++)
|
|
||||||
{
|
|
||||||
hic = ICOpen(fccType, mmioStringToFOURCCA(s2, 0), wMode);
|
|
||||||
if (hic)
|
|
||||||
{
|
|
||||||
if (!ICSendMessage(hic, querymsg, (DWORD)lpbiIn, (DWORD)lpbiOut))
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, pszBuffer);
|
|
||||||
TRACE("=> %p\n", hic);
|
|
||||||
return hic;
|
|
||||||
}
|
|
||||||
ICClose(hic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s += strlen(s) + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, pszBuffer);
|
|
||||||
|
|
||||||
if (fccType == streamtypeVIDEO)
|
if (fccType == streamtypeVIDEO)
|
||||||
return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode);
|
return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user