Move the system.ini/[drivers32] section to the registry

Dimitrie O. Paun dpaun at rogers.com
Mon Nov 24 00:58:22 CST 2003


On November 22, 2003 03:18 am, Eric Pouech wrote:
>
> This will break any native Win9x driver configuration.

OK, here it is again, this time around with system.ini support
still in here. Hope this one is acceptable.

ChangeLog
    Move the system.ini/[drivers32] section to the registry.

Index: documentation/samples/system.ini
===================================================================
RCS file: /var/cvs/wine/documentation/samples/system.ini,v
retrieving revision 1.12
diff -u -r1.12 system.ini
--- documentation/samples/system.ini	9 Nov 2003 00:31:35 -0000	1.12
+++ documentation/samples/system.ini	24 Nov 2003 06:51:12 -0000
@@ -8,12 +8,3 @@
 ; videodisc=mcipionr.drv
 waveaudio=mciwave.drv
 
-[drivers32]
-MSACM.imaadpcm=imaadp32.acm
-MSACM.msadpcm=msadp32.acm
-VIDC.MRLE=msrle32.dll
-; VIDC.IV50=ir50_32.dll
-; vidc.CVID=iccvid.dll
-; VIDC.IV31=ir32_32.dll
-; VIDC.IV32=ir32_32.dll
-; vidc.MSVC=msvidc32.dll
Index: winedefault.reg
===================================================================
RCS file: /var/cvs/wine/winedefault.reg,v
retrieving revision 1.79
diff -u -r1.79 winedefault.reg
--- winedefault.reg	18 Nov 2003 20:40:59 -0000	1.79
+++ winedefault.reg	22 Nov 2003 07:54:50 -0000
@@ -48,6 +48,16 @@
 #
 # WinMM config
 #
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI]
+"MPEGVideo"="mciqtz.drv"
+"MPEGVideo2"="mciqtz.drv"
+"avivideo"="mciavi.drv"
+"cdaudio"="mcicda.drv"
+"sequencer"="mciseq.drv"
+"vcr"="mcivisca.drv"
+# "videodisc"="mcipionr.drv"
+"waveaudio"="mciwave.drv"
+
 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions]
 "cda"="cdaudio"
 "mid"="sequencer"
@@ -87,6 +97,16 @@
 "wmv"="MPEGVideo2"
 "wmx"="MPEGVideo2"
 "wvx"="MPEGVideo2"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32]
+"MSACM.imaadpcm"="imaadp32.acm"
+"MSACM.msadpcm"="msadp32.acm"
+"VIDC.MRLE"="msrle32.dll"
+# "VIDC.IV50"="ir50_32.dll"
+# "vidc.CVID"="iccvid.dll"
+# "VIDC.IV31"="ir32_32.dll"
+# "VIDC.IV32"="ir32_32.dll"
+# "vidc.MSVC"="msvidc32.dll"
 
 #
 # Override default load address of BDE (Borland database engine),
Index: dlls/msacm/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/msacm/Makefile.in,v
retrieving revision 1.24
diff -u -r1.24 Makefile.in
--- dlls/msacm/Makefile.in	11 Oct 2003 01:09:19 -0000	1.24
+++ dlls/msacm/Makefile.in	22 Nov 2003 05:26:26 -0000
@@ -5,6 +5,7 @@
 MODULE    = msacm32.dll
 IMPORTS   = winmm user32 advapi32 kernel32
 ALTNAMES  = msacm.dll
+EXTRALIBS = $(LIBUNICODE)
 
 SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
 
