[MSVFW32] Sync with Wine Staging 4.18. CORE-16441
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 10 Nov 2019 13:07:06 +0000 (14:07 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 10 Nov 2019 13:07:06 +0000 (14:07 +0100)
dll/win32/msvfw32/mciwnd.c
dll/win32/msvfw32/msvideo_main.c
media/doc/README.WINE

index 50899e1..0b35bad 100644 (file)
@@ -32,7 +32,6 @@
 #include "vfw.h"
 #include "digitalv.h"
 #include "commctrl.h"
-#include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mci);
@@ -200,7 +199,7 @@ static void MCIWND_UpdateState(MCIWndInfo *mwi)
         return;
 
     if ((mwi->dwStyle & MCIWNDF_SHOWNAME) && mwi->lpName)
-        strcpyW(buffer, mwi->lpName);
+        lstrcpyW(buffer, mwi->lpName);
     else
         *buffer = 0;
 
@@ -209,8 +208,8 @@ static void MCIWND_UpdateState(MCIWndInfo *mwi)
         static const WCHAR spaceW[] = {' ',0};
         static const WCHAR l_braceW[] = {'(',0};
 
-        if (*buffer) strcatW(buffer, spaceW);
-        strcatW(buffer, l_braceW);
+        if (*buffer) lstrcatW(buffer, spaceW);
+        lstrcatW(buffer, l_braceW);
     }
 
     if (mwi->dwStyle & MCIWNDF_SHOWPOS)
@@ -219,13 +218,13 @@ static void MCIWND_UpdateState(MCIWndInfo *mwi)
 
         posW[0] = 0;
         SendMessageW(mwi->hWnd, MCIWNDM_GETPOSITIONW, 64, (LPARAM)posW);
-        strcatW(buffer, posW);
+        lstrcatW(buffer, posW);
     }
 
     if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
     {
         static const WCHAR dashW[] = {' ','-',' ',0};
-        strcatW(buffer, dashW);
+        lstrcatW(buffer, dashW);
     }
 
     if (mwi->dwStyle & MCIWNDF_SHOWMODE)
@@ -234,13 +233,13 @@ static void MCIWND_UpdateState(MCIWndInfo *mwi)
 
         modeW[0] = 0;
         SendMessageW(mwi->hWnd, MCIWNDM_GETMODEW, 64, (LPARAM)modeW);
-        strcatW(buffer, modeW);
+        lstrcatW(buffer, modeW);
     }
 
     if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE))
     {
         static const WCHAR r_braceW[] = {')',0};
-        strcatW(buffer, r_braceW);
+        lstrcatW(buffer, r_braceW);
     }
 
     TRACE("=> %s\n", debugstr_w(buffer));
@@ -590,8 +589,8 @@ static LRESULT WINAPI MCIWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lPa
             mwi->mci = mci_open.wDeviceID;
             mwi->alias = HandleToLong(hWnd) + 1;
 
-            mwi->lpName = HeapAlloc(GetProcessHeap(), 0, (strlenW((LPWSTR)lParam) + 1) * sizeof(WCHAR));
-            strcpyW(mwi->lpName, (LPWSTR)lParam);
+            mwi->lpName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW((LPWSTR)lParam) + 1) * sizeof(WCHAR));
+            lstrcpyW(mwi->lpName, (LPWSTR)lParam);
 
             MCIWND_UpdateState(mwi);
 
@@ -987,7 +986,7 @@ end_of_mci_open:
 
             TRACE("MCIWNDM_SENDSTRINGW %s\n", debugstr_w((LPCWSTR)lParam));
 
-            p = strchrW((LPCWSTR)lParam, ' ');
+            p = wcschr((LPCWSTR)lParam, ' ');
             if (p)
             {
                 static const WCHAR formatW[] = {'%','d',' ',0};
@@ -1000,7 +999,7 @@ end_of_mci_open:
 
                 memcpy(cmdW, (void *)lParam, pos * sizeof(WCHAR));
                 wsprintfW(cmdW + pos, formatW, mwi->alias);
-                strcatW(cmdW, (WCHAR *)lParam + pos);
+                lstrcatW(cmdW, (WCHAR *)lParam + pos);
             }
             else
                 cmdW = (LPWSTR)lParam;
@@ -1182,7 +1181,7 @@ end_of_mci_open:
             {
                 cmdW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW((LPCWSTR)lParam) + 64) * sizeof(WCHAR));
                 wsprintfW(cmdW, formatW, mwi->alias);
