For ShellExecuteExA we need to copy out the hProcess value from the W
[wine] / dlls / msacm / format.c
index 2bc0ce2..fa20995 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <stdarg.h>
 #include <string.h>
+#include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
 #include "winerror.h"
-#include "windef.h"
 #include "wingdi.h"
 #include "winuser.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
 #include "mmsystem.h"
+#include "mmreg.h"
 #include "msacm.h"
 #include "msacmdrv.h"
 #include "wineacm.h"
@@ -50,7 +52,7 @@ struct MSACM_FillFormatData {
     DWORD              ret;
 };
 
-static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid, 
+static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
                                            PACMFORMATTAGDETAILSA paftd,
                                            DWORD dwInstance, DWORD fdwSupport)
 {
@@ -58,10 +60,10 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
 
     switch (affd->mode) {
     case WINE_ACMFF_TAG:
-       if (SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 
-                               CB_FINDSTRINGEXACT, 
+       if (SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
+                               CB_FINDSTRINGEXACT,
                                (WPARAM)-1, (LPARAM)paftd->szFormatTag) == CB_ERR)
-           SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 
+           SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
                                CB_ADDSTRING, 0, (DWORD)paftd->szFormatTag);
        break;
     case WINE_ACMFF_FORMAT:
@@ -70,7 +72,7 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
 
            if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
                ACMFORMATDETAILSA       afd;
-               int                     i, idx;
+               unsigned int            i, idx;
                MMRESULT                mmr;
                char                    buffer[ACMFORMATDETAILS_FORMAT_CHARS+16];
 
@@ -87,22 +89,22 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
                    mmr = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
                    if (mmr == MMSYSERR_NOERROR) {
                        strncpy(buffer, afd.szFormat, ACMFORMATTAGDETAILS_FORMATTAG_CHARS);
-                       for (idx = strlen(buffer); 
+                       for (idx = strlen(buffer);
                             idx < ACMFORMATTAGDETAILS_FORMATTAG_CHARS; idx++)
                            buffer[idx] = ' ';
-                       wsprintfA(buffer + ACMFORMATTAGDETAILS_FORMATTAG_CHARS, 
-                                 "%d Ko/s", 
+                       wsprintfA(buffer + ACMFORMATTAGDETAILS_FORMATTAG_CHARS,
+                                 "%d Ko/s",
                                  (afd.pwfx->nAvgBytesPerSec + 512) / 1024);
-                       SendDlgItemMessageA(affd->hWnd, 
-                                           IDD_ACMFORMATCHOOSE_CMB_FORMAT, 
+                       SendDlgItemMessageA(affd->hWnd,
+                                           IDD_ACMFORMATCHOOSE_CMB_FORMAT,
                                            CB_ADDSTRING, 0, (DWORD)buffer);
                    }
                }
                acmDriverClose(had, 0);
-               SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, 
+               SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
                                    CB_SETCURSEL, 0, 0);
                HeapFree(MSACM_hHeap, 0, afd.pwfx);
-           } 
+           }
        }
        break;
     case WINE_ACMFF_WFX:
@@ -117,12 +119,12 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
                afd.pwfx = affd->afc->pwfx;
                afd.cbwfx = affd->afc->cbwfx;
 
-               afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, 
-                                                       CB_GETCURSEL, 0, 0);;
+               afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
+                                                       CB_GETCURSEL, 0, 0);
                affd->ret = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
                acmDriverClose(had, 0);
                return TRUE;
-           } 
+           }
        }
        break;
     default:
@@ -143,7 +145,7 @@ static BOOL MSACM_FillFormatTags(HWND hWnd)
     affd.hWnd = hWnd;
     affd.mode = WINE_ACMFF_TAG;
 
-    acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
+    acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
     SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, CB_SETCURSEL, 0, 0);
     return TRUE;
 }
@@ -160,13 +162,13 @@ static BOOL MSACM_FillFormat(HWND hWnd)
 
     affd.hWnd = hWnd;
     affd.mode = WINE_ACMFF_FORMAT;
-    SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 
+    SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
                        CB_GETLBTEXT,
-                       SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 
+                       SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
                                            CB_GETCURSEL, 0, 0),
                        (DWORD)affd.szFormatTag);
-    
-    acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
+
+    acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
     SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_SETCURSEL, 0, 0);
     return TRUE;
 }