Index: dlls/msacm/internal.c
===================================================================
RCS file: /var/cvs/wine/dlls/msacm/internal.c,v
retrieving revision 1.17
diff -u -r1.17 internal.c
--- dlls/msacm/internal.c	5 Sep 2003 23:08:36 -0000	1.17
+++ dlls/msacm/internal.c	24 Nov 2003 06:50:32 -0000
@@ -283,48 +283,50 @@
  */
 void MSACM_RegisterAllDrivers(void)
 {
-    LPWSTR pszBuffer;
-    DWORD dwBufferLength;
     static WCHAR msacm32[] = {'m','s','a','c','m','3','2','.','d','l','l','\0'};
     static WCHAR msacmW[] = {'M','S','A','C','M','.'};
     static WCHAR drv32[] = {'d','r','i','v','e','r','s','3','2','\0'};
     static WCHAR sys[] = {'s','y','s','t','e','m','.','i','n','i','\0'};
+    static WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\',
+			     'M','i','c','r','o','s','o','f','t','\\',
+			     'W','i','n','d','o','w','s',' ','N','T','\\',
+			     'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+			     'D','r','i','v','e','r','s','3','2','\0'};
+    DWORD i, cnt = 0, bufLen, lRet;
+    WCHAR buf[2048], *name, *s;
+    FILETIME lastWrite;
+    HKEY hKey;
 
-    /* FIXME
-     *  What if the user edits system.ini while the program is running?
-     *  Does Windows handle that?
-     */
-    if (MSACM_pFirstACMDriverID)
-	return;
+    /* FIXME: What if the user edits system.ini while the program is running?
+     * Does Windows handle that?  */
+    if (MSACM_pFirstACMDriverID) return;
 
-    /* FIXME: Does not work! How do I determine the section length? */
-    dwBufferLength = 1024;
-/* EPP 	GetPrivateProfileSectionA("drivers32", NULL, 0, "system.ini"); */
+    lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey);
+    if (lRet == ERROR_SUCCESS) {
+	RegQueryInfoKeyW( 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 = RegEnumKeyExW(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
+	    if (lRet != ERROR_SUCCESS) continue;
+	    if (strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue;
+	    if (!(name = strchrW(buf, '='))) continue;
+	    *name = 0;
+	    MSACM_RegisterDriver(buf, name + 1, 0);
+	}
+    	RegCloseKey( hKey );
+    }
 
-    pszBuffer = (LPWSTR) HeapAlloc(MSACM_hHeap, 0, dwBufferLength * sizeof(WCHAR));
-    if (GetPrivateProfileSectionW(drv32, pszBuffer, dwBufferLength, sys))
+    if (GetPrivateProfileSectionW(drv32, buf, sizeof(buf)/sizeof(buf[0]), sys))
     {
-	LPWSTR s = pszBuffer, s2;
-
-	while (*s)
-        {
-            CharUpperBuffW(s, 6);
-            if (memcmp(s, msacmW, 6 * sizeof(WCHAR)) == 0)
-            {
-                s2 = s;
-		while (*s2 != '\0' && *s2 != '=') s2++;
-		if (*s2)
-                {
-		    *s2 = '\0';
-		    MSACM_RegisterDriver(s, s2 + 1, 0);
-		    *s2 = '=';
-		}
-	    }
-	    s += strlenW(s) + 1; /* Either next char or \0 */
+	for(s = buf; *s;  s += strlenW(s) + 1)
+	{
+	    if (strncmpiW(s, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue;
+	    if (!(name = strchrW(s, '='))) continue;
+	    *name = 0;
+	    MSACM_RegisterDriver(s, name + 1, 0);
+	    *name = '=';
 	}
     }
-
-    HeapFree(MSACM_hHeap, 0, pszBuffer);
 
     MSACM_RegisterDriver(msacm32, msacm32, 0);
 }
Index: dlls/msvideo/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/msvideo/Makefile.in,v
retrieving revision 1.26
diff -u -r1.26 Makefile.in
--- dlls/msvideo/Makefile.in	11 Oct 2003 01:09:18 -0000	1.26
+++ dlls/msvideo/Makefile.in	22 Nov 2003 07:20:43 -0000
@@ -3,7 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = msvfw32.dll
-IMPORTS   = winmm comctl32 version user32 gdi32 kernel32
+IMPORTS   = winmm comctl32 version advapi32 user32 gdi32 kernel32
 ALTNAMES  = msvideo.dll
 
 SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
Index: dlls/msvideo/msvideo16.c
===================================================================
RCS file: /var/cvs/wine/dlls/msvideo/msvideo16.c,v
retrieving revision 1.11
diff -u -r1.11 msvideo16.c
--- dlls/msvideo/msvideo16.c	27 Aug 2003 02:20:44 -0000	1.11
+++ dlls/msvideo/msvideo16.c	24 Nov 2003 06:21:46 -0000
@@ -26,11 +26,14 @@
 #include "msvideo_private.h"
 #include "winver.h"
 #include "winnls.h"
+#include "winreg.h"
 #include "vfw16.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
 
+/* Drivers32 settings */
+#define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
 
 /***********************************************************************
  *		DrawDibOpen		[MSVIDEO.102]
@@ -760,35 +763,55 @@
                                         LPSTR buf2, WORD buf2len)
 {
     DWORD	verhandle;
-    WORD	xnr = nr;
     DWORD	infosize;
     UINT	subblocklen;
-    char	*s,  buf[2000],  fn[260];
+    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);
-    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;
-        while (*s) 
-        {
-            if (!strncasecmp(s, "vid", 3)) 
-            {
-                if (!xnr) break;
-                xnr--;
-            }
-            s = s + strlen(s) + 1; /* either next char or \0 */
-        }
+	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, 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 (xnr) 
+
+    if (nr || !found) 
     {
-        FIXME("No more VID* entries found\n");
+        TRACE("No more VID* entries found nr=%d\n", nr);
         return 20;
     }
-    GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini");
     infosize = GetFileVersionInfoSizeA(fn, &verhandle);
     if (!infosize) 
     {
Index: dlls/msvideo/msvideo_main.c
===================================================================
RCS file: /var/cvs/wine/dlls/msvideo/msvideo_main.c,v
retrieving revision 1.53
diff -u -r1.53 msvideo_main.c
--- dlls/msvideo/msvideo_main.c	12 Sep 2003 00:24:17 -0000	1.53
+++ dlls/msvideo/msvideo_main.c	24 Nov 2003 05:55:43 -0000
@@ -32,11 +32,15 @@
 #include "winnls.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winreg.h"
 
 #include "windowsx.h"
 
 #include "wine/debug.h"
 
+/* Drivers32 settings */
+#define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
+
 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
 
 static inline const char *wine_dbgstr_fcc( DWORD fcc )
@@ -62,22 +66,64 @@
 
 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)
+
 static int compare_fourcc(DWORD fcc1, DWORD fcc2)
 {
-  char fcc_str1[5];
-  char fcc_str2[5];
-  fcc_str1[0] = LOBYTE(LOWORD(fcc1));
-  fcc_str1[1] = HIBYTE(LOWORD(fcc1));
-  fcc_str1[2] = LOBYTE(HIWORD(fcc1));
-  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;
+  char fcc_str1[4];
+  char fcc_str2[4];
+  fourcc_to_string(fcc_str1, fcc1);
+  fourcc_to_string(fcc_str2, fcc2);
+  return strncasecmp(fcc_str1, fcc_str2, 4);
+}
+
+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;
 
-  return strcasecmp(fcc_str1,fcc_str2);
+    /* 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;
 }
 
 /******************************************************************
@@ -104,60 +150,45 @@
     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.@]
  * Get information about an installable compressor. Return TRUE if there
  * 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(
-	DWORD fccType,		/* [in] type of compressor ('vidc') */
-	DWORD fccHandler,	/* [in] real fcc for handler or <n>th compressor */
-	ICINFO *lpicinfo)	/* [out] information about compressor */
+BOOL VFWAPI ICInfo( DWORD fccType, DWORD fccHandler, ICINFO *lpicinfo)
 {
-    char	buf[2000];
-
     TRACE("(%s,%s/%08lx,%p)\n", 
           wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), fccHandler, lpicinfo);
 
-    if (GetPrivateProfileSectionA("drivers32", buf, sizeof(buf), "system.ini")) 
-    {
-        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;
+    lpicinfo->fccHandler = fccHandler;
+    return enum_drivers(fccType, ICInfo_enum_handler, lpicinfo);
 }
 
 static DWORD IC_HandleRef = 1;
@@ -289,15 +320,9 @@
 	
     if (!driver) {
         /* The driver is registered in the registry */
-        codecname[0] = LOBYTE(LOWORD(fccType));
-        codecname[1] = HIBYTE(LOWORD(fccType));
-        codecname[2] = LOBYTE(HIWORD(fccType));
-        codecname[3] = HIBYTE(HIWORD(fccType));
+	fourcc_to_string(codecname, fccType);
         codecname[4] = '.';
-        codecname[5] = LOBYTE(LOWORD(fccHandler));
-        codecname[6] = HIBYTE(LOWORD(fccHandler));
-        codecname[7] = LOBYTE(HIWORD(fccHandler));
-        codecname[8] = HIBYTE(HIWORD(fccHandler));
+	fourcc_to_string(codecname + 5, fccHandler);
         codecname[9] = '\0';
 
         hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
@@ -305,10 +330,10 @@
         {
             if (fccType == streamtypeVIDEO) 
             {
-                codecname[0] = 'v';
-                codecname[1] = 'i';
-                codecname[2] = 'd';
-                codecname[3] = 'c';
+		codecname[0] = 'v';
+		codecname[1] = 'i';
+		codecname[2] = 'd';
+		codecname[3] = 'c';
 
 		fccType = ICTYPE_VIDEO;
                 hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
@@ -460,31 +485,66 @@
     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.@]
  */
 HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
                     LPBITMAPINFOHEADER lpbiOut, WORD wMode)
 {
-    HIC         hic;
-    DWORD	querymsg;
-    LPSTR       pszBuffer;
+    driver_info_t info;
 
     TRACE("(%s,%s,%p,%p,0x%04x)\n", 
           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) 
     {
     case ICMODE_FASTCOMPRESS:
     case ICMODE_COMPRESS:
-        querymsg = ICM_COMPRESS_QUERY;
+        info.querymsg = ICM_COMPRESS_QUERY;
         break;
     case ICMODE_FASTDECOMPRESS:
     case ICMODE_DECOMPRESS:
-        querymsg = ICM_DECOMPRESS_QUERY;
+        info.querymsg = ICM_DECOMPRESS_QUERY;
         break;
     case ICMODE_DRAW:
-        querymsg = ICM_DRAW_QUERY;
+        info.querymsg = ICM_DRAW_QUERY;
         break;
     default:
         WARN("Unknown mode (%d)\n", wMode);
@@ -492,55 +552,16 @@
     }
 
     /* Easy case: handler/type match, we just fire a query and return */
-    hic = ICOpen(fccType, fccHandler, wMode);
-    if (hic) 
-    {
-        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. */
+    info.hic = try_driver(&info);
+    /* If it didn't work, try each driver in turn. 32 bit codecs only. */
     /* FIXME: Move this to an init routine? */
-    
-    pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(), 0, 1024);
-    if (GetPrivateProfileSectionA("drivers32", pszBuffer, 1024, "system.ini")) 
-    {
-        char* s = pszBuffer;
-        char  fcc[4];
+    if (!info.hic) enum_drivers(fccType, ICLocate_enum_handler, &info);
 
-        while (*s) 
-        {
-            fcc[0] = LOBYTE(LOWORD(fccType));
-            fcc[1] = HIBYTE(LOWORD(fccType));
-            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;
-        }
+    if (info.hic) 
+    {
+        TRACE("=> %p\n", info.hic);
+	return info.hic;
     }
-    HeapFree(GetProcessHeap(), 0, pszBuffer);
 
     if (fccType == streamtypeVIDEO) 
         return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode);
Index: dlls/winmm/driver.c
===================================================================
RCS file: /var/cvs/wine/dlls/winmm/driver.c,v
retrieving revision 1.25
diff -u -r1.25 driver.c
--- dlls/winmm/driver.c	9 Nov 2003 01:19:59 -0000	1.25
+++ dlls/winmm/driver.c	22 Nov 2003 17:33:25 -0000
@@ -29,12 +29,15 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winnls.h"
+#include "winreg.h"
 #include "mmddk.h"
 #include "winemm.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(driver);
 
+#define HKLM_BASE "Software\\Microsoft\\Windows NT\\CurrentVersion"
+
 static LPWINE_DRIVER   lpDrvItemList  /* = NULL */;
 
 WINE_MMTHREAD*  (*pFnGetMMThread16)(UINT16 h) /* = NULL */;
@@ -206,7 +209,21 @@
  */
 BOOL	DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz)
 {
-    /* should also do some registry diving */
+    HKEY	hKey, hSecKey;
+    DWORD	bufLen, lRet;
+
+    lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_BASE, 0, KEY_QUERY_VALUE, &hKey);
+    if (lRet == ERROR_SUCCESS) {
+	lRet = RegOpenKeyExA(hKey, sectName, 0, KEY_QUERY_VALUE, &hSecKey);
+	if (lRet == ERROR_SUCCESS) {
+	    lRet = RegQueryValueExA(hSecKey, keyName, 0, 0, buf, &bufLen);
+	    RegCloseKey( hSecKey );
+	}
+        RegCloseKey( hKey );
+    }
+    if (lRet == ERROR_SUCCESS) return TRUE;
+    /* default to system.ini if we can't find it in the registry,
+     * to support native installations where system.ini is still used */
     return GetPrivateProfileStringA(sectName, keyName, "", buf, sz, "SYSTEM.INI");
 }
 



-- 
Dimi.




More information about the wine-devel mailing list