-                strcatW(cmdW, (WCHAR *)lParam);
+                lstrcatW(cmdW, (WCHAR *)lParam);
 
                 mwi->lasterror = mciSendStringW(cmdW, NULL, 0, 0);
 
index 4b09913..09ed031 100644 (file)
 #include "winreg.h"
 #include "winnls.h"
 #include "wingdi.h"
+#include "wine/winternl.h"
 #include "winuser.h"
 #include "commdlg.h"
 #include "vfw.h"
 #include "msvideo_private.h"
 #include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/list.h"
 
 /* Drivers32 settings */
 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
@@ -100,17 +103,15 @@ static const char *wine_dbgstr_icerr( int ret )
 
 static WINE_HIC*        MSVIDEO_FirstHic /* = NULL */;
 
-typedef struct _reg_driver reg_driver;
-struct _reg_driver
+struct reg_driver
 {
     DWORD       fccType;
     DWORD       fccHandler;
     DRIVERPROC  proc;
-    LPWSTR      name;
-    reg_driver* next;
+    struct list entry;
 };
 
-static reg_driver* reg_driver_list = NULL;
+static struct list reg_driver_list = LIST_INIT(reg_driver_list);
 
 HMODULE MSVFW32_hModule;
 
@@ -220,7 +221,7 @@ static int compare_fourcc(DWORD fcc1, DWORD fcc2)
   char fcc_str2[4];
   fourcc_to_string(fcc_str1, fcc1);
   fourcc_to_string(fcc_str2, fcc2);
-  return strncasecmp(fcc_str1, fcc_str2, 4);
+  return _strnicmp(fcc_str1, fcc_str2, 4);
 }
 
 static DWORD get_size_image(LONG width, LONG height, WORD depth)
@@ -232,53 +233,6 @@ static DWORD get_size_image(LONG width, LONG height, WORD depth)
     return ret;
 }
 