@@ -183,22 +185,22 @@ static MMRESULT MSACM_GetWFX(HWND hWnd, PACMFORMATCHOOSEA afc)
     affd.mode = WINE_ACMFF_WFX;
     affd.afc = afc;
     affd.ret = MMSYSERR_NOERROR;
-    SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 
+    SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
                        CB_GETLBTEXT,
-                       SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 
+                       SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
                                            CB_GETCURSEL, 0, 0),
                        (DWORD)affd.szFormatTag);
 
-    acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
+    acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
     return affd.ret;
 }
 
-static BOOL WINAPI FormatChooseDlgProc(HWND hWnd, UINT msg, 
+static INT_PTR CALLBACK FormatChooseDlgProc(HWND hWnd, UINT msg,
                                       WPARAM wParam, LPARAM lParam)
 {
-    
-    TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd,  msg, wParam, lParam );
-    
+
+    TRACE("hwnd=%p msg=%i 0x%08x 0x%08lx\n", hWnd,  msg, wParam, lParam );
+
     switch (msg) {
     case WM_INITDIALOG:
        afc = (PACMFORMATCHOOSEA)lParam;
@@ -210,7 +212,7 @@ static BOOL WINAPI FormatChooseDlgProc(HWND hWnd, UINT msg,
        if (!(afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP))
            ShowWindow(GetDlgItem(hWnd, IDD_ACMFORMATCHOOSE_BTN_HELP), SW_HIDE);
        return TRUE;
-       
+
     case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
@@ -225,39 +227,39 @@ static BOOL WINAPI FormatChooseDlgProc(HWND hWnd, UINT msg,
                MSACM_FillFormat(hWnd);
                break;
            default:
-               TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n", 
+               TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
                      HIWORD(wParam), lParam);
                break;
            }
            break;
        case IDD_ACMFORMATCHOOSE_BTN_HELP:
            if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP)
-               SendMessageA(afc->hwndOwner, 
+               SendMessageA(afc->hwndOwner,
                             RegisterWindowMessageA(ACMHELPMSGSTRINGA), 0L, 0L);
            break;
-           
+
        default:
-           TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n", 
+           TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
                  LOWORD(wParam), HIWORD(wParam), lParam);
            break;
        }
        break;
     case WM_CONTEXTMENU:
        if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
-           SendMessageA(afc->hwndOwner, 
-                        RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA), 
+           SendMessageA(afc->hwndOwner,
+                        RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA),
                         wParam, lParam);
        break;
 #if defined(WM_CONTEXTHELP)
     case WM_CONTEXTHELP:
        if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
-           SendMessageA(afc->hwndOwner, 
-                        RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA), 
+           SendMessageA(afc->hwndOwner,
+                        RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA),
                         wParam, lParam);
        break;
-#endif       
+#endif
     default:
-       TRACE("Dropped dlgMsg: hwnd=%i msg=%i 0x%08x 0x%08lx\n", 
+       TRACE("Dropped dlgMsg: hwnd=%p msg=%i 0x%08x 0x%08lx\n",
              hWnd,  msg, wParam, lParam );
        break;
     }
@@ -286,7 +288,7 @@ MMRESULT WINAPI acmFormatChooseW(PACMFORMATCHOOSEW pafmtc)
 /***********************************************************************
  *           acmFormatDetailsA (MSACM32.@)
  */
-MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd, 
+MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
                                  DWORD fdwDetails)
 {
     ACMFORMATDETAILSW  afdw;
@@ -295,14 +297,14 @@ MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
     memset(&afdw, 0, sizeof(afdw));
     afdw.cbStruct = sizeof(afdw);
     afdw.dwFormatIndex = pafd->dwFormatIndex;
-    afdw.dwFormatTag = pafd->dwFormatTag; 
-    afdw.pwfx = pafd->pwfx; 
-    afdw.cbwfx = pafd->cbwfx; 
+    afdw.dwFormatTag = pafd->dwFormatTag;
+    afdw.pwfx = pafd->pwfx;
+    afdw.cbwfx = pafd->cbwfx;
 
     mmr = acmFormatDetailsW(had, &afdw, fdwDetails);
     if (mmr == MMSYSERR_NOERROR) {
-       pafd->dwFormatTag = afdw.dwFormatTag; 
-       pafd->fdwSupport = afdw.fdwSupport; 
+       pafd->dwFormatTag = afdw.dwFormatTag;
+       pafd->fdwSupport = afdw.fdwSupport;
         WideCharToMultiByte( CP_ACP, 0, afdw.szFormat, -1,
                              pafd->szFormat, sizeof(pafd->szFormat), NULL, NULL );
     }
@@ -315,36 +317,36 @@ MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
 MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails)
 {
     MMRESULT                   mmr;
-    static WCHAR               fmt1[] = {'%','d',' ','H','z',0};
-    static WCHAR               fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};
+    static const WCHAR         fmt1[] = {'%','d',' ','H','z',0};
+    static const WCHAR         fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};
     ACMFORMATTAGDETAILSA       aftd;
 
