https://git.reactos.org/?p=reactos.git;a=commitdiff;h=01f2426dcf11290fb1dfc388db47ec3e99cd6c07

commit 01f2426dcf11290fb1dfc388db47ec3e99cd6c07
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sat Dec 24 10:05:08 2022 +0200
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Wed Jan 4 10:32:28 2023 +0100

    [WINMM] Sync mci.c with wine
    
    Date: 2022-02-22
    Author: Eric Pouech
    Commit: "winmm: Enable compilation with long types."
    Hash 71189f62604c2cb8208c85372a0e027dd2b79055
---
 dll/win32/winmm/mci.c    | 858 ++++++++++++++++++++++++++++-------------------
 dll/win32/winmm/winemm.h |   7 +-
 2 files changed, 510 insertions(+), 355 deletions(-)

diff --git a/dll/win32/winmm/mci.c b/dll/win32/winmm/mci.c
index b5ee88de9cf..8a5f221e349 100644
--- a/dll/win32/winmm/mci.c
+++ b/dll/win32/winmm/mci.c
@@ -37,11 +37,24 @@
  * - command table handling isn't thread safe
  */
 
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "mmsystem.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "winreg.h"
+#include "wownt32.h"
+
+#include "digitalv.h"
 #include "winemm.h"
 
-#include <mmsystem.h>
-#include <wownt32.h>
-#include <digitalv.h>
+#include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mci);
 
@@ -49,12 +62,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mci);
 #define MCI_MAGIC 0x0001
 
 /* MCI settings */
-static const WCHAR wszHklmMci  [] = 
{'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','\\','M','C','I',0};
-static const WCHAR wszNull     [] = {0};
-static const WCHAR wszAll      [] = {'A','L','L',0};
-static const WCHAR wszMci      [] = {'M','C','I',0};
-static const WCHAR wszOpen     [] = {'o','p','e','n',0};
-static const WCHAR wszSystemIni[] = 
{'s','y','s','t','e','m','.','i','n','i',0};
+static const WCHAR wszHklmMci  [] = L"Software\\Microsoft\\Windows 
NT\\CurrentVersion\\MCI";
 
 static WINE_MCIDRIVER *MciDrivers;
 
@@ -64,7 +72,7 @@ static UINT MCI_SetCommandTable(HGLOBAL hMem, UINT uDevType);
 /* dup a string and uppercase it */
 static inline LPWSTR str_dup_upper( LPCWSTR str )
 {
-    INT len = (strlenW(str) + 1) * sizeof(WCHAR);
+    INT len = (lstrlenW(str) + 1) * sizeof(WCHAR);
     LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len );
     if (p)
     {
@@ -101,20 +109,12 @@ static UINT MCI_GetDriverFromString(LPCWSTR lpstrName)
     if (!lpstrName)
        return 0;
 
-    if (!strcmpiW(lpstrName, wszAll))
+    if (!wcsicmp(lpstrName, L"ALL"))
        return MCI_ALL_DEVICE_ID;
 
     EnterCriticalSection(&WINMM_cs);
     for (wmd = MciDrivers; wmd; wmd = wmd->lpNext) {
-       if (wmd->lpstrElementName && strcmpW(wmd->lpstrElementName, lpstrName) 
== 0) {
-           ret = wmd->wDeviceID;
-           break;
-       }
-       if (wmd->lpstrDeviceType && strcmpiW(wmd->lpstrDeviceType, lpstrName) 
== 0) {
-           ret = wmd->wDeviceID;
-           break;
-       }
-       if (wmd->lpstrAlias && strcmpiW(wmd->lpstrAlias, lpstrName) == 0) {
+       if (wmd->lpstrAlias && wcsicmp(wmd->lpstrAlias, lpstrName) == 0) {
            ret = wmd->wDeviceID;
            break;
        }
@@ -127,10 +127,8 @@ static UINT MCI_GetDriverFromString(LPCWSTR lpstrName)
 /**************************************************************************
  *                     MCI_MessageToString                     [internal]
  */
-const char* MCI_MessageToString(UINT wMsg)
+static const char* MCI_MessageToString(UINT wMsg)
 {
-    static char buffer[100];
-
 #define CASE(s) case (s): return #s
 
     switch (wMsg) {
@@ -171,6 +169,7 @@ const char* MCI_MessageToString(UINT wMsg)
        CASE(MCI_SAVE);
        CASE(MCI_SEEK);
        CASE(MCI_SET);
+       CASE(MCI_SOUND);
        CASE(MCI_SPIN);
        CASE(MCI_STATUS);
        CASE(MCI_STEP);
@@ -194,12 +193,11 @@ const char* MCI_MessageToString(UINT wMsg)
        CASE(MCI_RESTORE);
 #undef CASE
     default:
-       sprintf(buffer, "MCI_<<%04X>>", wMsg);
-       return buffer;
+        return wine_dbg_sprintf("MCI_<<%04X>>", wMsg);
     }
 }
 
-LPWSTR MCI_strdupAtoW( LPCSTR str )
+static LPWSTR MCI_strdupAtoW( LPCSTR str )
 {
     LPWSTR ret;
     INT len;
@@ -211,18 +209,6 @@ LPWSTR MCI_strdupAtoW( LPCSTR str )
     return ret;
 }
 
-LPSTR MCI_strdupWtoA( LPCWSTR str )
-{
-    LPSTR ret;
-    INT len;
-
-    if (!str) return NULL;
-    len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
-    ret = HeapAlloc( GetProcessHeap(), 0, len );
-    if (ret) WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
-    return ret;
-}
-
 static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
 {
     if (msg < DRV_RESERVED) return 0;
@@ -241,7 +227,6 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
     case MCI_STEP:
     case MCI_RECORD:
     case MCI_BREAK:
-    case MCI_SOUND:
     case MCI_STATUS:
     case MCI_CUE:
     case MCI_REALIZE:
@@ -256,24 +241,23 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
     case MCI_RESUME:
     case MCI_DELETE:
     case MCI_MONITOR:
-    case MCI_SETAUDIO:
     case MCI_SIGNAL:
-    case MCI_SETVIDEO:
-    case MCI_LIST:
+    case MCI_UNDO:
         return 0;
 
     case MCI_OPEN:
-        {
-            MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA*)*dwParam2;
-            MCI_OPEN_PARMSW *mci_openW;
+        {   /* MCI_ANIM_OPEN_PARMS is the largest known MCI_OPEN_PARMS
+             * structure, larger than MCI_WAVE_OPEN_PARMS */
+            MCI_ANIM_OPEN_PARMSA *mci_openA = (MCI_ANIM_OPEN_PARMSA*)*dwParam2;
+            MCI_ANIM_OPEN_PARMSW *mci_openW;
             DWORD_PTR *ptr;
 
-            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD_PTR) + 
sizeof(*mci_openW) + 2 * sizeof(DWORD));
+            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD_PTR) + 
sizeof(*mci_openW));
             if (!ptr) return -1;
 
             *ptr++ = *dwParam2; /* save the previous pointer */
             *dwParam2 = (DWORD_PTR)ptr;
-            mci_openW = (MCI_OPEN_PARMSW *)ptr;
+            mci_openW = (MCI_ANIM_OPEN_PARMSW *)ptr;
 
             if (dwParam1 & MCI_NOTIFY)
                 mci_openW->dwCallback = mci_openA->dwCallback;
@@ -294,11 +278,10 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
             }
             if (dwParam1 & MCI_OPEN_ALIAS)
                 mci_openW->lpstrAlias = MCI_strdupAtoW(mci_openA->lpstrAlias);
-            /* FIXME: this is only needed for specific types of MCI devices, 
and
-             * may cause a segfault if the two DWORD:s don't exist at the end 
of 
-             * mci_openA
-             */
-            memcpy(mci_openW + 1, mci_openA + 1, 2 * sizeof(DWORD));
+            /* We don't know how many DWORD follow, as
+             * the structure depends on the device. */
+            if (HIWORD(dwParam1))
+                memcpy(&mci_openW->dwStyle, &mci_openA->dwStyle, 
sizeof(MCI_ANIM_OPEN_PARMSW) - sizeof(MCI_OPEN_PARMSW));
         }
         return 1;
 
@@ -327,6 +310,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
         return 0;
 
     case MCI_SYSINFO:
+        if (dwParam1 & (MCI_SYSINFO_INSTALLNAME | MCI_SYSINFO_NAME))
         {
             MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)*dwParam2;
             MCI_SYSINFO_PARMSW *mci_sysinfoW;
@@ -342,16 +326,18 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
             if (dwParam1 & MCI_NOTIFY)
                 mci_sysinfoW->dwCallback = mci_sysinfoA->dwCallback;
 
+            /* Size is measured in numbers of characters, despite what MSDN 
says. */
             mci_sysinfoW->dwRetSize = mci_sysinfoA->dwRetSize;
-            mci_sysinfoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, 
mci_sysinfoW->dwRetSize);
+            mci_sysinfoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, 
mci_sysinfoW->dwRetSize * sizeof(WCHAR));
             mci_sysinfoW->dwNumber = mci_sysinfoA->dwNumber;
             mci_sysinfoW->wDeviceType = mci_sysinfoA->wDeviceType;
             return 1;
         }
+        return 0;
     case MCI_INFO:
         {
-            MCI_INFO_PARMSA *mci_infoA = (MCI_INFO_PARMSA *)*dwParam2;
-            MCI_INFO_PARMSW *mci_infoW;
+            MCI_DGV_INFO_PARMSA *mci_infoA = (MCI_DGV_INFO_PARMSA *)*dwParam2;
+            MCI_DGV_INFO_PARMSW *mci_infoW;
             DWORD_PTR *ptr;
 
             ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_infoW) + 
sizeof(DWORD_PTR));
@@ -359,33 +345,25 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
 
             *ptr++ = *dwParam2; /* save the previous pointer */
             *dwParam2 = (DWORD_PTR)ptr;
-            mci_infoW = (MCI_INFO_PARMSW *)ptr;
+            mci_infoW = (MCI_DGV_INFO_PARMSW *)ptr;
 
             if (dwParam1 & MCI_NOTIFY)
                 mci_infoW->dwCallback = mci_infoA->dwCallback;
 
-            mci_infoW->dwRetSize = mci_infoA->dwRetSize * sizeof(WCHAR); /* 
it's not the same as SYSINFO !!! */
-            mci_infoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, 
mci_infoW->dwRetSize);
+            /* Size is measured in numbers of characters. */
+            mci_infoW->dwRetSize = mci_infoA->dwRetSize;
+            mci_infoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, 
mci_infoW->dwRetSize * sizeof(WCHAR));
+            if (dwParam1 & MCI_DGV_INFO_ITEM)
+                mci_infoW->dwItem = mci_infoA->dwItem;
             return 1;
         }
     case MCI_SAVE:
-        {
-            MCI_SAVE_PARMSA *mci_saveA = (MCI_SAVE_PARMSA *)*dwParam2;
-            MCI_SAVE_PARMSW *mci_saveW;
-
-            mci_saveW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_saveW));
-            if (!mci_saveW) return -1;
-
-            *dwParam2 = (DWORD_PTR)mci_saveW;
-            if (dwParam1 & MCI_NOTIFY)
-                mci_saveW->dwCallback = mci_saveA->dwCallback;
-            mci_saveW->lpfilename = MCI_strdupAtoW(mci_saveA->lpfilename);
-            return 1;
-        }
     case MCI_LOAD:
-        {
-            MCI_LOAD_PARMSA *mci_loadA = (MCI_LOAD_PARMSA *)*dwParam2;
-            MCI_LOAD_PARMSW *mci_loadW;
+    case MCI_CAPTURE:
+    case MCI_RESTORE:
+        {   /* All these commands have the same layout: callback + string + 
optional rect */
+            MCI_OVLY_LOAD_PARMSA *mci_loadA = (MCI_OVLY_LOAD_PARMSA 
*)*dwParam2;
+            MCI_OVLY_LOAD_PARMSW *mci_loadW;
 
             mci_loadW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_loadW));
             if (!mci_loadW) return -1;
@@ -394,11 +372,16 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
             if (dwParam1 & MCI_NOTIFY)
                 mci_loadW->dwCallback = mci_loadA->dwCallback;
             mci_loadW->lpfilename = MCI_strdupAtoW(mci_loadA->lpfilename);
+            if ((MCI_SAVE    == msg && dwParam1 & MCI_DGV_RECT) ||
+                (MCI_LOAD    == msg && dwParam1 & MCI_OVLY_RECT) ||
+                (MCI_CAPTURE == msg && dwParam1 & MCI_DGV_CAPTURE_AT) ||
+                (MCI_RESTORE == msg && dwParam1 & MCI_DGV_RESTORE_AT))
+                mci_loadW->rc = mci_loadA->rc;
             return 1;
         }
-
+    case MCI_SOUND:
     case MCI_ESCAPE:
-        {
+        {   /* All these commands have the same layout: callback + string */
             MCI_VD_ESCAPE_PARMSA *mci_vd_escapeA = (MCI_VD_ESCAPE_PARMSA 
*)*dwParam2;
             MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW;
 
@@ -411,13 +394,22 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR *dwParam2)
             mci_vd_escapeW->lpstrCommand = 
MCI_strdupAtoW(mci_vd_escapeA->lpstrCommand);
             return 1;
         }
+    case MCI_SETAUDIO:
+    case MCI_SETVIDEO:
+        if (!(dwParam1 & (MCI_DGV_SETVIDEO_QUALITY | MCI_DGV_SETVIDEO_ALG
+                        | MCI_DGV_SETAUDIO_QUALITY | MCI_DGV_SETAUDIO_ALG)))
+            return 0;
+        /* fall through to default */
+    case MCI_RESERVE:
+    case MCI_QUALITY:
+    case MCI_LIST:
     default:
         FIXME("Message %s needs translation\n", MCI_MessageToString(msg));
-        return -1;
+        return 0; /* pass through untouched */
     }
 }
 
-static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
+static void MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
                               DWORD result)
 {
     switch (msg)
@@ -426,7 +418,7 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR dwParam2,
         {
             DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
             MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA *)*ptr;
-            MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)(ptr + 1);
+            MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)dwParam2;
 
             mci_openA->wDeviceID = mci_openW->wDeviceID;
 
@@ -456,22 +448,18 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR 
dwParam1, DWORD_PTR dwParam2,
         break;
 
     case MCI_SYSINFO:
+        if (dwParam1 & (MCI_SYSINFO_INSTALLNAME | MCI_SYSINFO_NAME))
         {
             DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
             MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)*ptr;
-            MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)(ptr + 1);
+            MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)dwParam2;
 
             if (!result)
             {
-                mci_sysinfoA->dwNumber = mci_sysinfoW->dwNumber;
-                mci_sysinfoA->wDeviceType = mci_sysinfoW->wDeviceType;
-                if (dwParam1 & MCI_SYSINFO_QUANTITY)
-                    *(DWORD*)mci_sysinfoA->lpstrReturn = 
*(DWORD*)mci_sysinfoW->lpstrReturn;
-                else
-                    WideCharToMultiByte(CP_ACP, 0,
-                                        mci_sysinfoW->lpstrReturn, 
mci_sysinfoW->dwRetSize,
-                                        mci_sysinfoA->lpstrReturn, 
mci_sysinfoA->dwRetSize,
-                                        NULL, NULL);
+                WideCharToMultiByte(CP_ACP, 0,
+                                    mci_sysinfoW->lpstrReturn, -1,
+                                    mci_sysinfoA->lpstrReturn, 
mci_sysinfoA->dwRetSize,
+                                    NULL, NULL);
             }
 
             HeapFree(GetProcessHeap(), 0, mci_sysinfoW->lpstrReturn);
@@ -482,12 +470,12 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR 
dwParam1, DWORD_PTR dwParam2,
         {
             DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
             MCI_INFO_PARMSA *mci_infoA = (MCI_INFO_PARMSA *)*ptr;
-            MCI_INFO_PARMSW *mci_infoW = (MCI_INFO_PARMSW *)(ptr + 1);
+            MCI_INFO_PARMSW *mci_infoW = (MCI_INFO_PARMSW *)dwParam2;
 
             if (!result)
             {
                 WideCharToMultiByte(CP_ACP, 0,
-                                    mci_infoW->lpstrReturn, 
mci_infoW->dwRetSize / sizeof(WCHAR),
+                                    mci_infoW->lpstrReturn, -1,
                                     mci_infoA->lpstrReturn, 
mci_infoA->dwRetSize,
                                     NULL, NULL);
             }
@@ -497,23 +485,19 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR 
dwParam1, DWORD_PTR dwParam2,
         }
         break;
     case MCI_SAVE:
-        {
-            MCI_SAVE_PARMSW *mci_saveW = (MCI_SAVE_PARMSW *)dwParam2;
-
-            HeapFree(GetProcessHeap(), 0, (void*)mci_saveW->lpfilename);
-            HeapFree(GetProcessHeap(), 0, mci_saveW);
-        }
-        break;
     case MCI_LOAD:
-        {
-            MCI_LOAD_PARMSW *mci_loadW = (MCI_LOAD_PARMSW *)dwParam2;
+    case MCI_CAPTURE:
+    case MCI_RESTORE:
+        {   /* All these commands have the same layout: callback + string + 
optional rect */
+            MCI_OVLY_LOAD_PARMSW *mci_loadW = (MCI_OVLY_LOAD_PARMSW *)dwParam2;
 
             HeapFree(GetProcessHeap(), 0, (void*)mci_loadW->lpfilename);
             HeapFree(GetProcessHeap(), 0, mci_loadW);
         }
         break;
+    case MCI_SOUND:
     case MCI_ESCAPE:
-        {
+        {   /* All these commands have the same layout: callback + string */
             MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW = (MCI_VD_ESCAPE_PARMSW 
*)dwParam2;
 
             HeapFree(GetProcessHeap(), 0, (void*)mci_vd_escapeW->lpstrCommand);
@@ -525,8 +509,6 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, 
DWORD_PTR dwParam2,
         FIXME("Message %s needs unmapping\n", MCI_MessageToString(msg));
         break;
     }
-
-    return result;
 }
 
 /**************************************************************************
@@ -536,11 +518,9 @@ static     DWORD   MCI_GetDevTypeFromFileName(LPCWSTR 
fileName, LPWSTR buf, UINT len)
 {
     LPCWSTR    tmp;
     HKEY       hKey;
-    static const WCHAR keyW[] = 
{'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','\\',
-                                 'M','C','I',' 
','E','x','t','e','n','s','i','o','n','s',0};
-    if ((tmp = strrchrW(fileName, '.'))) {
-       if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, keyW,
+    if ((tmp = wcsrchr(fileName, '.'))) {
+       if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
+                          L"SOFTWARE\\Microsoft\\Windows 
NT\\CurrentVersion\\MCI Extensions",
                           0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS) {
            DWORD dwLen = len;
            LONG lRet = RegQueryValueExW( hKey, tmp + 1, 0, 0, (void*)buf, 
&dwLen ); 
@@ -552,6 +532,23 @@ static     DWORD   MCI_GetDevTypeFromFileName(LPCWSTR 
fileName, LPWSTR buf, UINT len)
     return MCIERR_EXTENSION_NOT_FOUND;
 }
 
+/**************************************************************************
+ *                             MCI_GetDevTypeFromResource      [internal]
+ */
+static UINT    MCI_GetDevTypeFromResource(LPCWSTR lpstrName)
+{
+    WCHAR      buf[32];
+    UINT       uDevType;
+    for (uDevType = MCI_DEVTYPE_FIRST; uDevType <= MCI_DEVTYPE_LAST; 
uDevType++) {
+       if (LoadStringW(hWinMM32Instance, uDevType, buf, ARRAY_SIZE(buf))) {
+           /* FIXME: ignore digits suffix */
+           if (!wcsicmp(buf, lpstrName))
+               return uDevType;
+       }
+    }
+    return 0;
+}
+
 #define        MAX_MCICMDTABLE                 20
 #define MCI_COMMAND_TABLE_NOT_LOADED   0xFFFE
 
@@ -586,7 +583,7 @@ static      BOOL            MCI_IsCommandTableValid(UINT 
uTbl)
     lmem = S_MciCmdTable[uTbl].lpTable;
     do {
         str = (LPCWSTR)lmem;
-        lmem += (strlenW(str) + 1) * sizeof(WCHAR);
+        lmem += (lstrlenW(str) + 1) * sizeof(WCHAR);
         flg = *(const DWORD*)lmem;
         eid = *(const WORD*)(lmem + sizeof(DWORD));
         lmem += sizeof(DWORD) + sizeof(WORD);
@@ -595,6 +592,9 @@ static      BOOL            MCI_IsCommandTableValid(UINT 
uTbl)
         switch (eid) {
         case MCI_COMMAND_HEAD:          if (!*str || !flg) return FALSE; idx = 
0;              break;  /* check unicity of str in table */
         case MCI_STRING:                if (inCst) return FALSE;               
                break;
+        case MCI_HWND:                  /* Occurs inside MCI_CONSTANT as in 
"window handle default" */
+        case MCI_HPAL:
+        case MCI_HDC:
         case MCI_INTEGER:               if (!*str) return FALSE;               
                break;
         case MCI_END_COMMAND:           if (*str || flg || idx == 0) return 
FALSE; idx = 0;    break;
         case MCI_RETURN:               if (*str || idx != 1) return FALSE;     
                break;
@@ -616,7 +616,6 @@ static      BOOL            MCI_DumpCommandTable(UINT uTbl)
 {
     const BYTE*        lmem;
     LPCWSTR    str;
-    DWORD      flg;
     WORD       eid;
 
     if (!MCI_IsCommandTableValid(uTbl)) {
@@ -627,9 +626,10 @@ static     BOOL            MCI_DumpCommandTable(UINT uTbl)
     lmem = S_MciCmdTable[uTbl].lpTable;
     do {
        do {
+           /* DWORD flg; */
            str = (LPCWSTR)lmem;
-           lmem += (strlenW(str) + 1) * sizeof(WCHAR);
-           flg = *(const DWORD*)lmem;
+           lmem += (lstrlenW(str) + 1) * sizeof(WCHAR);
+           /* flg = *(const DWORD*)lmem; */
            eid = *(const WORD*)(lmem + sizeof(DWORD));
             /* TRACE("cmd=%s %08lx %04x\n", debugstr_w(str), flg, eid); */
            lmem += sizeof(DWORD) + sizeof(WORD);
@@ -657,12 +657,11 @@ static    UINT            MCI_GetCommandTable(UINT 
uDevType)
 
     /* well try to load id */
     if (uDevType >= MCI_DEVTYPE_FIRST && uDevType <= MCI_DEVTYPE_LAST) {
-       if (LoadStringW(hWinMM32Instance, uDevType, buf, sizeof(buf) / 
sizeof(WCHAR))) {
+       if (LoadStringW(hWinMM32Instance, uDevType, buf, ARRAY_SIZE(buf))) {
            str = buf;
        }
     } else if (uDevType == 0) {
-        static const WCHAR wszCore[] = {'C','O','R','E',0};
-       str = wszCore;
+       str = L"CORE";
     }
     uTbl = MCI_NO_COMMAND_TABLE;
     if (str) {
@@ -720,7 +719,7 @@ static UINT MCI_SetCommandTable(HGLOBAL hMem, UINT uDevType)
            count = 0;
            do {
                str = (LPCWSTR)lmem;
-               lmem += (strlenW(str) + 1) * sizeof(WCHAR);
+               lmem += (lstrlenW(str) + 1) * sizeof(WCHAR);
                eid = *(const WORD*)(lmem + sizeof(DWORD));
                lmem += sizeof(DWORD) + sizeof(WORD);
                if (eid == MCI_COMMAND_HEAD)
@@ -734,7 +733,7 @@ static UINT MCI_SetCommandTable(HGLOBAL hMem, UINT uDevType)
            count = 0;
            do {
                str = (LPCWSTR)lmem;
-               lmem += (strlenW(str) + 1) * sizeof(WCHAR);
+               lmem += (lstrlenW(str) + 1) * sizeof(WCHAR);
                eid = *(const WORD*)(lmem + sizeof(DWORD));
                lmem += sizeof(DWORD) + sizeof(WORD);
                if (eid == MCI_COMMAND_HEAD)
@@ -774,7 +773,6 @@ static      BOOL    MCI_UnLoadMciDriver(LPWINE_MCIDRIVER 
wmd)
 
     HeapFree(GetProcessHeap(), 0, wmd->lpstrDeviceType);
     HeapFree(GetProcessHeap(), 0, wmd->lpstrAlias);
-    HeapFree(GetProcessHeap(), 0, wmd->lpstrElementName);
 
     HeapFree(GetProcessHeap(), 0, wmd);
     return TRUE;
@@ -787,7 +785,7 @@ static      BOOL    MCI_OpenMciDriver(LPWINE_MCIDRIVER wmd, 
LPCWSTR drvTyp, DWORD_PTR lp
 {
     WCHAR      libName[128];
 
-    if (!DRIVER_GetLibName(drvTyp, wszMci, libName, sizeof(libName)))
+    if (!DRIVER_GetLibName(drvTyp, L"MCI", libName, sizeof(libName)))
        return FALSE;
 
     /* First load driver */
@@ -837,7 +835,7 @@ static      DWORD   MCI_LoadMciDriver(LPCWSTR _strDevTyp, 
LPWINE_MCIDRIVER* lpwmd)
        /* silence warning if all is used... some bogus program use commands 
like
         * 'open all'...
         */
-       if (strcmpiW(strDevTyp, wszAll) == 0) {
+       if (wcsicmp(strDevTyp, L"ALL") == 0) {
            dwRet = MCIERR_CANNOT_USE_ALL;
        } else {
            FIXME("Couldn't load driver for type %s.\n",
@@ -881,6 +879,9 @@ static DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, 
UINT16 wMsg, DWORD_PTR dw
     LPWINE_MCIDRIVER   wmd = MCI_GetDriver(wDevID);
 
     if (wmd) {
+        if(wmd->CreatorThread != GetCurrentThreadId())
+            return MCIERR_INVALID_DEVICE_NAME;
+
         dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
     }
     return dwRet;
@@ -888,19 +889,38 @@ static DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, 
UINT16 wMsg, DWORD_PTR dw
 
 /**************************************************************************
  *                     MCI_FinishOpen                          [internal]
+ *
+ * Three modes of operation:
+ * 1 open foo.ext ...        -> OPEN_ELEMENT with lpstrElementName=foo.ext
+ *   open sequencer!foo.ext     same         with lpstrElementName=foo.ext
+ * 2 open new type waveaudio -> OPEN_ELEMENT with empty ("") lpstrElementName
+ * 3 open sequencer          -> OPEN_ELEMENT unset, and
+ *   capability sequencer       (auto-open)  likewise
  */
 static DWORD   MCI_FinishOpen(LPWINE_MCIDRIVER wmd, LPMCI_OPEN_PARMSW lpParms,
                               DWORD dwParam)
 {
-    if (dwParam & MCI_OPEN_ELEMENT)
-    {
-        wmd->lpstrElementName = 
HeapAlloc(GetProcessHeap(),0,(strlenW(lpParms->lpstrElementName)+1) * 
sizeof(WCHAR));
-        strcpyW( wmd->lpstrElementName, lpParms->lpstrElementName );
+    LPCWSTR alias = NULL;
+    /* Open always defines an alias for further reference */
+    if (dwParam & MCI_OPEN_ALIAS) {         /* open ... alias */
+        alias = lpParms->lpstrAlias;
+        if (MCI_GetDriverFromString(alias))
+            return MCIERR_DUPLICATE_ALIAS;
+    } else {
+        if ((dwParam & MCI_OPEN_ELEMENT)    /* open file.wav */
+            && !(dwParam & MCI_OPEN_ELEMENT_ID))
+            alias = lpParms->lpstrElementName;
+        else if (dwParam & MCI_OPEN_TYPE )  /* open cdaudio */
+            alias = wmd->lpstrDeviceType;
+        if (alias && MCI_GetDriverFromString(alias))
+            return MCIERR_DEVICE_OPEN;
     }
-    if (dwParam & MCI_OPEN_ALIAS)
-    {
-        wmd->lpstrAlias = HeapAlloc(GetProcessHeap(), 0, 
(strlenW(lpParms->lpstrAlias)+1) * sizeof(WCHAR));
-        strcpyW( wmd->lpstrAlias, lpParms->lpstrAlias);
+    if (alias) {
+        wmd->lpstrAlias = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(alias)+1) * 
sizeof(WCHAR));
+        if (!wmd->lpstrAlias) return MCIERR_OUT_OF_MEMORY;
+        lstrcpyW( wmd->lpstrAlias, alias);
+        /* In most cases, natives adds MCI_OPEN_ALIAS to the flags passed to 
the driver.
+         * Don't.  The drivers don't care about the winmm alias. */
     }
     lpParms->wDeviceID = wmd->wDeviceID;
 
@@ -923,7 +943,7 @@ static      LPCWSTR         MCI_FindCommand(UINT uTbl, 
LPCWSTR verb)
      * array look up
      */
     for (idx = 0; idx < S_MciCmdTable[uTbl].nVerbs; idx++) {
-       if (strcmpiW(S_MciCmdTable[uTbl].aVerbs[idx], verb) == 0)
+       if (wcsicmp(S_MciCmdTable[uTbl].aVerbs[idx], verb) == 0)
            return S_MciCmdTable[uTbl].aVerbs[idx];
     }
 
@@ -935,7 +955,7 @@ static      LPCWSTR         MCI_FindCommand(UINT uTbl, 
LPCWSTR verb)
  */
 static DWORD           MCI_GetReturnType(LPCWSTR lpCmd)
 {
-    lpCmd = (LPCWSTR)((const BYTE*)(lpCmd + strlenW(lpCmd) + 1) + 
sizeof(DWORD) + sizeof(WORD));
+    lpCmd = (LPCWSTR)((const BYTE*)(lpCmd + lstrlenW(lpCmd) + 1) + 
sizeof(DWORD) + sizeof(WORD));
     if (*lpCmd == '\0' && *(const WORD*)((const BYTE*)(lpCmd + 1) + 
sizeof(DWORD)) == MCI_RETURN) {
        return *(const DWORD*)(lpCmd + 1);
     }
@@ -947,28 +967,52 @@ static    DWORD           MCI_GetReturnType(LPCWSTR lpCmd)
  */
 static WORD            MCI_GetMessage(LPCWSTR lpCmd)
 {
-    return (WORD)*(const DWORD*)(lpCmd + strlenW(lpCmd) + 1);
+    return (WORD)*(const DWORD*)(lpCmd + lstrlenW(lpCmd) + 1);
 }
 
 /**************************************************************************
  *                             MCI_GetDWord                    [internal]
+ *
+ * Accept 0 -1 255 255:0 255:255:255:255 :::1 1::: 2::3 ::4: 12345678
+ * Refuse -1:0 0:-1 :: 256:0 1:256 0::::1
  */
-static BOOL            MCI_GetDWord(DWORD_PTR *data, LPWSTR* ptr)
+static BOOL            MCI_GetDWord(DWORD* data, LPWSTR* ptr)
 {
-    DWORD      val;
-    LPWSTR     ret;
-
-    val = strtoulW(*ptr, &ret, 0);
-
-    switch (*ret) {
-    case '\0': break;
-    case ' ':  ret++; break;
-    default:   return FALSE;
+    LPWSTR     ret = *ptr;
+    DWORD      total = 0, shift = 0;
+    BOOL       sign = FALSE, digits = FALSE;
+
+    while (*ret == ' ' || *ret == '\t') ret++;
+    if (*ret == '-') {
+       ret++;
+       sign = TRUE;
     }
+    for(;;) {
+       DWORD   val = 0;
+       while ('0' <= *ret && *ret <= '9') {
+           val = *ret++ - '0' + 10 * val;
+           digits = TRUE;
+       }
+       switch (*ret) {
+       case '\0':      break;
+       case '\t':
+       case ' ':       ret++; break;
+       default:        return FALSE;
+       case ':':
+           if ((val >= 256) || (shift >= 24))  return FALSE;
+           total |= val << shift;
+           shift += 8;
+           ret++;
+           continue;
+       }
 
-    *data |= val;
-    *ptr = ret;
-    return TRUE;
+       if (!digits)                            return FALSE;
+       if (shift && (val >= 256 || sign))      return FALSE;
+       total |= val << shift;
+       *data = sign ? -total : total;
+       *ptr = ret;
+       return TRUE;
+    }
 }
 
 /**************************************************************************
@@ -980,19 +1024,19 @@ static   DWORD   MCI_GetString(LPWSTR* str, LPWSTR* args)
 
     /* see if we have a quoted string */
     if (*ptr == '"') {
-       ptr = strchrW(*str = ptr + 1, '"');
+       ptr = wcschr(*str = ptr + 1, '"');
        if (!ptr) return MCIERR_NO_CLOSING_QUOTE;
        /* FIXME: shall we escape \" from string ?? */
        if (ptr[-1] == '\\') TRACE("Ooops: un-escaped \"\n");
        *ptr++ = '\0'; /* remove trailing " */
        if (*ptr != ' ' && *ptr != '\0') return MCIERR_EXTRA_CHARACTERS;
     } else {
-       ptr = strchrW(ptr, ' ');
+       ptr = wcschr(ptr, ' ');
 
        if (ptr) {
            *ptr++ = '\0';
        } else {
-           ptr = *args + strlenW(*args);
+           ptr = *args + lstrlenW(*args);
        }
        *str = *args;
     }
@@ -1006,7 +1050,7 @@ static    DWORD   MCI_GetString(LPWSTR* str, LPWSTR* args)
 /**************************************************************************
  *                             MCI_ParseOptArgs                [internal]
  */
-static DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int _offset, LPCWSTR lpCmd,
+static DWORD   MCI_ParseOptArgs(DWORD* data, int _offset, LPCWSTR lpCmd,
                                 LPWSTR args, LPDWORD dwFlags)
 {
     int                len, offset;
@@ -1024,11 +1068,11 @@ static  DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
 
        /* skip any leading white space(s) */
        while (*args == ' ') args++;
-       TRACE("args=%s offset=%d\n", debugstr_w(args), offset);
+       TRACE("args=%s\n", debugstr_w(args));
 
        do { /* loop on options for command table for the requested verb */
            str = (LPCWSTR)lmem;
-           lmem += ((len = strlenW(str)) + 1) * sizeof(WCHAR);
+           lmem += ((len = lstrlenW(str)) + 1) * sizeof(WCHAR);
            flg = *(const DWORD*)lmem;
            eid = *(const WORD*)(lmem + sizeof(DWORD));
            lmem += sizeof(DWORD) + sizeof(WORD);
@@ -1044,9 +1088,14 @@ static   DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
                }
                inCst = FALSE;  cflg = 0;
                break;
+           case MCI_RETURN:
+               if (offset != _offset) {
+                   FIXME("MCI_RETURN not in first position\n");
+                   return MCIERR_PARSER_INTERNAL;
+               }
            }
 
-           if (strncmpiW(args, str, len) == 0 &&
+           if (wcsnicmp(args, str, len) == 0 &&
                 ((eid == MCI_STRING && len == 0) || args[len] == 0 || 
args[len] == ' ')) {
                /* store good values into data[] */
                args += len;
@@ -1063,17 +1112,23 @@ static  DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
                    break;
                case MCI_FLAG:
                    *dwFlags |= flg;
+                   TRACE("flag=%08lx\n", flg);
                    break;
+               case MCI_HWND:
+               case MCI_HPAL:
+               case MCI_HDC:
                case MCI_INTEGER:
                    if (inCst) {
                        data[offset] |= flg;
                        *dwFlags |= cflg;
                        inCst = FALSE;
+                       TRACE("flag=%08lx constant=%08lx\n", cflg, flg);
                    } else {
                        *dwFlags |= flg;
                        if (!MCI_GetDWord(&(data[offset]), &args)) {
                            return MCIERR_BAD_INTEGER;
                        }
+                       TRACE("flag=%08lx int=%ld\n", flg, data[offset]);
                    }
                    break;
                case MCI_RECT:
@@ -1083,14 +1138,15 @@ static  DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
                        !MCI_GetDWord(&(data[offset+1]), &args) ||
                        !MCI_GetDWord(&(data[offset+2]), &args) ||
                        !MCI_GetDWord(&(data[offset+3]), &args)) {
-                       ERR("Bad rect %s\n", debugstr_w(args));
                        return MCIERR_BAD_INTEGER;
                    }
+                   TRACE("flag=%08lx for rectangle\n", flg);
                    break;
                case MCI_STRING:
                    *dwFlags |= flg;
                    if ((dwRet = MCI_GetString((LPWSTR*)&data[offset], &args)))
                        return dwRet;
+                   TRACE("flag=%08lx string=%s\n", flg, 
debugstr_w(*(LPWSTR*)&data[offset]));
                    break;
                default:        ERR("oops\n");
                }
@@ -1105,9 +1161,12 @@ static   DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
                case MCI_END_COMMAND_LIST:
                case MCI_CONSTANT:
                case MCI_FLAG:                  break;
+               case MCI_HWND:
+               case MCI_HPAL:
+               case MCI_HDC:                   if (!inCst) offset += 
sizeof(HANDLE)/sizeof(DWORD); break;
                case MCI_INTEGER:               if (!inCst) offset++;   break;
-               case MCI_END_CONSTANT:
-               case MCI_STRING:                offset++; break;
+               case MCI_END_CONSTANT:          offset++; break;
+               case MCI_STRING:                offset += 
sizeof(LPWSTR)/sizeof(DWORD); break;
                case MCI_RECT:                  offset += 4; break;
                default:                        ERR("oops\n");
                }
@@ -1118,7 +1177,7 @@ static    DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
            return MCIERR_UNRECOGNIZED_COMMAND;
        }
        if (offset == MCI_DATA_SIZE) {
-           ERR("Internal data[] buffer overflow\n");
+           FIXME("Internal data[] buffer overflow\n");
            return MCIERR_PARSER_INTERNAL;
        }
     }
@@ -1128,70 +1187,107 @@ static DWORD   MCI_ParseOptArgs(DWORD_PTR *data, int 
_offset, LPCWSTR lpCmd,
 /**************************************************************************
  *                             MCI_HandleReturnValues  [internal]
  */
-static DWORD   MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD 
retType, 
-                                       DWORD_PTR *data, LPWSTR lpstrRet, UINT 
uRetLen)
+static DWORD   MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD 
retType,
+                                       MCI_GENERIC_PARMS *params, LPWSTR 
lpstrRet, UINT uRetLen)
 {
-    static const WCHAR wszLd  [] = {'%','l','d',0};
-    static const WCHAR wszLd4 [] = {'%','l','d',' ','%','l','d',' 
','%','l','d',' ','%','l','d',0};
-    static const WCHAR wszCol3[] = {'%','d',':','%','d',':','%','d',0};
-    static const WCHAR wszCol4[] = 
{'%','d',':','%','d',':','%','d',':','%','d',0};
-
     if (lpstrRet) {
        switch (retType) {
        case 0: /* nothing to return */
            break;
        case MCI_INTEGER:
+        {
+            DWORD data = *(DWORD *)(params + 1);
            switch (dwRet & 0xFFFF0000ul) {
            case 0:
            case MCI_INTEGER_RETURNED:
-               snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
+               swprintf(lpstrRet, uRetLen, L"%d", data);
                break;
            case MCI_RESOURCE_RETURNED:
-               /* return string which ID is HIWORD(data[1]),
+               /* return string which ID is HIWORD(data),
                 * string is loaded from mmsystem.dll */
-               LoadStringW(hWinMM32Instance, HIWORD(data[1]), lpstrRet, 
uRetLen);
+               LoadStringW(hWinMM32Instance, HIWORD(data), lpstrRet, uRetLen);
                break;
            case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
-               /* return string which ID is HIWORD(data[1]),
+               /* return string which ID is HIWORD(data),
                 * string is loaded from driver */
                /* FIXME: this is wrong for a 16 bit handle */
                LoadStringW(GetDriverModuleHandle(wmd->hDriver),
-                           HIWORD(data[1]), lpstrRet, uRetLen);
+                           HIWORD(data), lpstrRet, uRetLen);
                break;
            case MCI_COLONIZED3_RETURN:
-               snprintfW(lpstrRet, uRetLen, wszCol3,
-                         LOBYTE(LOWORD(data[1])), HIBYTE(LOWORD(data[1])),
-                         LOBYTE(HIWORD(data[1])));
+               swprintf(lpstrRet, uRetLen, L"%02d:%02d:%02d",
+                         LOBYTE(LOWORD(data)), HIBYTE(LOWORD(data)),
+                         LOBYTE(HIWORD(data)));
                break;
            case MCI_COLONIZED4_RETURN:
-               snprintfW(lpstrRet, uRetLen, wszCol4,
-                         LOBYTE(LOWORD(data[1])), HIBYTE(LOWORD(data[1])),
-                         LOBYTE(HIWORD(data[1])), HIBYTE(HIWORD(data[1])));
+               swprintf(lpstrRet, uRetLen, L"%02d:%02d:%02d:%02d",
+                         LOBYTE(LOWORD(data)), HIBYTE(LOWORD(data)),
+                         LOBYTE(HIWORD(data)), HIBYTE(HIWORD(data)));
                break;
            default:    ERR("Ooops (%04X)\n", HIWORD(dwRet));
            }
            break;
+        }
+       case 13: /* MCI_INTEGER64 */
+        {
+           DWORD_PTR data = *(DWORD_PTR *)(params + 1);
+           switch (dwRet & 0xFFFF0000ul) {
+           case 0:
+           case MCI_INTEGER_RETURNED:
+               swprintf(lpstrRet, uRetLen, L"%Id", data);
+               break;
+           case MCI_RESOURCE_RETURNED:
+               /* return string which ID is HIWORD(data),
+                * string is loaded from mmsystem.dll */
+               LoadStringW(hWinMM32Instance, HIWORD(data), lpstrRet, uRetLen);
+               break;
+           case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
+               /* return string which ID is HIWORD(data),
+                * string is loaded from driver */
+               /* FIXME: this is wrong for a 16 bit handle */
+               LoadStringW(GetDriverModuleHandle(wmd->hDriver),
+                           HIWORD(data), lpstrRet, uRetLen);
+               break;
+           case MCI_COLONIZED3_RETURN:
+               swprintf(lpstrRet, uRetLen, L"%02d:%02d:%02d",
+                         LOBYTE(LOWORD(data)), HIBYTE(LOWORD(data)),
+                         LOBYTE(HIWORD(data)));
+               break;
+           case MCI_COLONIZED4_RETURN:
+               swprintf(lpstrRet, uRetLen, L"%02d:%02d:%02d:%02d",
+                         LOBYTE(LOWORD(data)), HIBYTE(LOWORD(data)),
+                         LOBYTE(HIWORD(data)), HIBYTE(HIWORD(data)));
+               break;
+           default:    ERR("Ooops (%04X)\n", HIWORD(dwRet));
+           }
+           break;
+        }
        case MCI_STRING:
            switch (dwRet & 0xFFFF0000ul) {
            case 0:
-               /* nothing to do data[1] == lpstrRet */
+               /* nothing to do data[0] == lpstrRet */
                break;
            case MCI_INTEGER_RETURNED:
-               data[1] = *(LPDWORD)lpstrRet;
-               snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
+            {
+                DWORD *data = (DWORD *)(params + 1);
+               *data = *(LPDWORD)lpstrRet;
+               swprintf(lpstrRet, uRetLen, L"%d", *data);
                break;
+            }
            default:
                WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", 
HIWORD(dwRet));
                break;
            }
            break;
        case MCI_RECT:
+        {
+            DWORD *data = (DWORD *)(params + 1);
            if (dwRet & 0xFFFF0000ul)
                WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", 
HIWORD(dwRet));
-           snprintfW(lpstrRet, uRetLen, wszLd4,
-                      data[1], data[2], data[3], data[4]);
+           swprintf(lpstrRet, uRetLen, L"%d %d %d %d", data[0], data[1], 
data[2], data[3]);
            break;
-       default:                ERR("oops\n");
+        }
+       default:                FIXME("Unknown MCI return type %ld\n", retType);
        }
     }
     return LOWORD(dwRet);
@@ -1203,30 +1299,39 @@ static  DWORD   MCI_HandleReturnValues(DWORD dwRet, 
LPWINE_MCIDRIVER wmd, DWORD ret
 DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
                            UINT uRetLen, HWND hwndCallback)
 {
-    LPWSTR             verb, dev, args;
+    LPWSTR             verb, dev, args, devType = NULL;
     LPWINE_MCIDRIVER   wmd = 0;
+    MCIDEVICEID                uDevID, auto_open = 0;
     DWORD              dwFlags = 0, dwRet = 0;
     int                        offset = 0;
-    DWORD_PTR  data[MCI_DATA_SIZE];
     DWORD              retType;
     LPCWSTR            lpCmd = 0;
-    LPWSTR             devAlias = NULL;
-    static const WCHAR  wszNew[] = {'n','e','w',0};
-    static const WCHAR  wszSAliasS[] = {' ','a','l','i','a','s',' ',0};
-    static const WCHAR wszTypeS[] = {'t','y','p','e',' ',0};
+    WORD               wMsg = 0;
+    union
+    {
+        MCI_GENERIC_PARMS  generic;
+        MCI_OPEN_PARMSW    open;
+        MCI_SOUND_PARMSW   sound;
+        MCI_SYSINFO_PARMSW sysinfo;
+        DWORD              dw[MCI_DATA_SIZE];
+    } data;
 
     TRACE("(%s, %p, %d, %p)\n", 
           debugstr_w(lpstrCommand), lpstrRet, uRetLen, hwndCallback);
+    if (lpstrRet && uRetLen) *lpstrRet = '\0';
+
+    if (!lpstrCommand[0])
+        return MCIERR_MISSING_COMMAND_STRING;
 
     /* format is <command> <device> <optargs> */
-    if (!(verb = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpstrCommand)+1) * 
sizeof(WCHAR))))
+    if (!(verb = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(lpstrCommand)+1) * 
sizeof(WCHAR))))
        return MCIERR_OUT_OF_MEMORY;
-    strcpyW( verb, lpstrCommand );
+    lstrcpyW( verb, lpstrCommand );
     CharLowerW(verb);
 
-    memset(data, 0, sizeof(data));
+    memset(&data, 0, sizeof(data));
 
-    if (!(args = strchrW(verb, ' '))) {
+    if (!(args = wcschr(verb, ' '))) {
        dwRet = MCIERR_MISSING_DEVICE_NAME;
        goto errCleanUp;
     }
@@ -1234,18 +1339,19 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, 
LPWSTR lpstrRet,
     if ((dwRet = MCI_GetString(&dev, &args))) {
        goto errCleanUp;
     }
+    uDevID = wcsicmp(dev, L"ALL") ? 0 : MCI_ALL_DEVICE_ID;
 
     /* Determine devType from open */
-    if (!strcmpW(verb, wszOpen)) {
-       LPWSTR  devType, tmp;
+    if (!wcscmp(verb, L"open")) {
+       LPWSTR  tmp;
         WCHAR  buf[128];
 
        /* case dev == 'new' has to be handled */
-       if (!strcmpW(dev, wszNew)) {
+       if (!wcscmp(dev, L"new")) {
            dev = 0;
-           if ((devType = strstrW(args, wszTypeS)) != NULL) {
+           if ((devType = wcsstr(args, L"type ")) != NULL) {
                devType += 5;
-               tmp = strchrW(devType, ' ');
+               tmp = wcschr(devType, ' ');
                if (tmp) *tmp = '\0';
                devType = str_dup_upper(devType);
                if (tmp) *tmp = ' ';
@@ -1255,31 +1361,33 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, 
LPWSTR lpstrRet,
                dwRet = MCIERR_MISSING_DEVICE_NAME;
                goto errCleanUp;
            }
-       } else if ((devType = strchrW(dev, '!')) != NULL) {
+           dwFlags |= MCI_OPEN_ELEMENT;
+           data.open.lpstrElementName = &L""[0];
+       } else if ((devType = wcschr(dev, '!')) != NULL) {
            *devType++ = '\0';
            tmp = devType; devType = dev; dev = tmp;
 
            dwFlags |= MCI_OPEN_TYPE;
-           data[2] = (DWORD_PTR)devType;
+           data.open.lpstrDeviceType = devType;
            devType = str_dup_upper(devType);
            dwFlags |= MCI_OPEN_ELEMENT;
-           data[3] = (DWORD_PTR)dev;
-       } else if (DRIVER_GetLibName(dev, wszMci, buf, sizeof(buf))) {
+           data.open.lpstrElementName = dev;
+       } else if (DRIVER_GetLibName(dev, L"MCI", buf, sizeof(buf))) {
             /* this is the name of a mci driver's type */
-           tmp = strchrW(dev, ' ');
+           tmp = wcschr(dev, ' ');
            if (tmp) *tmp = '\0';
-           data[2] = (DWORD_PTR)dev;
+           data.open.lpstrDeviceType = dev;
            devType = str_dup_upper(dev);
            if (tmp) *tmp = ' ';
            dwFlags |= MCI_OPEN_TYPE;
        } else {
-           if ((devType = strstrW(args, wszTypeS)) != NULL) {
+           if ((devType = wcsstr(args, L"type ")) != NULL) {
                devType += 5;
-               tmp = strchrW(devType, ' ');
+               tmp = wcschr(devType, ' ');
                if (tmp) *tmp = '\0';
                devType = str_dup_upper(devType);
                if (tmp) *tmp = ' ';
-               /* dwFlags and data[2] will be correctly set in ParseOpt loop */
+               /* dwFlags and lpstrDeviceType will be correctly set in 
ParseOpt loop */
            } else {
                if ((dwRet = MCI_GetDevTypeFromFileName(dev, buf, sizeof(buf))))
                    goto errCleanUp;
@@ -1287,21 +1395,13 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, 
LPWSTR lpstrRet,
                devType = str_dup_upper(buf);
            }
            dwFlags |= MCI_OPEN_ELEMENT;
-           data[3] = (DWORD_PTR)dev;
+           data.open.lpstrElementName = dev;
        }
-       if ((devAlias = strstrW(args, wszSAliasS))) {
-            WCHAR*      tmp2;
-           devAlias += 7;
-           if (!(tmp = strchrW(devAlias,' '))) tmp = devAlias + 
strlenW(devAlias);
-           if (tmp) *tmp = '\0';
-            tmp2 = HeapAlloc(GetProcessHeap(), 0, (tmp - devAlias + 1) * 
sizeof(WCHAR) );
-            memcpy( tmp2, devAlias, (tmp - devAlias) * sizeof(WCHAR) );
-            tmp2[tmp - devAlias] = 0;
-            data[4] = (DWORD_PTR)tmp2;
-           /* should be done in regular options parsing */
-           /* dwFlags |= MCI_OPEN_ALIAS; */
-       } else if (dev == 0) {
-           /* "open new" requires alias */
+       if (MCI_ALL_DEVICE_ID == uDevID) {
+           dwRet = MCIERR_CANNOT_USE_ALL;
+           goto errCleanUp;
+       }
+       if (!wcsstr(args, L" alias ") && !dev) {
            dwRet = MCIERR_NEW_REQUIRES_ALIAS;
            goto errCleanUp;
        }
@@ -1309,25 +1409,38 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, 
LPWSTR lpstrRet,
        dwRet = MCI_LoadMciDriver(devType, &wmd);
        if (dwRet == MCIERR_DEVICE_NOT_INSTALLED)
            dwRet = MCIERR_INVALID_DEVICE_NAME;
-       HeapFree(GetProcessHeap(), 0, devType);
-       if (dwRet) {
-           MCI_UnLoadMciDriver(wmd);
-           goto errCleanUp;
-       }
-    } else if (!(wmd = MCI_GetDriver(mciGetDeviceIDW(dev)))) {
-       /* auto open */
-        static const WCHAR wszOpenWait[] = {'o','p','e','n',' ','%','s',' 
','w','a','i','t',0};
-       WCHAR   buf[128];
-       sprintfW(buf, wszOpenWait, dev);
-
-       if ((dwRet = mciSendStringW(buf, NULL, 0, 0)) != 0)
+       if (dwRet)
            goto errCleanUp;
-
-       wmd = MCI_GetDriver(mciGetDeviceIDW(dev));
-       if (!wmd) {
-           /* FIXME: memory leak, MCI driver is not closed */
-           dwRet = MCIERR_INVALID_DEVICE_ID;
+    } else if ((MCI_ALL_DEVICE_ID != uDevID) && !(wmd = 
MCI_GetDriver(mciGetDeviceIDW(dev)))
+              && (lpCmd = MCI_FindCommand(MCI_GetCommandTable(0), verb))) {
+       /* auto-open uses the core command table */
+       switch (MCI_GetMessage(lpCmd)) {
+       case MCI_SOUND:   /* command does not use a device name */
+       case MCI_SYSINFO:
+           break;
+       case MCI_CLOSE:   /* don't auto-open for close */
+       case MCI_BREAK:   /* no auto-open for system commands */
+           dwRet = MCIERR_INVALID_DEVICE_NAME;
            goto errCleanUp;
+           break;
+       default:
+           {
+               WCHAR   buf[138], retbuf[6];
+               swprintf(buf, ARRAY_SIZE(buf), L"open %s wait", dev);
+               /* open via mciSendString handles quoting, dev!file syntax and 
alias creation */
+               if ((dwRet = mciSendStringW(buf, retbuf, ARRAY_SIZE(retbuf), 
0)) != 0)
+                   goto errCleanUp;
+               auto_open = wcstoul(retbuf, NULL, 10);
+               TRACE("auto-opened %u for %s\n", auto_open, debugstr_w(dev));
+
+               /* FIXME: test for notify flag (how to preparse?) before 
opening */
+               wmd = MCI_GetDriver(auto_open);
+               if (!wmd) {
+                   ERR("No auto-open device %u\n", auto_open);
+                   dwRet = MCIERR_INVALID_DEVICE_ID;
+                   goto errCleanUp;
+               }
+           }
        }
     }
 
@@ -1351,50 +1464,118 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, 
LPWSTR lpstrRet,
        dwRet = MCIERR_UNRECOGNIZED_COMMAND;
        goto errCleanUp;
     }
+    wMsg = MCI_GetMessage(lpCmd);
 
     /* set return information */
+    offset = sizeof(data.generic);
     switch (retType = MCI_GetReturnType(lpCmd)) {
-    case 0:            offset = 1;     break;
-    case MCI_INTEGER:  offset = 2;     break;
-    case MCI_STRING:   data[1] = (DWORD_PTR)lpstrRet; data[2] = uRetLen; 
offset = 3; break;
-    case MCI_RECT:     offset = 5;     break;
-    default:   ERR("oops\n");
+    case 0:
+        break;
+    case MCI_INTEGER:
+        offset += sizeof(DWORD);
+        break;
+    case MCI_STRING:
+        data.sysinfo.lpstrReturn = lpstrRet;
+        data.sysinfo.dwRetSize = uRetLen;
+        offset = FIELD_OFFSET( MCI_SYSINFO_PARMSW, dwNumber );
+        break;
+    case MCI_RECT:
+        offset += 4 * sizeof(DWORD);
+        break;
+    case 13: /* MCI_INTEGER64 */
+       offset += sizeof(DWORD_PTR);
+        break;
+    default:
+       FIXME("Unknown MCI return type %ld\n", retType);
+       dwRet = MCIERR_PARSER_INTERNAL;
+       goto errCleanUp;
     }
 
     TRACE("verb=%s on dev=%s; offset=%d\n", 
           debugstr_w(verb), debugstr_w(dev), offset);
 
-    if ((dwRet = MCI_ParseOptArgs(data, offset, lpCmd, args, &dwFlags)))
+    if ((dwRet = MCI_ParseOptArgs(data.dw, offset / sizeof(DWORD), lpCmd, 
args, &dwFlags)))
        goto errCleanUp;
 
     /* set up call back */
+    if (auto_open) {
+       if (dwFlags & MCI_NOTIFY) {
+           dwRet = MCIERR_NOTIFY_ON_AUTO_OPEN;
+           goto errCleanUp;
+       }
+       /* FIXME: the command should get its own notification window set up and
+        * ask for device closing while processing the notification mechanism.
+        * hwndCallback = ...
+        * dwFlags |= MCI_NOTIFY;
+        * In the meantime special-case all commands but PLAY and RECORD below. 
*/
+    }
     if (dwFlags & MCI_NOTIFY) {
-       data[0] = (DWORD_PTR)hwndCallback;
+       data.generic.dwCallback = (DWORD_PTR)hwndCallback;
     }
 
-    /* FIXME: the command should get it's own notification window set up and
-     * ask for device closing while processing the notification mechanism
-     */
-    if (lpstrRet && uRetLen) *lpstrRet = '\0';
+    switch (wMsg) {
+    case MCI_OPEN:
+       if (wcscmp(verb, L"open")) {
+           FIXME("Cannot open with command %s\n", debugstr_w(verb));
+           dwRet = MCIERR_DRIVER_INTERNAL;
+           wMsg = 0;
+           goto errCleanUp;
+       }
+       break;
+    case MCI_SYSINFO:
+       /* Requirements on dev depend on the flags:
+        * alias with INSTALLNAME, name like "digitalvideo"
+        * with QUANTITY and NAME. */
+       {
+           data.sysinfo.wDeviceType = MCI_ALL_DEVICE_ID;
+           if (uDevID != MCI_ALL_DEVICE_ID) {
+               if (dwFlags & MCI_SYSINFO_INSTALLNAME)
+                   wmd = MCI_GetDriver(mciGetDeviceIDW(dev));
+               else if (!(data.sysinfo.wDeviceType = 
MCI_GetDevTypeFromResource(dev))) {
+                   dwRet = MCIERR_DEVICE_TYPE_REQUIRED;
+                   goto errCleanUp;
+               }
+           }
+       }
+       break;
+    case MCI_SOUND:
+       /* FIXME: name is optional, "sound" is a valid command.
+        * FIXME: Parse "sound notify" as flag, not as name. */
+       data.sound.lpstrSoundName = dev;
+       dwFlags |= MCI_SOUND_NAME;
+       break;
+    }
 
-    TRACE("[%d, %s, %08x, %08x/%s %08x/%s %08x/%s %08x/%s %08x/%s %08x/%s]\n",
-         wmd->wDeviceID, MCI_MessageToString(MCI_GetMessage(lpCmd)), dwFlags,
-         data[0], debugstr_w((WCHAR *)data[0]), data[1], debugstr_w((WCHAR 
*)data[1]),
-         data[2], debugstr_w((WCHAR *)data[2]), data[3], debugstr_w((WCHAR 
*)data[3]),
-         data[4], debugstr_w((WCHAR *)data[4]), data[5], debugstr_w((WCHAR 
*)data[5]));
+    TRACE("[%d, %s, %08lx, %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx 
%08lx %08lx]\n",
+         wmd ? wmd->wDeviceID : uDevID, MCI_MessageToString(wMsg), dwFlags,
+         data.dw[0], data.dw[1], data.dw[2], data.dw[3], data.dw[4],
+         data.dw[5], data.dw[6], data.dw[7], data.dw[8], data.dw[9]);
 
-    if (strcmpW(verb, wszOpen) == 0) {
-       if ((dwRet = MCI_FinishOpen(wmd, (LPMCI_OPEN_PARMSW)data, dwFlags)))
-           MCI_UnLoadMciDriver(wmd);
+    if (wMsg == MCI_OPEN) {
+       if ((dwRet = MCI_FinishOpen(wmd, &data.open, dwFlags)))
+           goto errCleanUp;
        /* FIXME: notification is not properly shared across two opens */
     } else {
-       dwRet = MCI_SendCommand(wmd->wDeviceID, MCI_GetMessage(lpCmd), dwFlags, 
(DWORD_PTR)data);
+       dwRet = MCI_SendCommand(wmd ? wmd->wDeviceID : uDevID, wMsg, dwFlags, 
(DWORD_PTR)&data);
     }
-    TRACE("=> 1/ %x (%s)\n", dwRet, debugstr_w(lpstrRet));
-    dwRet = MCI_HandleReturnValues(dwRet, wmd, retType, data, lpstrRet, 
uRetLen);
-    TRACE("=> 2/ %x (%s)\n", dwRet, debugstr_w(lpstrRet));
+    if (!LOWORD(dwRet)) {
+       TRACE("=> 1/ %lx (%s)\n", dwRet, debugstr_w(lpstrRet));
+       dwRet = MCI_HandleReturnValues(dwRet, wmd, retType, &data.generic, 
lpstrRet, uRetLen);
+       TRACE("=> 2/ %lx (%s)\n", dwRet, debugstr_w(lpstrRet));
+    } else
+       TRACE("=> %lx\n", dwRet);
 
 errCleanUp:
+    if (auto_open) {
+       /* PLAY and RECORD are the only known non-immediate commands */
+       if (LOWORD(dwRet) || !(wMsg == MCI_PLAY || wMsg == MCI_RECORD))
+           MCI_SendCommand(auto_open, MCI_CLOSE, 0, 0);
+       else
+           FIXME("leaking auto-open device %u\n", auto_open);
+    }
+    if (wMsg == MCI_OPEN && LOWORD(dwRet) && wmd)
+       MCI_UnLoadMciDriver(wmd);
+    HeapFree(GetProcessHeap(), 0, devType);
     HeapFree(GetProcessHeap(), 0, verb);
     return dwRet;
 }
@@ -1416,9 +1597,9 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR 
lpstrRet,
     MultiByteToWideChar( CP_ACP, 0, lpstrCommand, -1, lpwstrCommand, len );
     if (lpstrRet)
     {
+        if (uRetLen) *lpstrRet = '\0'; /* NT-w2k3 use memset(lpstrRet, 0, 
uRetLen); */
         lpwstrRet = HeapAlloc(GetProcessHeap(), 0, uRetLen * sizeof(WCHAR));
         if (!lpwstrRet) {
-            WARN("no memory\n");
             HeapFree( GetProcessHeap(), 0, lpwstrCommand );
             return MCIERR_OUT_OF_MEMORY;
         }
@@ -1444,7 +1625,7 @@ BOOL WINAPI mciExecute(LPCSTR lpstrCommand)
     ret = mciSendStringA(lpstrCommand, strRet, sizeof(strRet), 0);
     if (ret != 0) {
        if (!mciGetErrorStringA(ret, strRet, sizeof(strRet))) {
-           sprintf(strRet, "Unknown MCI error (%lu)", ret);
+           sprintf(strRet, "Unknown MCI error (%ld)", ret);
        }
        MessageBoxA(0, strRet, "Error in mciExecute()", MB_OK);
     }
@@ -1522,16 +1703,15 @@ static  DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSW 
lpParms)
     DWORD                      dwRet;
     LPWINE_MCIDRIVER           wmd = NULL;
 
-    TRACE("(%08X, %p)\n", dwParam, lpParms);
+    TRACE("(%08lX, %p)\n", dwParam, lpParms);
     if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
 
     /* only two low bytes are generic, the other ones are dev type specific */
 #define WINE_MCIDRIVER_SUPP    
(0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \
                          MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID| \
                          MCI_NOTIFY|MCI_WAIT)
-    if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0) {
-       FIXME("Unsupported yet dwFlags=%08lX\n", dwParam & 
~WINE_MCIDRIVER_SUPP);
-    }
+    if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0)
+        FIXME("Unsupported yet dwFlags=%08lX\n", dwParam);
 #undef WINE_MCIDRIVER_SUPP
 
     strDevTyp[0] = 0;
@@ -1540,10 +1720,8 @@ static   DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSW 
lpParms)
        if (dwParam & MCI_OPEN_TYPE_ID) {
            WORD uDevType = LOWORD(lpParms->lpstrDeviceType);
 
-           if (uDevType < MCI_DEVTYPE_FIRST ||
-               uDevType > MCI_DEVTYPE_LAST ||
-               !LoadStringW(hWinMM32Instance, uDevType,
-                             strDevTyp, sizeof(strDevTyp) / sizeof(WCHAR))) {
+           if (uDevType < MCI_DEVTYPE_FIRST || uDevType > MCI_DEVTYPE_LAST ||
+               !LoadStringW(hWinMM32Instance, uDevType, strDevTyp, 
ARRAY_SIZE(strDevTyp))) {
                dwRet = MCIERR_BAD_INTEGER;
                goto errCleanUp;
            }
@@ -1553,8 +1731,8 @@ static    DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSW 
lpParms)
                dwRet = MCIERR_NULL_PARAMETER_BLOCK;
                goto errCleanUp;
            }
-           strcpyW(strDevTyp, lpParms->lpstrDeviceType);
-           ptr = strchrW(strDevTyp, '!');
+           lstrcpyW(strDevTyp, lpParms->lpstrDeviceType);
+           ptr = wcschr(strDevTyp, '!');
            if (ptr) {
                /* this behavior is not documented in windows. However, since, 
in
                 * some occasions, MCI_OPEN handling is translated by WinMM into
@@ -1595,13 +1773,12 @@ static  DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSW 
lpParms)
        if (!strDevTyp[0] &&
            MCI_GetDevTypeFromFileName(lpParms->lpstrElementName,
                                       strDevTyp, sizeof(strDevTyp))) {
-            static const WCHAR wszCdAudio[] = {'C','D','A','U','D','I','O',0};
            if (GetDriveTypeW(lpParms->lpstrElementName) != DRIVE_CDROM) {
                dwRet = MCIERR_EXTENSION_NOT_FOUND;
                goto errCleanUp;
            }
            /* FIXME: this will not work if several CDROM drives are installed 
on the machine */
-           strcpyW(strDevTyp, wszCdAudio);
+           lstrcpyW(strDevTyp, L"CDAUDIO");
        }
     }
 
@@ -1624,23 +1801,17 @@ static  DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSW 
lpParms)
     }
 
     if ((dwRet = MCI_FinishOpen(wmd, lpParms, dwParam))) {
-       TRACE("Failed to open driver (MCI_OPEN_DRIVER) [%08x], closing\n", 
dwRet);
+       TRACE("Failed to open driver (MCI_OPEN_DRIVER) [%08lx], closing\n", 
dwRet);
        /* FIXME: is dwRet the correct ret code ? */
        goto errCleanUp;
     }
 
     /* only handled devices fall through */
-    TRACE("wDevID=%04X wDeviceID=%d dwRet=%d\n", wmd->wDeviceID, 
lpParms->wDeviceID, dwRet);
-
-    if (dwParam & MCI_NOTIFY)
-       mciDriverNotify((HWND)lpParms->dwCallback, wmd->wDeviceID, 
MCI_NOTIFY_SUCCESSFUL);
-
+    TRACE("wDevID=%04X wDeviceID=%d dwRet=%ld\n", wmd->wDeviceID, 
lpParms->wDeviceID, dwRet);
     return 0;
+
 errCleanUp:
     if (wmd) MCI_UnLoadMciDriver(wmd);
-
-    if (dwParam & MCI_NOTIFY)
-       mciDriverNotify((HWND)lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE);
     return dwRet;
 }
 
@@ -1652,14 +1823,10 @@ static  DWORD MCI_Close(UINT wDevID, DWORD dwParam, 
LPMCI_GENERIC_PARMS lpParms)
     DWORD              dwRet;
     LPWINE_MCIDRIVER   wmd;
 
-    TRACE("(%04x, %08X, %p)\n", wDevID, dwParam, lpParms);
+    TRACE("(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
 
     /* Every device must handle MCI_NOTIFY on its own. */
     if ((UINT16)wDevID == (UINT16)MCI_ALL_DEVICE_ID) {
-       /* FIXME: shall I notify once after all is done, or for
-        * each of the open drivers ? if the latest, which notif
-        * to return when only one fails ?
-        */
        while (MciDrivers) {
             /* Retrieve the device ID under lock, but send the message without,
              * the driver might be calling some winmm functions from another
@@ -1682,15 +1849,13 @@ static  DWORD MCI_Close(UINT wDevID, DWORD dwParam, 
LPMCI_GENERIC_PARMS lpParms)
        return MCIERR_INVALID_DEVICE_ID;
     }
 
+    if(wmd->CreatorThread != GetCurrentThreadId())
+        return MCIERR_INVALID_DEVICE_NAME;
+
     dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, 
(DWORD_PTR)lpParms);
 
     MCI_UnLoadMciDriver(wmd);
 
-    if (dwParam & MCI_NOTIFY)
-        mciDriverNotify(lpParms ? (HWND)lpParms->dwCallback : 0,
-                        wDevID,
-                        dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);
-
     return dwRet;
 }
 
@@ -1702,12 +1867,10 @@ static DWORD MCI_WriteString(LPWSTR lpDstStr, DWORD 
dstSize, LPCWSTR lpSrcStr)
     DWORD      ret = 0;
 
     if (lpSrcStr) {
-        dstSize /= sizeof(WCHAR);
-       if (dstSize <= strlenW(lpSrcStr)) {
-           lstrcpynW(lpDstStr, lpSrcStr, dstSize - 1);
+       if (dstSize <= lstrlenW(lpSrcStr)) {
            ret = MCIERR_PARAM_OVERFLOW;
        } else {
-           strcpyW(lpDstStr, lpSrcStr);
+           lstrcpyW(lpDstStr, lpSrcStr);
        }
     } else {
        *lpDstStr = 0;
@@ -1728,7 +1891,7 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
     if (lpParms == NULL)                       return 
MCIERR_NULL_PARAMETER_BLOCK;
     if (lpParms->lpstrReturn == NULL)          return MCIERR_PARAM_OVERFLOW;
 
-    TRACE("(%08x, %08X, %p[num=%d, wDevTyp=%u])\n",
+    TRACE("(%08x, %08lX, %p[num=%ld, wDevTyp=%u])\n",
          uDevID, dwFlags, lpParms, lpParms->dwNumber, lpParms->wDeviceType);
     if ((WORD)MCI_ALL_DEVICE_ID == LOWORD(uDevID))
        uDevID = MCI_ALL_DEVICE_ID; /* Be compatible with Win9x */
@@ -1754,8 +1917,8 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
                    RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
                    RegCloseKey( hKey );
                }
-               if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, 
sizeof(buf) / sizeof(buf[0]), wszSystemIni))
-                   for (s = buf; *s; s += strlenW(s) + 1) cnt++;
+               if (GetPrivateProfileStringW(L"MCI", 0, L"", buf, 
ARRAY_SIZE(buf), L"system.ini"))
+                   for (s = buf; *s; s += lstrlenW(s) + 1) cnt++;
            }
        } else {
            if (dwFlags & MCI_SYSINFO_OPEN) {
@@ -1782,7 +1945,7 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
            }
        }
        *(DWORD*)lpParms->lpstrReturn = cnt;
-       TRACE("(%d) => '%d'\n", lpParms->dwNumber, 
*(DWORD*)lpParms->lpstrReturn);
+       TRACE("(%ld) => '%ld'\n", lpParms->dwNumber, 
*(DWORD*)lpParms->lpstrReturn);
        ret = MCI_INTEGER_RETURNED;
        /* return ret; Only Win9x sends a notification in this case. */
        break;
@@ -1795,7 +1958,7 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
            ret = (uDevID == MCI_ALL_DEVICE_ID)
                ? MCIERR_CANNOT_USE_ALL : MCIERR_INVALID_DEVICE_NAME;
        }
-       TRACE("(%d) => %s\n", lpParms->dwNumber, 
debugstr_w(lpParms->lpstrReturn));
+       TRACE("(%ld) => %s\n", lpParms->dwNumber, 
debugstr_w(lpParms->lpstrReturn));
        break;
     case MCI_SYSINFO_NAME:
        s = NULL;
@@ -1818,13 +1981,13 @@ static  DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
            LeaveCriticalSection(&WINMM_cs);
            ret = s ? MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, 
s) : MCIERR_OUTOFRANGE;
        } else if (MCI_ALL_DEVICE_ID == uDevID) {
-           TRACE("MCI_SYSINFO_NAME: device #%d\n", lpParms->dwNumber);
+           TRACE("MCI_SYSINFO_NAME: device #%ld\n", lpParms->dwNumber);
            if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, wszHklmMci, 0, 
                                KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS) {
                if (RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 
                                       0, 0, 0, 0, 0, 0, 0) == ERROR_SUCCESS && 
                     lpParms->dwNumber <= cnt) {
-                   DWORD bufLen = sizeof(buf)/sizeof(buf[0]);
+                   DWORD bufLen = ARRAY_SIZE(buf);
                    if (RegEnumKeyExW(hKey, lpParms->dwNumber - 1, 
                                       buf, &bufLen, 0, 0, 0, 0) == 
ERROR_SUCCESS)
                         s = buf;
@@ -1832,9 +1995,9 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
                RegCloseKey( hKey );
            }
            if (!s) {
-               if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, 
sizeof(buf) / sizeof(buf[0]), wszSystemIni)) {
-                   for (p = buf; *p; p += strlenW(p) + 1, cnt++) {
-                        TRACE("%d: %s\n", cnt, debugstr_w(p));
+               if (GetPrivateProfileStringW(L"MCI", 0, L"", buf, 
ARRAY_SIZE(buf), L"system.ini")) {
+                   for (p = buf; *p; p += lstrlenW(p) + 1, cnt++) {
+                        TRACE("%ld: %s\n", cnt, debugstr_w(p));
                        if (cnt == lpParms->dwNumber - 1) {
                            s = p;
                            break;
@@ -1855,10 +2018,10 @@ static  DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
                ret = 0;
            }
        }
-       TRACE("(%d) => %s\n", lpParms->dwNumber, 
debugstr_w(lpParms->lpstrReturn));
+       TRACE("(%ld) => %s\n", lpParms->dwNumber, 
debugstr_w(lpParms->lpstrReturn));
        break;
     default:
-       TRACE("Unsupported flag value=%08x\n", dwFlags);
+       TRACE("Unsupported flag value=%08lx\n", dwFlags);
        ret = MCIERR_UNRECOGNIZED_KEYWORD;
     }
     if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
@@ -1871,14 +2034,17 @@ static  DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, 
LPMCI_SYSINFO_PARMSW lpParm
  */
 static DWORD MCI_Break(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
 {
-    DWORD      dwRet = 0;
+    DWORD dwRet;
 
-    if (lpParms == NULL)       return MCIERR_NULL_PARAMETER_BLOCK;
+    if (lpParms == NULL)
+        return MCIERR_NULL_PARAMETER_BLOCK;
 
-    if (dwFlags & MCI_NOTIFY)
-       mciDriverNotify((HWND)lpParms->dwCallback, wDevID,
-                        (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : 
MCI_NOTIFY_FAILURE);
+    TRACE("(%08x, %08lX, vkey %04X, hwnd %p)\n", wDevID, dwFlags,
+          lpParms->nVirtKey, lpParms->hwndBreak);
 
+    dwRet = MCI_SendCommandFrom32(wDevID, MCI_BREAK, dwFlags, 
(DWORD_PTR)lpParms);
+    if (!dwRet && (dwFlags & MCI_NOTIFY))
+        mciDriverNotify((HWND)lpParms->dwCallback, wDevID, 
MCI_NOTIFY_SUCCESSFUL);
     return dwRet;
 }
 
@@ -1887,18 +2053,19 @@ static  DWORD MCI_Break(UINT wDevID, DWORD dwFlags, 
LPMCI_BREAK_PARMS lpParms)
  */
 static DWORD MCI_Sound(UINT wDevID, DWORD dwFlags, LPMCI_SOUND_PARMSW lpParms)
 {
-    DWORD      dwRet = 0;
-
-    if (lpParms == NULL)       return MCIERR_NULL_PARAMETER_BLOCK;
-
-    if (dwFlags & MCI_SOUND_NAME)
-        dwRet = sndPlaySoundW(lpParms->lpstrSoundName, SND_SYNC) ? 
MMSYSERR_NOERROR : MMSYSERR_ERROR;
-    else
-        dwRet = MMSYSERR_ERROR; /* what should be done ??? */
-    if (dwFlags & MCI_NOTIFY)
-       mciDriverNotify((HWND)lpParms->dwCallback, wDevID,
-                        (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : 
MCI_NOTIFY_FAILURE);
+    DWORD      dwRet;
 
+    if (dwFlags & MCI_SOUND_NAME) {
+       if (lpParms == NULL)    return MCIERR_NULL_PARAMETER_BLOCK;
+       else dwRet = PlaySoundW(lpParms->lpstrSoundName, NULL,
+                               SND_ALIAS    | (dwFlags & MCI_WAIT ? SND_SYNC : 
SND_ASYNC))
+               ? 0 : MCIERR_HARDWARE;
+    } else   dwRet = PlaySoundW((LPCWSTR)SND_ALIAS_SYSTEMDEFAULT, NULL,
+                               SND_ALIAS_ID | (dwFlags & MCI_WAIT ? SND_SYNC : 
SND_ASYNC))
+               ? 0 : MCIERR_HARDWARE;
+
+    if (!dwRet && lpParms && (dwFlags & MCI_NOTIFY))
+        mciDriverNotify((HWND)lpParms->dwCallback, wDevID, 
MCI_NOTIFY_SUCCESSFUL);
     return dwRet;
 }
 
@@ -1964,7 +2131,7 @@ static LRESULT    MCI_CleanUp(LRESULT dwRet, UINT wMsg, 
DWORD_PTR dwParam2)
                LPMCI_GETDEVCAPS_PARMS  lmgp;
 
                lmgp = (LPMCI_GETDEVCAPS_PARMS)dwParam2;
-               TRACE("Changing %08x to %08x\n", lmgp->dwReturn, 
LOWORD(lmgp->dwReturn));
+               TRACE("Changing %08lx to %08x\n", lmgp->dwReturn, 
LOWORD(lmgp->dwReturn));
                lmgp->dwReturn = LOWORD(lmgp->dwReturn);
            }
            break;
@@ -1987,7 +2154,7 @@ static LRESULT    MCI_CleanUp(LRESULT dwRet, UINT wMsg, 
DWORD_PTR dwParam2)
                LPMCI_STATUS_PARMS      lsp;
 
                lsp = (LPMCI_STATUS_PARMS)dwParam2;
-               TRACE("Changing %08lx to %08x\n", lsp->dwReturn, 
LOWORD(lsp->dwReturn));
+               TRACE("Changing %08Ix to %08x\n", lsp->dwReturn, 
LOWORD(lsp->dwReturn));
                lsp->dwReturn = LOWORD(lsp->dwReturn);
            }
            break;
@@ -2008,7 +2175,7 @@ static LRESULT    MCI_CleanUp(LRESULT dwRet, UINT wMsg, 
DWORD_PTR dwParam2)
        break;
     default:
        if (HIWORD(dwRet)) {
-           FIXME("Got non null hiword for dwRet=0x%08lx for command %s\n",
+           FIXME("Got non null hiword for dwRet=0x%08Ix for command %s\n",
                  dwRet, MCI_MessageToString(wMsg));
        }
        break;
@@ -2086,7 +2253,7 @@ BOOL WINAPI mciSetDriverData(MCIDEVICEID uDeviceID, 
DWORD_PTR data)
 {
     LPWINE_MCIDRIVER   wmd;
 
-    TRACE("(%04x, %08lx)\n", uDeviceID, data);
+    TRACE("(%04x, %08Ix)\n", uDeviceID, data);
 
     wmd = MCI_GetDriver(uDeviceID);
 
@@ -2107,12 +2274,12 @@ DWORD WINAPI mciSendCommandW(MCIDEVICEID wDevID, UINT 
wMsg, DWORD_PTR dwParam1,
 {
     DWORD      dwRet;
 
-    TRACE("(%08x, %s, %08lx, %08lx)\n",
+    TRACE("(%08x, %s, %08Ix, %08Ix)\n",
          wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
 
     dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2);
     dwRet = MCI_CleanUp(dwRet, wMsg, dwParam2);
-    TRACE("=> %08x\n", dwRet);
+    TRACE("=> %08lx\n", dwRet);
     return dwRet;
 }
 
@@ -2124,14 +2291,14 @@ DWORD WINAPI mciSendCommandA(MCIDEVICEID wDevID, UINT 
wMsg, DWORD_PTR dwParam1,
     DWORD ret;
     int mapped;
 
-    TRACE("(%08x, %s, %08lx, %08lx)\n",
+    TRACE("(%08x, %s, %08Ix, %08Ix)\n",
          wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
 
     mapped = MCI_MapMsgAtoW(wMsg, dwParam1, &dwParam2);
     if (mapped == -1)
     {
         FIXME("message %04x mapping failed\n", wMsg);
-        return MMSYSERR_NOMEM;
+        return MCIERR_OUT_OF_MEMORY;
     }
     ret = mciSendCommandW(wDevID, wMsg, dwParam1, dwParam2);
     if (mapped)
@@ -2163,37 +2330,21 @@ UINT WINAPI mciGetDeviceIDW(LPCWSTR lpwstrName)
     return MCI_GetDriverFromString(lpwstrName); 
 }
 
-/******************************************************************
- *             MyUserYield
- *
- * Internal wrapper to call USER.UserYield16 (in fact through a Wine only 
export from USER32).
- */
-static void MyUserYield(void)
-{
-    HMODULE mod = GetModuleHandleA( "user32.dll" );
-    if (mod)
-    {
-        FARPROC proc = GetProcAddress( mod, "UserYield16" );
-        if (proc) proc();
-    }
-}
-
 /**************************************************************************
  *                             MCI_DefYieldProc                [internal]
  */
 static UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data)
 {
     INT16      ret;
+    MSG                msg;
 
-    TRACE("(0x%04x, 0x%08x)\n", wDevID, data);
+    TRACE("(0x%04x, 0x%08lx)\n", wDevID, data);
 
     if ((HIWORD(data) != 0 && HWND_16(GetActiveWindow()) != HIWORD(data)) ||
        (GetAsyncKeyState(LOWORD(data)) & 1) == 0) {
-       MyUserYield();
+        PeekMessageW(&msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE);
        ret = 0;
     } else {
-       MSG             msg;
-
        msg.hwnd = HWND_32(HIWORD(data));
        while (!PeekMessageW(&msg, msg.hwnd, WM_KEYFIRST, WM_KEYLAST, 
PM_REMOVE));
        ret = -1;
@@ -2208,7 +2359,7 @@ BOOL WINAPI mciSetYieldProc(MCIDEVICEID uDeviceID, 
YIELDPROC fpYieldProc, DWORD
 {
     LPWINE_MCIDRIVER   wmd;
 
-    TRACE("(%u, %p, %08x)\n", uDeviceID, fpYieldProc, dwYieldData);
+    TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
 
     if (!(wmd = MCI_GetDriver(uDeviceID))) {
        WARN("Bad uDeviceID\n");
@@ -2245,7 +2396,7 @@ UINT WINAPI mciGetDeviceIDFromElementIDW(DWORD 
dwElementID, LPCWSTR lpstrType)
     /* FIXME: that's rather strange, there is no
      * mciGetDeviceIDFromElementID32A in winmm.spec
      */
-    FIXME("(%u, %s) stub\n", dwElementID, debugstr_w(lpstrType));
+    FIXME("(%lu, %s) stub\n", dwElementID, debugstr_w(lpstrType));
     return 0;
 }
 
@@ -2278,7 +2429,7 @@ HTASK WINAPI mciGetCreatorTask(MCIDEVICEID uDeviceID)
     LPWINE_MCIDRIVER   wmd;
     HTASK ret = 0;
 
-    if ((wmd = MCI_GetDriver(uDeviceID))) ret = (HTASK)wmd->CreatorThread;
+    if ((wmd = MCI_GetDriver(uDeviceID))) ret = 
(HTASK)(DWORD_PTR)wmd->CreatorThread;
 
     TRACE("(%u) => %p\n", uDeviceID, ret);
     return ret;
@@ -2295,7 +2446,8 @@ UINT WINAPI mciDriverYield(MCIDEVICEID uDeviceID)
     TRACE("(%04x)\n", uDeviceID);
 
     if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc) {
-       MyUserYield();
+        MSG msg;
+        PeekMessageW(&msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE);
     } else {
        ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
     }
diff --git a/dll/win32/winmm/winemm.h b/dll/win32/winmm/winemm.h
index b6efa8e1160..640c8036a3c 100644
--- a/dll/win32/winmm/winemm.h
+++ b/dll/win32/winmm/winemm.h
@@ -170,9 +170,7 @@ LPWINE_MLD  MMDRV_GetRelated(HANDLE hndl, UINT srcType, 
BOOL bSrcCanBeID, UINT ds
 DWORD           MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, 
DWORD_PTR dwParam2);
 UINT           MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD_PTR 
dwParam1, DWORD_PTR dwParam2);
 
-const char*    MCI_MessageToString(UINT wMsg);
 DWORD           MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, 
DWORD_PTR dwParam2);
-LPWSTR          MCI_strdupAtoW(LPCSTR str);
 LPSTR           MCI_strdupWtoA(LPCWSTR str);
 
 const char*     WINMM_ErrorToString(MMRESULT error);
@@ -205,4 +203,9 @@ extern HANDLE psStopEvent;
 
 INT LoadRegistryMMEDrivers(char* key);
 
+// REACTOS:
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define wcsnicmp strncmpiW
+#define swprintf snprintfW
+
 #endif /* _WINEMM_H_ */

Reply via email to