-typedef BOOL (*enum_handler_t)(const char *name, const char *driver, unsigned int index, void *param);
-
-static BOOL enum_drivers(DWORD fccType, enum_handler_t handler, void* param)
-{
-    char fccTypeStr[4];
-    char name_buf[10];
-    char buf[2048];
-
-    DWORD i, cnt = 0, lRet;
-    BOOL result = FALSE;
-    HKEY hKey;
-
-    fourcc_to_string(fccTypeStr, fccType);
-
-    /* first, go through the registry entries */
-    lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
-    if (lRet == ERROR_SUCCESS) 
-    {
-        i = 0;
-        for (;;)
-        {
-            DWORD name_len = 10, driver_len = 128;
-            lRet = RegEnumValueA(hKey, i++, name_buf, &name_len, 0, 0, (BYTE *)buf, &driver_len);
-            if (lRet == ERROR_NO_MORE_ITEMS) break;
-            if (name_len != 9 || name_buf[4] != '.') continue;
-            if (fccType && strncasecmp(name_buf, fccTypeStr, 4)) continue;
-            if ((result = handler(name_buf, buf, cnt++, 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")) 
-    {
-        char *s;
-        for (s = buf; *s; s += strlen(s) + 1)
-        {
-            if (s[4] != '.' || s[9] != '=') continue;
-            if (fccType && strncasecmp(s, fccTypeStr, 4)) continue;
-            if ((result = handler(s, s + 10, cnt++, param))) break;
-        }
-    }
-
-    return result;
-}
-
 /******************************************************************
  *             MSVIDEO_GetHicPtr
  *
@@ -303,27 +257,6 @@ DWORD WINAPI VideoForWindowsVersion(void)
     return 0x040003B6; /* 4.950 */
 }
 
-static BOOL ICInfo_enum_handler(const char *name, const char *driver, unsigned int nr, void *param)
-{
-    ICINFO *lpicinfo = param;
-    DWORD fccType = mmioStringToFOURCCA(name, 0);
-    DWORD fccHandler = mmioStringToFOURCCA(name + 5, 0);
-
-    if (lpicinfo->fccHandler != nr && compare_fourcc(lpicinfo->fccHandler, fccHandler))
-        return FALSE;
-
-    lpicinfo->fccType = fccType;
-    lpicinfo->fccHandler = fccHandler;
-    lpicinfo->dwFlags = 0;
-    lpicinfo->dwVersion = 0;
-    lpicinfo->dwVersionICM = ICVERSION;
-    lpicinfo->szName[0] = 0;
-    lpicinfo->szDescription[0] = 0;
-    MultiByteToWideChar(CP_ACP, 0, driver, -1, lpicinfo->szDriver, ARRAY_SIZE(lpicinfo->szDriver));
-
-    return TRUE;
-}
-
 /***********************************************************************
  *             ICInfo                          [MSVFW32.@]
  * Get information about an installable compressor. Return TRUE if there
@@ -334,99 +267,170 @@ static BOOL ICInfo_enum_handler(const char *name, const char *driver, unsigned i
  *   fccHandler  [I] real fcc for handler or <n>th compressor
  *   lpicinfo    [O] information about compressor
  */
-BOOL VFWAPI ICInfo( DWORD fccType, DWORD fccHandler, ICINFO *lpicinfo)
+BOOL VFWAPI ICInfo(DWORD type, DWORD handler, ICINFO *info)
 {
-    TRACE("(%s,%s,%p)\n",
-          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpicinfo);
+    char name_buf[10], buf[2048];
+    DWORD ret_type, ret_handler;
+    struct reg_driver *driver;
+    DWORD i, count = 0;
+    LONG res;
+    HKEY key;
 
-    lpicinfo->fccType = fccType;
-    lpicinfo->fccHandler = fccHandler;
-    return enum_drivers(fccType, ICInfo_enum_handler, lpicinfo);
+    TRACE("type %s, handler %s, info %p.\n",
+            wine_dbgstr_fcc(type), wine_dbgstr_fcc(handler), info);
+
+    memset(info, 0, sizeof(*info));
+    info->dwSize = sizeof(*info);
+    info->dwVersionICM = ICVERSION;
+
+    if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &key))
+    {
+        i = 0;
+        for (;;)
+        {
+            DWORD name_len = ARRAY_SIZE(name_buf), driver_len = ARRAY_SIZE(info->szDriver);
+
+            res = RegEnumValueA(key, i++, name_buf, &name_len, 0, 0, (BYTE *)buf, &driver_len);
+            if (res == ERROR_NO_MORE_ITEMS) break;
+
+            if (name_len != 9 || name_buf[4] != '.') continue;
+            ret_type = mmioStringToFOURCCA(name_buf, 0);
+            ret_handler = mmioStringToFOURCCA(name_buf + 5, 0);
+            if (type && compare_fourcc(type, ret_type)) continue;
+            if (compare_fourcc(handler, ret_handler) && handler != count++) continue;
+
+            info->fccType = ret_type;
+            info->fccHandler = ret_handler;
+            MultiByteToWideChar(CP_ACP, 0, buf, -1, info->szDriver, ARRAY_SIZE(info->szDriver));
+            TRACE("Returning codec %s, driver %s.\n", debugstr_a(name_buf), debugstr_a(buf));
+            return TRUE;
+        }
+        RegCloseKey(key);
+    }
+
+    if (GetPrivateProfileSectionA("drivers32", buf, sizeof(buf), "system.ini"))
+    {
+        char *s;
+        for (s = buf; *s; s += strlen(s) + 1)
+        {
+            if (s[4] != '.' || s[9] != '=') continue;
+            ret_type = mmioStringToFOURCCA(s, 0);
+            ret_handler = mmioStringToFOURCCA(s + 5, 0);
+            if (type && compare_fourcc(type, ret_type)) continue;
+            if (compare_fourcc(handler, ret_handler) && handler != count++) continue;
+
+            info->fccType = ret_type;
+            info->fccHandler = ret_handler;
+            MultiByteToWideChar(CP_ACP, 0, s + 10, -1, info->szDriver, ARRAY_SIZE(info->szDriver));
+            TRACE("Returning codec %s, driver %s.\n", debugstr_an(s, 8), debugstr_a(s + 10));
+            return TRUE;
+        }
+    }
+
+    LIST_FOR_EACH_ENTRY(driver, &reg_driver_list, struct reg_driver, entry)
+    {
+        if (type && compare_fourcc(type, driver->fccType)) continue;
+        if (compare_fourcc(handler, driver->fccHandler) && handler != count++) continue;
+        if (driver->proc(0, NULL, ICM_GETINFO, (DWORD_PTR)info, sizeof(*info)) == sizeof(*info))
+            return TRUE;
+    }
+
+    info->fccType = type;
+    info->fccHandler = handler;
+    WARN("No driver found for codec %s.%s.\n", wine_dbgstr_fcc(type), wine_dbgstr_fcc(handler));
+    return FALSE;
 }
 
 static DWORD IC_HandleRef = 1;
 
 /***********************************************************************
- *             ICInstall                       [MSVFW32.@]
+ *              ICInstall                       [MSVFW32.@]
  */
-BOOL VFWAPI ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR szDesc, UINT wFlags) 
+BOOL VFWAPI ICInstall(DWORD type, DWORD handler, LPARAM lparam, char *desc, UINT flags)
 {
-    reg_driver* driver;
-    unsigned len;
+    struct reg_driver *driver;
 
-    TRACE("(%s,%s,%p,%p,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), (void*)lParam, szDesc, wFlags);
+    TRACE("type %s, handler %s, lparam %#lx, desc %s, flags %#x.\n",
+            wine_dbgstr_fcc(type), wine_dbgstr_fcc(handler), lparam, debugstr_a(desc), flags);
 
-    /* Check if a driver is already registered */
-    for (driver = reg_driver_list; driver; driver = driver->next)
+    LIST_FOR_EACH_ENTRY(driver, &reg_driver_list, struct reg_driver, entry)
     {
-        if (!compare_fourcc(fccType, driver->fccType) &&
-            !compare_fourcc(fccHandler, driver->fccHandler))
-            break;
+        if (!compare_fourcc(type, driver->fccType)
+                && !compare_fourcc(handler, driver->fccHandler))
+        {
+            return FALSE;
+        }
     }
-    if (driver) return FALSE;
 
-    /* Register the driver */
-    driver = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(reg_driver));
-    if (!driver) goto oom;
-    driver->fccType = fccType;
-    driver->fccHandler = fccHandler;
-
-    switch(wFlags)
+    switch (flags)
     {
     case ICINSTALL_FUNCTION:
-        driver->proc = (DRIVERPROC)lParam;
-       driver->name = NULL;
-        break;
+        if (!(driver = heap_alloc_zero(sizeof(*driver))))
+            return FALSE;
+        driver->fccType = type;
+        driver->fccHandler = handler;
+        driver->proc = (DRIVERPROC)lparam;
+        list_add_tail(&reg_driver_list, &driver->entry);
+        return TRUE;
     case ICINSTALL_DRIVER:
-       driver->proc = NULL;
-        len = MultiByteToWideChar(CP_ACP, 0, (char*)lParam, -1, NULL, 0);
-        driver->name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!driver->name) goto oom;
-        MultiByteToWideChar(CP_ACP, 0, (char*)lParam, -1, driver->name, len);
-       break;
+    {
+        const char *driver = (const char *)lparam;
+        char value[10];
+        HKEY key;
+        LONG res;
+
+        if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_SET_VALUE, &key))
+            return FALSE;
+        fourcc_to_string(value, type);
+        value[4] = '.';
+        fourcc_to_string(value + 5, handler);
+        value[9] = 0;
+        res = RegSetValueExA(key, value, 0, REG_SZ, (const BYTE *)driver, strlen(driver) + 1);
+        RegCloseKey(key);
+        return !res;
+    }
     default:
-       ERR("Invalid flags!\n");
-       HeapFree(GetProcessHeap(), 0, driver);
-       return FALSE;
-   }
-
-   /* Insert our driver in the list*/
-   driver->next = reg_driver_list;
-   reg_driver_list = driver;
-    
-   return TRUE;
-oom:
-   HeapFree(GetProcessHeap(), 0, driver);
-   return FALSE;
+        FIXME("Unhandled flags %#x.\n", flags);
+        return FALSE;
+    }
 }
 
 /***********************************************************************
- *             ICRemove                        [MSVFW32.@]
+ *              ICRemove                        [MSVFW32.@]
  */
-BOOL VFWAPI ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags) 
+BOOL VFWAPI ICRemove(DWORD type, DWORD handler, UINT flags)
 {
-    reg_driver** pdriver;
-    reg_driver*  drv;
+    struct reg_driver *driver;
+    char value[10];
+    HKEY key;
+    LONG res;
 
-    TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wFlags);
+    TRACE("type %s, handler %s, flags %#x.\n",
+            wine_dbgstr_fcc(type), wine_dbgstr_fcc(handler), flags);
 
-    /* Check if a driver is already registered */
-    for (pdriver = &reg_driver_list; *pdriver; pdriver = &(*pdriver)->next)
+    LIST_FOR_EACH_ENTRY(driver, &reg_driver_list, struct reg_driver, entry)
     {
-        if (!compare_fourcc(fccType, (*pdriver)->fccType) &&
-            !compare_fourcc(fccHandler, (*pdriver)->fccHandler))
-            break;
+        if (!compare_fourcc(type, driver->fccType)
+                && !compare_fourcc(handler, driver->fccHandler))
+        {
+            list_remove(&driver->entry);
+            heap_free(driver);
+            return TRUE;
+        }
     }
-    if (!*pdriver)
-        return FALSE;
 