-    TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
+    TRACE("(%p, %p, %ld)\n", had, pafd, fdwDetails);
 
     memset(&aftd, 0, sizeof(aftd));
     aftd.cbStruct = sizeof(aftd);
 
     if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
-       
+
     switch (fdwDetails) {
     case ACM_FORMATDETAILSF_FORMAT:
        if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) {
            mmr = MMSYSERR_INVALPARAM;
            break;
        }
-       if (had == (HACMDRIVER)NULL) {
+       if (had == NULL) {
            PWINE_ACMDRIVERID           padid;
 
            mmr = ACMERR_NOTPOSSIBLE;
            for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
                /* should check for codec only */
-               if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 
+               if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
                    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
                    mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
                    acmDriverClose(had, 0);
                    if (mmr == MMSYSERR_NOERROR) break;
                }
-           }               
+           }
        } else {
            mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
        }
@@ -362,7 +364,7 @@ MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD
     if (mmr == MMSYSERR_NOERROR && pafd->szFormat[0] == (WCHAR)0) {
        wsprintfW(pafd->szFormat, fmt1, pafd->pwfx->nSamplesPerSec);
        if (pafd->pwfx->wBitsPerSample) {
-           wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2, 
+           wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2,
                      pafd->pwfx->wBitsPerSample);
        }
         MultiByteToWideChar( CP_ACP, 0, (pafd->pwfx->nChannels == 1) ? "; Mono" : "; Stereo", -1,
@@ -381,21 +383,21 @@ struct MSACM_FormatEnumWtoA_Instance {
 };
 
 static BOOL CALLBACK MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid,
-                                                 PACMFORMATDETAILSW pafdw,  
-                                                 DWORD dwInstance,             
+                                                 PACMFORMATDETAILSW pafdw,
+                                                 DWORD dwInstance,
                                                  DWORD fdwSupport)
 {
     struct MSACM_FormatEnumWtoA_Instance* pafei;
 
     pafei = (struct MSACM_FormatEnumWtoA_Instance*)dwInstance;
 
-    pafei->pafda->dwFormatIndex = pafdw->dwFormatIndex; 
-    pafei->pafda->dwFormatTag = pafdw->dwFormatTag; 
-    pafei->pafda->fdwSupport = pafdw->fdwSupport; 
+    pafei->pafda->dwFormatIndex = pafdw->dwFormatIndex;
+    pafei->pafda->dwFormatTag = pafdw->dwFormatTag;
+    pafei->pafda->fdwSupport = pafdw->fdwSupport;
     WideCharToMultiByte( CP_ACP, 0, pafdw->szFormat, -1,
                          pafei->pafda->szFormat, sizeof(pafei->pafda->szFormat), NULL, NULL );
 
-    return (pafei->fnCallback)(hadid, pafei->pafda, 
+    return (pafei->fnCallback)(hadid, pafei->pafda,
                               pafei->dwInstance, fdwSupport);
 }
 
@@ -403,12 +405,18 @@ static BOOL CALLBACK MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid,
  *           acmFormatEnumA (MSACM32.@)
  */
 MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda,
-                              ACMFORMATENUMCBA fnCallback, DWORD dwInstance, 
+                              ACMFORMATENUMCBA fnCallback, DWORD dwInstance,
                               DWORD fdwEnum)
 {
     ACMFORMATDETAILSW          afdw;
     struct MSACM_FormatEnumWtoA_Instance afei;
 
+    if (!pafda)
+        return MMSYSERR_INVALPARAM;
+
+    if (pafda->cbStruct < sizeof(*pafda))
+        return MMSYSERR_INVALPARAM;
+
     memset(&afdw, 0, sizeof(afdw));
     afdw.cbStruct = sizeof(afdw);
     afdw.dwFormatIndex = pafda->dwFormatIndex;
@@ -420,20 +428,20 @@ MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda,
     afei.dwInstance = dwInstance;
     afei.fnCallback = fnCallback;
 
-    return acmFormatEnumW(had, &afdw, MSACM_FormatEnumCallbackWtoA, 
+    return acmFormatEnumW(had, &afdw, MSACM_FormatEnumCallbackWtoA,
                          (DWORD)&afei, fdwEnum);
 }
 
 /***********************************************************************
  *           acmFormatEnumW (MSACM32.@)
  */
-static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, 
-                                  PACMFORMATDETAILSW pafd, PWAVEFORMATEX pwfxRef, 
-                                  ACMFORMATENUMCBW fnCallback, DWORD dwInstance,  
+static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
+                                  PACMFORMATDETAILSW pafd, PWAVEFORMATEX pwfxRef,
+                                  ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
                                   DWORD fdwEnum)
 {
     ACMFORMATTAGDETAILSW       aftd;
-    int                                i, j;
+    unsigned int                       i, j;
 
     for (i = 0; i < padid->cFormatTags; i++) {
        memset(&aftd, 0, sizeof(aftd));
@@ -441,33 +449,33 @@ static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
        aftd.dwFormatTagIndex = i;
        if (acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
            continue;
-       
+
        if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && aftd.dwFormatTag != pwfxRef->wFormatTag)
            continue;
-       
+
        for (j = 0; j < aftd.cStandardFormats; j++) {
            pafd->dwFormatIndex = j;
            pafd->dwFormatTag = aftd.dwFormatTag;
-           if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR) 
+           if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR)
                continue;
-           
-           if ((fdwEnum & ACM_FORMATENUMF_NCHANNELS) && 
+
+           if ((fdwEnum & ACM_FORMATENUMF_NCHANNELS) &&
                pafd->pwfx->nChannels != pwfxRef->nChannels)
                continue;
-           if ((fdwEnum & ACM_FORMATENUMF_NSAMPLESPERSEC) && 
+           if ((fdwEnum & ACM_FORMATENUMF_NSAMPLESPERSEC) &&
                pafd->pwfx->nSamplesPerSec != pwfxRef->nSamplesPerSec)
                continue;
-           if ((fdwEnum & ACM_FORMATENUMF_WBITSPERSAMPLE) && 
+           if ((fdwEnum & ACM_FORMATENUMF_WBITSPERSAMPLE) &&
                pafd->pwfx->wBitsPerSample != pwfxRef->wBitsPerSample)
                continue;
            if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
                !(pafd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_HARDWARE))
                continue;
-           
+
            /* more checks to be done on fdwEnum */
 
            if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
-               return FALSE; 
+               return FALSE;
        }
        /* the "formats" used by the filters are also reported */
     }
@@ -477,24 +485,28 @@ static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
 /**********************************************************************/
 
 MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
-                              ACMFORMATENUMCBW fnCallback, DWORD dwInstance,  
+                              ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
                               DWORD fdwEnum)
 {
     PWINE_ACMDRIVERID          padid;
     WAVEFORMATEX               wfxRef;
     BOOL                       ret;
 
-    TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
+    TRACE("(%p, %p, %p, %ld, %ld)\n",
          had, pafd, fnCallback, dwInstance, fdwEnum);
 
-    if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
+    if (!pafd)
+        return MMSYSERR_INVALPARAM;
+
+    if (pafd->cbStruct < sizeof(*pafd))
+        return MMSYSERR_INVALPARAM;
 
     if (fdwEnum & (ACM_FORMATENUMF_WFORMATTAG|ACM_FORMATENUMF_NCHANNELS|
                   ACM_FORMATENUMF_NSAMPLESPERSEC|ACM_FORMATENUMF_WBITSPERSAMPLE|
                   ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST))
         wfxRef = *pafd->pwfx;
 
-    if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) && 
+    if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
        !(fdwEnum & (ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT)))
        return MMSYSERR_INVALPARAM;
 