-    /* Remove the driver from the list */
-    drv = *pdriver;
-    *pdriver = (*pdriver)->next;
-    HeapFree(GetProcessHeap(), 0, drv->name);
-    HeapFree(GetProcessHeap(), 0, drv);
-    
-    return TRUE;  
+    if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_SET_VALUE, &key))
+    {
+        fourcc_to_string(value, type);
+        value[4] = '.';
+        fourcc_to_string(value + 5, handler);
+        value[9] = 0;
+        res = RegDeleteValueA(key, value);
+        RegCloseKey(key);
+        return !res;
+    }
+
+    return FALSE;
 }
 
 
@@ -438,10 +442,10 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
 {
     WCHAR              codecname[10];
     ICOPEN             icopen;
-    HDRVR              hdrv;
     WINE_HIC*           whic;
     static const WCHAR  drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'};
-    reg_driver*         driver;
+    struct reg_driver *driver;
+    HDRVR hdrv = NULL;
 
     TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode);
 
@@ -466,21 +470,15 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
         }
     }
 
-    /* Check if there is a registered driver that matches */
-    driver = reg_driver_list;
-    while(driver)
-        if (!compare_fourcc(fccType, driver->fccType) &&
-            !compare_fourcc(fccHandler, driver->fccHandler)) {
-           fccType = driver->fccType;
-           fccHandler = driver->fccHandler;
-           break;
-        } else
-            driver = driver->next;
-
-    if (driver && driver->proc)
-        /* The driver has been registered at runtime with its driverproc */
-        return ICOpenFunction(fccType, fccHandler, wMode, driver->proc);
-  
+    LIST_FOR_EACH_ENTRY(driver, &reg_driver_list, struct reg_driver, entry)
+    {
+        if (!compare_fourcc(fccType, driver->fccType)
+                && !compare_fourcc(fccHandler, driver->fccHandler))
+        {
+            return ICOpenFunction(driver->fccType, driver->fccHandler, wMode, driver->proc);
+        }
+    }
+
     /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
      * same layout as ICOPEN
      */
@@ -494,7 +492,8 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
     icopen.pV2Reserved = NULL;
     icopen.dnDevNode   = 0; /* FIXME */
 
-    if (!driver) {
+    if (!hdrv)
+    {
         /* normalize to lower case as in 'vidc' */
         ((char*)&fccType)[0] = tolower(((char*)&fccType)[0]);
         ((char*)&fccType)[1] = tolower(((char*)&fccType)[1]);
@@ -510,15 +509,9 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
         hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
         if (!hdrv)
             return 0;
-    } else {
-        /* The driver has been registered at runtime with its name */
-        hdrv = OpenDriver(driver->name, NULL, (LPARAM)&icopen);
-        if (!hdrv) 
-            return 0; 
     }
 
-    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
-    if (!whic)
+    if (!(whic = heap_alloc(sizeof(*whic))))
     {
         CloseDriver(hdrv, 0, 0);
         return FALSE;
@@ -557,8 +550,8 @@ HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPRO
     icopen.pV2Reserved = NULL;
     icopen.dnDevNode   = 0; /* FIXME */
 
-    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
-    if (!whic) return 0;
+    if (!(whic = heap_alloc(sizeof(*whic))))
+        return NULL;
 
     whic->driverproc   = lpfnHandler;
     while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++;
@@ -573,7 +566,7 @@ HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPRO
     {
         WARN("DRV_LOAD failed for hic %p\n", whic->hic);
         MSVIDEO_FirstHic = whic->next;
-        HeapFree(GetProcessHeap(), 0, whic);
+        heap_free(whic);
         return 0;
     }
     /* return value is not checked */
@@ -587,7 +580,7 @@ HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPRO
     {
         WARN("DRV_OPEN failed for hic %p\n", whic->hic);
         MSVIDEO_FirstHic = whic->next;
-        HeapFree(GetProcessHeap(), 0, whic);
+        heap_free(whic);
         return 0;
     }
 
@@ -634,89 +627,69 @@ LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb)
     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_PTR)info->lpbiIn, (DWORD_PTR)info->lpbiOut))
-           return hic;
-       ICClose(hic);
-    }
-    return 0;
-}
-
-static BOOL ICLocate_enum_handler(const char *name, const char *driver, unsigned int nr, void *param)
-{
-    driver_info_t *info = param;
-    info->fccHandler = mmioStringToFOURCCA(name + 5, 0);
-    info->hic = try_driver(info);
-    return info->hic != 0;
-}
-
 /***********************************************************************
- *             ICLocate                        [MSVFW32.@]
+ *              ICLocate                        [MSVFW32.@]
  */
-HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
-                    LPBITMAPINFOHEADER lpbiOut, WORD wMode)
+HIC VFWAPI ICLocate(DWORD type, DWORD handler, BITMAPINFOHEADER *in,
+        BITMAPINFOHEADER *out, WORD mode)
 {
-    driver_info_t info;
-
-    TRACE("(%s,%s,%p,%p,0x%04x)\n", 
-          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode);
+    ICINFO info = {sizeof(info)};
+    UINT msg;
+    HIC hic;
+    DWORD i;
 
-    info.fccType = fccType;
-    info.fccHandler = fccHandler;
-    info.lpbiIn = lpbiIn;
-    info.lpbiOut = lpbiOut;
-    info.wMode = wMode;
+    TRACE("type %s, handler %s, in %p, out %p, mode %u.\n",
+            wine_dbgstr_fcc(type), wine_dbgstr_fcc(handler), in, out, mode);
 
-    switch (wMode) 
+    switch (mode)
     {
     case ICMODE_FASTCOMPRESS:
     case ICMODE_COMPRESS:
-        info.querymsg = ICM_COMPRESS_QUERY;
+        msg = ICM_COMPRESS_QUERY;
         break;
     case ICMODE_FASTDECOMPRESS:
     case ICMODE_DECOMPRESS:
-        info.querymsg = ICM_DECOMPRESS_QUERY;
+        msg = ICM_DECOMPRESS_QUERY;
         break;
     case ICMODE_DRAW:
-        info.querymsg = ICM_DRAW_QUERY;
+        msg = ICM_DRAW_QUERY;
         break;
     default:
-        WARN("Unknown mode (%d)\n", wMode);
+        FIXME("Unhandled mode %#x.\n", mode);
         return 0;
     }
 
-    /* Easy case: handler/type match, we just fire a query and return */
-    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? */
-    if (!info.hic) enum_drivers(fccType, ICLocate_enum_handler, &info);
+    if ((hic = ICOpen(type, handler, mode)))
+    {
+        if (!ICSendMessage(hic, msg, (DWORD_PTR)in, (DWORD_PTR)out))
+        {
+            TRACE("Found codec %s.%s.\n", wine_dbgstr_fcc(type),
+                    wine_dbgstr_fcc(handler));
+            return hic;
+        }
+        ICClose(hic);
+    }
 
-    if (info.hic) 
+    for (i = 0; ICInfo(type, i, &info); ++i)
     {
-        TRACE("=> %p\n", info.hic);
-       return info.hic;
+        if ((hic = ICOpen(info.fccType, info.fccHandler, mode)))
+        {
+            if (!ICSendMessage(hic, msg, (DWORD_PTR)in, (DWORD_PTR)out))
+            {
+                TRACE("Found codec %s.%s.\n", wine_dbgstr_fcc(info.fccType),
+                        wine_dbgstr_fcc(info.fccHandler));
+                return hic;
+            }
+            ICClose(hic);
+        }
     }
 
-    if (fccType == streamtypeVIDEO) 
-        return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode);
-    
-    ERR("Required media codec '%s %s' not found!\n",
-         wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler));
+    if (type == streamtypeVIDEO)
+        return ICLocate(ICTYPE_VIDEO, handler, in, out, mode);
+
+    WARN("Could not find a driver for codec %s.%s.\n",
+            wine_dbgstr_fcc(type), wine_dbgstr_fcc(handler));
+
     return 0;
 }
 
@@ -925,7 +898,7 @@ static BOOL enum_compressors(HWND list, COMPVARS *pcv, BOOL enum_all)
 
             idx = SendMessageW(list, CB_ADDSTRING, 0, (LPARAM)icinfo.szDescription);
 
-            ic = HeapAlloc(GetProcessHeap(), 0, sizeof(struct codec_info));
+            ic = heap_alloc(sizeof(*ic));
             ic->icinfo = icinfo;
             ic->hic = hic;
             SendMessageW(list, CB_SETITEMDATA, idx, (LPARAM)ic);