@@ -511,16 +523,16 @@ MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
 
        if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
            return MMSYSERR_INVALHANDLE;
-       MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef, 
+       MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef,
                               fnCallback, dwInstance, fdwEnum);
        return MMSYSERR_NOERROR;
     }
     for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
            /* should check for codec only */
-           if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) || 
+           if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
                acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
                continue;
-           ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef, 
+           ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef,
                                         fnCallback, dwInstance, fdwEnum);
            acmDriverClose(had, 0);
            if (!ret) break;
@@ -531,13 +543,13 @@ MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
 /***********************************************************************
  *           acmFormatSuggest (MSACM32.@)
  */
-MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc, 
+MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
                                 PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
 {
     ACMDRVFORMATSUGGEST        adfg;
     MMRESULT           mmr;
 
-    TRACE("(0x%08x, %p, %p, %ld, %ld)\n", 
+    TRACE("(%p, %p, %p, %ld, %ld)\n",
          had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest);
 
     if (fdwSuggest & ~(ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_NSAMPLESPERSEC|
@@ -548,14 +560,14 @@ MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
     adfg.fdwSuggest = fdwSuggest;
     adfg.pwfxSrc = pwfxSrc;
     adfg.cbwfxSrc = (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) ?
-       sizeof(WAVEFORMATEX) : pwfxSrc->cbSize;
+       sizeof(WAVEFORMATEX) : (sizeof(WAVEFORMATEX) + pwfxSrc->cbSize);
     adfg.pwfxDst = pwfxDst;
     adfg.cbwfxDst = cbwfxDst;
 
-    if (had == (HACMDRIVER)NULL) {
+    if (had == NULL) {
        PWINE_ACMDRIVERID       padid;
-       
-       /* MS doc says: ACM finds the best suggestion. 
+
+       /* MS doc says: ACM finds the best suggestion.
         * Well, first found will be the "best"
         */
        mmr = ACMERR_NOTPOSSIBLE;
@@ -564,7 +576,7 @@ MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
            if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
                acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
                continue;
-           
+
            if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) {
                mmr = MMSYSERR_NOERROR;
                break;
@@ -580,7 +592,7 @@ MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
 /***********************************************************************
  *           acmFormatTagDetailsA (MSACM32.@)
  */
-MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda, 
+MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
                                     DWORD fdwDetails)
 {
     ACMFORMATTAGDETAILSW       aftdw;
@@ -593,11 +605,11 @@ MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftd
 
     mmr = acmFormatTagDetailsW(had, &aftdw, fdwDetails);
     if (mmr == MMSYSERR_NOERROR) {
-       paftda->dwFormatTag = aftdw.dwFormatTag; 
+       paftda->dwFormatTag = aftdw.dwFormatTag;
        paftda->dwFormatTagIndex = aftdw.dwFormatTagIndex;
-       paftda->cbFormatSize = aftdw.cbFormatSize; 
-       paftda->fdwSupport = aftdw.fdwSupport; 
-       paftda->cStandardFormats = aftdw.cStandardFormats; 
+       paftda->cbFormatSize = aftdw.cbFormatSize;
+       paftda->fdwSupport = aftdw.fdwSupport;
+       paftda->cStandardFormats = aftdw.cStandardFormats;
         WideCharToMultiByte( CP_ACP, 0, aftdw.szFormatTag, -1, paftda->szFormatTag,
                              sizeof(paftda->szFormatTag), NULL, NULL );
     }
@@ -607,13 +619,13 @@ MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftd
 /***********************************************************************
  *           acmFormatTagDetailsW (MSACM32.@)
  */
-MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, 
+MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
                                     DWORD fdwDetails)
 {
     PWINE_ACMDRIVERID  padid;
     MMRESULT           mmr = ACMERR_NOTPOSSIBLE;
 
-    TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
+    TRACE("(%p, %p, %ld)\n", had, paftd, fdwDetails);
 
     if (fdwDetails & ~(ACM_FORMATTAGDETAILSF_FORMATTAG|ACM_FORMATTAGDETAILSF_INDEX|
                       ACM_FORMATTAGDETAILSF_LARGESTSIZE))
@@ -621,10 +633,10 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd
 
     switch (fdwDetails) {
     case ACM_FORMATTAGDETAILSF_FORMATTAG:
-       if (had == (HACMDRIVER)NULL) {
+       if (had == NULL) {
            for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
                /* should check for codec only */
-               if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 
+               if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
                    MSACM_FindFormatTagInCache(padid, paftd->dwFormatTag, NULL) &&
                    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
                    mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
@@ -634,42 +646,42 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd
            }
        } else {
            PWINE_ACMDRIVER     pad = MSACM_GetDriver(had);
-           
+
            if (pad && MSACM_FindFormatTagInCache(pad->obj.pACMDriverID, paftd->dwFormatTag, NULL))
                mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
        }
        break;
 
     case ACM_FORMATTAGDETAILSF_INDEX:
-       if (had != (HACMDRIVER)NULL) {
+       if (had != NULL) {
            PWINE_ACMDRIVER     pad = MSACM_GetDriver(had);
-           
+
            if (pad && paftd->dwFormatTagIndex < pad->obj.pACMDriverID->cFormatTags)
                mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
-       } 
+       }
        break;
 
     case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
-       if (had == (HACMDRIVER)NULL) {
+       if (had == NULL) {
            ACMFORMATTAGDETAILSW        tmp;
            DWORD                       ft = paftd->dwFormatTag;
 
            for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
                /* should check for codec only */
-               if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 
+               if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
                    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
 
                    memset(&tmp, 0, sizeof(tmp));
                    tmp.cbStruct = sizeof(tmp);
                    tmp.dwFormatTag = ft;
 
-                   if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, 
+                   if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
                                      (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
                        if (mmr == ACMERR_NOTPOSSIBLE ||
                            paftd->cbFormatSize < tmp.cbFormatSize) {
                            *paftd = tmp;
                            mmr = MMSYSERR_NOERROR;
-                       } 
+                       }
                    }
                    acmDriverClose(had, 0);
                }
@@ -684,7 +696,7 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd
        mmr = MMSYSERR_ERROR;
     }
 
-    if (mmr == MMSYSERR_NOERROR && 
+    if (mmr == MMSYSERR_NOERROR &&
        paftd->dwFormatTag == WAVE_FORMAT_PCM && paftd->szFormatTag[0] == 0)
         MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
                              sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
@@ -699,23 +711,23 @@ struct MSACM_FormatTagEnumWtoA_Instance {
 };
 
 static BOOL CALLBACK MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid,
-                                                    PACMFORMATTAGDETAILSW paftdw,  
-                                                    DWORD dwInstance,             
+                                                    PACMFORMATTAGDETAILSW paftdw,
+                                                    DWORD dwInstance,
                                                     DWORD fdwSupport)
 {
     struct MSACM_FormatTagEnumWtoA_Instance* paftei;
 
     paftei = (struct MSACM_FormatTagEnumWtoA_Instance*)dwInstance;
 
-    paftei->paftda->dwFormatTagIndex = paftdw->dwFormatTagIndex; 
-    paftei->paftda->dwFormatTag = paftdw->dwFormatTag; 
-    paftei->paftda->cbFormatSize = paftdw->cbFormatSize; 
-    paftei->paftda->fdwSupport = paftdw->fdwSupport; 
-    paftei->paftda->cStandardFormats = paftdw->cStandardFormats; 
+    paftei->paftda->dwFormatTagIndex = paftdw->dwFormatTagIndex;
+    paftei->paftda->dwFormatTag = paftdw->dwFormatTag;
+    paftei->paftda->cbFormatSize = paftdw->cbFormatSize;
+    paftei->paftda->fdwSupport = paftdw->fdwSupport;
+    paftei->paftda->cStandardFormats = paftdw->cStandardFormats;
     WideCharToMultiByte( CP_ACP, 0, paftdw->szFormatTag, -1, paftei->paftda->szFormatTag,
                          sizeof(paftei->paftda->szFormatTag), NULL, NULL );
 
-    return (paftei->fnCallback)(hadid, paftei->paftda, 
+    return (paftei->fnCallback)(hadid, paftei->paftda,
                                paftei->dwInstance, fdwSupport);
 }
 
@@ -723,12 +735,21 @@ static BOOL CALLBACK MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid,
  *           acmFormatTagEnumA (MSACM32.@)
  */
 MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
-                                 ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, 
+                                 ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance,
                                  DWORD fdwEnum)
 {
     ACMFORMATTAGDETAILSW       aftdw;
     struct MSACM_FormatTagEnumWtoA_Instance aftei;
 
+    if (!paftda)
+        return MMSYSERR_INVALPARAM;
+
+    if (paftda->cbStruct < sizeof(*paftda))
+        return MMSYSERR_INVALPARAM;
+
+    if (fdwEnum != 0)
+        return MMSYSERR_INVALFLAG;
+
     memset(&aftdw, 0, sizeof(aftdw));
     aftdw.cbStruct = sizeof(aftdw);
     aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
@@ -738,7 +759,7 @@ MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
     aftei.dwInstance = dwInstance;
     aftei.fnCallback = fnCallback;
 
-    return acmFormatTagEnumW(had, &aftdw, MSACM_FormatTagEnumCallbackWtoA, 
+    return acmFormatTagEnumW(had, &aftdw, MSACM_FormatTagEnumCallbackWtoA,
                             (DWORD)&aftei, fdwEnum);
 }
 
@@ -746,48 +767,92 @@ MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
  *           acmFormatTagEnumW (MSACM32.@)
  */
 MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
-                                 ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, 
+                                 ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance,
                                  DWORD fdwEnum)
 {
     PWINE_ACMDRIVERID          padid;
-    int                                i;
+    unsigned int                       i;
     BOOL                       bPcmDone = FALSE;
 
-    TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
-         had, paftd, fnCallback, dwInstance, fdwEnum); 
+    TRACE("(%p, %p, %p, %ld, %ld)\n",
+         had, paftd, fnCallback, dwInstance, fdwEnum);
 
-    if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
+    if (!paftd)
+        return MMSYSERR_INVALPARAM;
 
-    if (had) FIXME("had != NULL, not supported\n");
-    
-    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
-       /* should check for codec only */
-       if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 
-           acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
-           for (i = 0; i < padid->cFormatTags; i++) {
-               paftd->dwFormatTagIndex = i;
-               if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
-                                 (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
-                   if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
-                       if (paftd->szFormatTag[0] == 0)
-                           MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
-                                                sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
-                       /* FIXME (EPP): I'm not sure this is the correct 
-                        * algorithm (should make more sense to apply the same
-                        * for all already loaded formats, but this will do 
-                        * for now
-                        */
-                       if (bPcmDone) continue;
-                       bPcmDone = TRUE;
-                   }
-                   if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
-                       padid = NULL; /* to exist the two nested for loops */
-                       break;
-                   }
-               }
-           }
-       }
-       acmDriverClose(had, 0);
+    if (paftd->cbStruct < sizeof(*paftd))
+        return MMSYSERR_INVALPARAM;
+
+    if (fdwEnum != 0)
+        return MMSYSERR_INVALFLAG;
+
+    /* (WS) MSDN info page says that if had != 0, then we should find
+     * the specific driver to get its tags from. Therefore I'm removing
+     * the FIXME call and adding a search block below. It also seems
+     * that the lack of this functionality was the responsible for 
+     * codecs to be multiply and incorrectly listed. 
+     */
+
+    /* if (had) FIXME("had != NULL, not supported\n"); */
+
+    if (had) {
+
+       if (acmDriverID((HACMOBJ)had, (HACMDRIVERID *)&padid, 0) != MMSYSERR_NOERROR)
+          return MMSYSERR_INVALHANDLE;
+
+       for (i = 0; i < padid->cFormatTags; i++) {
+         paftd->dwFormatTagIndex = i;
+         if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
+         (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
+            if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
+               if (paftd->szFormatTag[0] == 0)
+                  MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
+                        sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
+               /* (WS) I'm preserving this PCM hack since it seems to be
+                * correct. Please notice this block was borrowed from
+                * below.
+                */
+               if (bPcmDone) continue;
+                  bPcmDone = TRUE;
+            }
+            if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) 
+                return MMSYSERR_NOERROR;
+         }
+       }
+
+    }
+
+    /* if had==0 then search for the first suitable driver */
+    else {
+       for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
+          /* should check for codec only */
+          if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
+            acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
+            for (i = 0; i < padid->cFormatTags; i++) {
+               paftd->dwFormatTagIndex = i;
+               if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
+                  (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
+                  if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
+                     if (paftd->szFormatTag[0] == 0)
+                        MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
+                                sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
+                     /* FIXME (EPP): I'm not sure this is the correct
+                      * algorithm (should make more sense to apply the same
+                      * for all already loaded formats, but this will do
+                      * for now
+                      */
+                     if (bPcmDone) continue;
+                        bPcmDone = TRUE;
+                  }
+                  if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
+                      acmDriverClose(had, 0);
+                      return MMSYSERR_NOERROR;
+                  }
+               }
+            }
+          }
+          acmDriverClose(had, 0);
+       }
     }
     return MMSYSERR_NOERROR;
 }