@@ -978,7 +951,7 @@ static INT_PTR CALLBACK icm_choose_compressor_dlgproc(HWND hdlg, UINT msg, WPARA
         LoadStringW(MSVFW32_hModule, IDS_FULLFRAMES, buf, 128);
         SendDlgItemMessageW(hdlg, IDC_COMP_LIST, CB_ADDSTRING, 0, (LPARAM)buf);
 
-        ic = HeapAlloc(GetProcessHeap(), 0, sizeof(struct codec_info));
+        ic = heap_alloc(sizeof(*ic));
         ic->icinfo.fccType = streamtypeVIDEO;
         ic->icinfo.fccHandler = comptypeDIB;
         ic->hic = 0;
@@ -1099,7 +1072,7 @@ static INT_PTR CALLBACK icm_choose_compressor_dlgproc(HWND hdlg, UINT msg, WPARA
                 if (!ic || (LONG_PTR)ic == CB_ERR) break;
 
                 if (ic->hic) ICClose(ic->hic);
-                HeapFree(GetProcessHeap(), 0, ic);
+                heap_free(ic);
             }
 
             EndDialog(hdlg, LOWORD(wparam) == IDOK);
@@ -1171,23 +1144,25 @@ BOOL VFWAPI ICCompressorChoose(HWND hwnd, UINT uiFlags, LPVOID pvIn,
  */
 void VFWAPI ICCompressorFree(PCOMPVARS pc)
 {
-  TRACE("(%p)\n",pc);
+    TRACE("(%p)\n", pc);
 
-  if (pc != NULL && pc->cbSize == sizeof(COMPVARS)) {
-    if (pc->hic != NULL) {
-      ICClose(pc->hic);
-      pc->hic = NULL;
+    if (pc && pc->cbSize == sizeof(COMPVARS))
+    {
+        if (pc->hic)
+        {
+            ICClose(pc->hic);
+            pc->hic = NULL;
+        }
+        heap_free(pc->lpbiIn);
+        pc->lpbiIn = NULL;
+        heap_free(pc->lpBitsOut);
+        pc->lpBitsOut = NULL;
+        heap_free(pc->lpBitsPrev);
+        pc->lpBitsPrev = NULL;
+        heap_free(pc->lpState);
+        pc->lpState = NULL;
+        pc->dwFlags = 0;
     }
-    HeapFree(GetProcessHeap(), 0, pc->lpbiIn);
-    pc->lpbiIn = NULL;
-    HeapFree(GetProcessHeap(), 0, pc->lpBitsOut);
-    pc->lpBitsOut = NULL;
-    HeapFree(GetProcessHeap(), 0, pc->lpBitsPrev);
-    pc->lpBitsPrev = NULL;
-    HeapFree(GetProcessHeap(), 0, pc->lpState);
-    pc->lpState = NULL;
-    pc->dwFlags = 0;
-  }
 }
 
 /***********************************************************************
@@ -1297,7 +1272,7 @@ LRESULT WINAPI ICClose(HIC hic)
         }
     }
 
-    HeapFree(GetProcessHeap(), 0, whic);
+    heap_free(whic);
     return 0;
 }
 
@@ -1382,8 +1357,7 @@ HANDLE VFWAPI ICImageDecompress(
                cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
                if ( cbHdr < sizeof(BITMAPINFOHEADER) )
                        goto err;
-               pHdr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,cbHdr+sizeof(RGBQUAD)*256);
-               if ( pHdr == NULL )
+               if (!(pHdr = heap_alloc_zero(cbHdr + sizeof(RGBQUAD) * 256)))
                        goto err;
                if ( ICDecompressGetFormat( hic, lpbiIn, pHdr ) != ICERR_OK )
                        goto err;
@@ -1438,7 +1412,7 @@ err:
                ICDecompressEnd( hic );
        if ( bReleaseIC )
                ICClose(hic);
-        HeapFree(GetProcessHeap(),0,pHdr);
+        heap_free(pHdr);
        if ( pMem != NULL )
                GlobalUnlock( hMem );
        if ( !bSucceeded && hMem != NULL )
@@ -1509,14 +1483,14 @@ LPVOID VFWAPI ICSeqCompressFrame(PCOMPVARS pc, UINT uiFlags, LPVOID lpBits, BOOL
 
 static void clear_compvars(PCOMPVARS pc)
 {
-    HeapFree(GetProcessHeap(), 0, pc->lpbiIn);
-    HeapFree(GetProcessHeap(), 0, pc->lpBitsPrev);
-    HeapFree(GetProcessHeap(), 0, pc->lpBitsOut);
-    HeapFree(GetProcessHeap(), 0, pc->lpState);
+    heap_free(pc->lpbiIn);
+    heap_free(pc->lpBitsPrev);
+    heap_free(pc->lpBitsOut);
+    heap_free(pc->lpState);
     pc->lpbiIn = pc->lpBitsPrev = pc->lpBitsOut = pc->lpState = NULL;
     if (pc->dwFlags & 0x80000000)
     {
-        HeapFree(GetProcessHeap(), 0, pc->lpbiOut);
+        heap_free(pc->lpbiOut);
         pc->lpbiOut = NULL;
         pc->dwFlags &= ~0x80000000;
     }
@@ -1532,6 +1506,28 @@ void VFWAPI ICSeqCompressFrameEnd(PCOMPVARS pc)
     clear_compvars(pc);
 }
 
+static BITMAPINFO *copy_bitmapinfo(const BITMAPINFO *src)
+{
+    int num_colors;
+    unsigned int size;
+    BITMAPINFO *dst;
+
+    if (src->bmiHeader.biClrUsed)
+        num_colors = min(src->bmiHeader.biClrUsed, 256);
+    else
+        num_colors = src->bmiHeader.biBitCount > 8 ? 0 : 1 << src->bmiHeader.biBitCount;
+
+    size = FIELD_OFFSET(BITMAPINFO, bmiColors[num_colors]);
+    if (src->bmiHeader.biCompression == BI_BITFIELDS)
+        size += 3 * sizeof(DWORD);
+
+    if (!(dst = heap_alloc(size)))
+        return NULL;
+
+    memcpy(dst, src, size);
+    return dst;
+}
+
 /***********************************************************************
  *      ICSeqCompressFrameStart [MSVFW32.@]
  */
@@ -1542,15 +1538,11 @@ BOOL VFWAPI ICSeqCompressFrameStart(PCOMPVARS pc, LPBITMAPINFO lpbiIn)
      */
     DWORD ret;
     ICCOMPRESS* icComp;
-    pc->lpbiIn = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFO));
-    if (!pc->lpbiIn)
-        return FALSE;
 
-    *pc->lpbiIn = *lpbiIn;
+    if (!(pc->lpbiIn = copy_bitmapinfo(lpbiIn)))
+        return FALSE;
 
-    pc->lpState = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS)
-                            + sizeof(*icComp->lpckid) + sizeof(*icComp->lpdwFlags));
-    if (!pc->lpState)
+    if (!(pc->lpState = heap_alloc(sizeof(ICCOMPRESS) + sizeof(*icComp->lpckid) + sizeof(*icComp->lpdwFlags))))
         goto error;
 
     pc->cbState = sizeof(ICCOMPRESS);
@@ -1563,8 +1555,7 @@ BOOL VFWAPI ICSeqCompressFrameStart(PCOMPVARS pc, LPBITMAPINFO lpbiIn)
         if (size <= 0)
             goto error;
 
-        pc->lpbiOut = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
-        if (!pc->lpbiOut)
+        if (!(pc->lpbiOut = heap_alloc_zero(size)))
             goto error;
         /* Flag to show that we allocated lpbiOut for proper cleanup */
         pc->dwFlags |= 0x80000000;
@@ -1600,13 +1591,11 @@ BOOL VFWAPI ICSeqCompressFrameStart(PCOMPVARS pc, LPBITMAPINFO lpbiIn)
           pc->lpbiOut->bmiHeader.biSizeImage);
 
     /* Buffer for compressed frame data */
-    pc->lpBitsOut = HeapAlloc(GetProcessHeap(), 0, pc->lpbiOut->bmiHeader.biSizeImage);
-    if (!pc->lpBitsOut)
+    if (!(pc->lpBitsOut = heap_alloc(pc->lpbiOut->bmiHeader.biSizeImage)))
         goto error;
 
     /* Buffer for previous compressed frame data */
-    pc->lpBitsPrev = HeapAlloc(GetProcessHeap(), 0, pc->lpbiOut->bmiHeader.biSizeImage);
-    if (!pc->lpBitsPrev)
+    if (!(pc->lpBitsPrev = heap_alloc(pc->lpbiOut->bmiHeader.biSizeImage)))
         goto error;
 
     TRACE("Compvars:\n"
index fa02e2c..3e2c2f7 100644 (file)
@@ -126,7 +126,7 @@ dll/win32/mssip32             # Synced to WineStaging-4.18
 dll/win32/mstask              # Synced to WineStaging-3.3
 dll/win32/msvcrt20            # Out of sync
 dll/win32/msvcrt40            # Out of sync
-dll/win32/msvfw32             # Synced to WineStaging-4.0
+dll/win32/msvfw32             # Synced to WineStaging-4.18
 dll/win32/msvidc32            # Synced to WineStaging-4.0
 dll/win32/msxml               # Synced to WineStaging-3.3
 dll/win32/msxml2              # Synced to WineStaging-3.3