Sync to Wine-20050211
Eric Pouech <pouech-eric@wanadoo.fr>
- rewrite MCI interfaces as Unicode interface (as it should be)
- made some winmm APIs rely on the Unicode version for the core
  implementation (instead of Ansi flavor)
Klemens Friedl <klemens_friedl@gmx.net>
Henning Gerhardt <henning.gerhardt@web.de>
- Spelling fixes.
Modified: trunk/reactos/lib/winmm/Makefile.in
Modified: trunk/reactos/lib/winmm/driver.c
Modified: trunk/reactos/lib/winmm/mci.c
Modified: trunk/reactos/lib/winmm/message16.c
Modified: trunk/reactos/lib/winmm/mmio.c
Modified: trunk/reactos/lib/winmm/mmsystem.c
Modified: trunk/reactos/lib/winmm/mmsystem.spec
Modified: trunk/reactos/lib/winmm/winemm.h
Modified: trunk/reactos/lib/winmm/winmm.c
Modified: trunk/reactos/lib/winmm/winmm.spec
Modified: trunk/reactos/lib/winmm/winmm_De.rc
Modified: trunk/reactos/lib/winmm/winmm_res.rc

Modified: trunk/reactos/lib/winmm/Makefile.in
--- trunk/reactos/lib/winmm/Makefile.in	2005-02-20 10:48:44 UTC (rev 13670)
+++ trunk/reactos/lib/winmm/Makefile.in	2005-02-20 11:03:14 UTC (rev 13671)
@@ -5,6 +5,7 @@
 VPATH     = @srcdir@
 MODULE    = winmm.dll
 IMPORTS   = user32 advapi32 kernel32 ntdll
+EXTRALIBS = $(LIBUNICODE)
 
 C_SRCS = \
 	driver.c \

Modified: trunk/reactos/lib/winmm/driver.c
--- trunk/reactos/lib/winmm/driver.c	2005-02-20 10:48:44 UTC (rev 13670)
+++ trunk/reactos/lib/winmm/driver.c	2005-02-20 11:03:14 UTC (rev 13671)
@@ -1,5 +1,3 @@
-/* -*- tab-width: 8; c-basic-offset: 4 -*- */
-
 /*
  * WINE Drivers functions
  *
@@ -33,15 +31,16 @@
 #include "mmddk.h"
 #include "winemm.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(driver);
 
-#define HKLM_BASE "Software\\Microsoft\\Windows NT\\CurrentVersion"
-
 static LPWINE_DRIVER   lpDrvItemList  /* = NULL */;
+static const WCHAR HKLM_BASE[] = {'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',0};
 
 WINE_MMTHREAD*  (*pFnGetMMThread16)(UINT16 h) /* = NULL */;
-LPWINE_DRIVER   (*pFnOpenDriver16)(LPCSTR,LPCSTR,LPARAM) /* = NULL */;
+LPWINE_DRIVER   (*pFnOpenDriver16)(LPCWSTR,LPCWSTR,LPARAM) /* = NULL */;
 LRESULT         (*pFnCloseDriver16)(UINT16,LPARAM,LPARAM) /* = NULL */;
 LRESULT         (*pFnSendMessage16)(UINT16,UINT,LPARAM,LPARAM) /* = NULL */;
 
@@ -207,16 +206,19 @@
  *				DRIVER_GetLibName		[internal]
  *
  */
-BOOL	DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz)
+BOOL	DRIVER_GetLibName(LPCWSTR keyName, LPCWSTR sectName, LPWSTR buf, int sz)
 {
     HKEY	hKey, hSecKey;
     DWORD	bufLen, lRet;
+    static const WCHAR wszSystemIni[] = {'S','Y','S','T','E','M','.','I','N','I',0};
+    WCHAR       wsznull = '\0';
 
-    lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_BASE, 0, KEY_QUERY_VALUE, &hKey);
+    lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, HKLM_BASE, 0, KEY_QUERY_VALUE, &hKey);
     if (lRet == ERROR_SUCCESS) {
-	lRet = RegOpenKeyExA(hKey, sectName, 0, KEY_QUERY_VALUE, &hSecKey);
+	lRet = RegOpenKeyExW(hKey, sectName, 0, KEY_QUERY_VALUE, &hSecKey);
 	if (lRet == ERROR_SUCCESS) {
-	    lRet = RegQueryValueExA(hSecKey, keyName, 0, 0, buf, &bufLen);
+            bufLen = sz;
+	    lRet = RegQueryValueExW(hSecKey, keyName, 0, 0, (void*)buf, &bufLen);
 	    RegCloseKey( hSecKey );
 	}
         RegCloseKey( hKey );
@@ -224,7 +226,7 @@
     if (lRet == ERROR_SUCCESS) return TRUE;
     /* default to system.ini if we can't find it in the registry,
      * to support native installations where system.ini is still used */
-    return GetPrivateProfileStringA(sectName, keyName, "", buf, sz, "SYSTEM.INI");
+    return GetPrivateProfileStringW(sectName, keyName, &wsznull, buf, sz, wszSystemIni);
 }
 
 /**************************************************************************
@@ -232,16 +234,16 @@
  *
  * Tries to load a 32 bit driver whose DLL's (module) name is fn
  */
-LPWINE_DRIVER	DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2)
+LPWINE_DRIVER	DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2)
 {
     LPWINE_DRIVER 	lpDrv = NULL;
     HMODULE		hModule = 0;
-    LPSTR		ptr;
+    LPWSTR		ptr;
     LPCSTR		cause = 0;
 
-    TRACE("(%s, %08lX);\n", debugstr_a(fn), lParam2);
+    TRACE("(%s, %08lX);\n", debugstr_w(fn), lParam2);
 
-    if ((ptr = strchr(fn, ' ')) != NULL) {
+    if ((ptr = strchrW(fn, ' ')) != NULL) {
 	*ptr++ = '\0';
 	while (*ptr == ' ') ptr++;
 	if (*ptr == '\0') ptr = NULL;
@@ -250,7 +252,7 @@
     lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
     if (lpDrv == NULL) {cause = "OOM"; goto exit;}
 
-    if ((hModule = LoadLibraryA(fn)) == 0) {cause = "Not a 32 bit lib"; goto exit;}
+    if ((hModule = LoadLibraryW(fn)) == 0) {cause = "Not a 32 bit lib"; goto exit;}
 
     lpDrv->d.d32.lpDrvProc = (DRIVERPROC)GetProcAddress(hModule, "DriverProc");
     if (lpDrv->d.d32.lpDrvProc == NULL) {cause = "no DriverProc"; goto exit;}
@@ -290,7 +292,7 @@
  exit:
     FreeLibrary(hModule);
     HeapFree(GetProcessHeap(), 0, lpDrv);
-    TRACE("Unable to load 32 bit module %s: %s\n", debugstr_a(fn), cause);
+    TRACE("Unable to load 32 bit module %s: %s\n", debugstr_w(fn), cause);
     return NULL;
 }
 
@@ -301,23 +303,59 @@
  * (0,1,DRV_ENABLE,0       ,0)
  * (0,1,DRV_OPEN  ,buf[256],0)
  */
-HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
+HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
 {
+    INT                 len;
+    LPWSTR 		dn = NULL;
+    LPWSTR 		sn = NULL;
+    HDRVR		ret;
+
+    if (lpDriverName)
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, NULL, 0 );
+        dn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if (!dn) return 0;
+        MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, dn, len );
+    }
+
+    if (lpSectionName)
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, NULL, 0 );
+        sn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if (!sn) return 0;
+        MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, sn, len );
+    }
+
+    ret = OpenDriver(dn, sn, lParam);
+
+    if (dn) HeapFree(GetProcessHeap(), 0, dn);
+    if (sn) HeapFree(GetProcessHeap(), 0, sn);
+    return ret;
+}
+
+/**************************************************************************
+ *				OpenDriver 		        [WINMM.@]
+ *				DrvOpen				[WINMM.@]
+ */
+HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
+{
     LPWINE_DRIVER	lpDrv = NULL;
-    char 		libName[128];
-    LPCSTR		lsn = lpSectionName;
+    WCHAR 		libName[128];
+    LPCWSTR		lsn = lpSectionName;
 
-    TRACE("(%s, %s, 0x%08lx);\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
+    TRACE("(%s, %s, 0x%08lx);\n", 
+          debugstr_w(lpDriverName), debugstr_w(lpSectionName), lParam);
 
     if (lsn == NULL) {
-	lstrcpynA(libName, lpDriverName, sizeof(libName));
+        static const WCHAR wszDrivers32[] = {'D','r','i','v','e','r','s','3','2',0};
+	lstrcpynW(libName, lpDriverName, sizeof(libName) / sizeof(WCHAR));
 
-	if ((lpDrv = DRIVER_TryOpenDriver32(libName, lParam2)))
+	if ((lpDrv = DRIVER_TryOpenDriver32(libName, lParam)))
 	    goto the_end;
-	lsn = "Drivers32";
+	lsn = wszDrivers32;
     }
     if (DRIVER_GetLibName(lpDriverName, lsn, libName, sizeof(libName)) &&
-	(lpDrv = DRIVER_TryOpenDriver32(libName, lParam2)))
+	(lpDrv = DRIVER_TryOpenDriver32(libName, lParam)))
 	goto the_end;
 
     /* now we will try a 16 bit driver (and add all the glue to make it work... which
@@ -326,12 +364,13 @@
      */
     WINMM_CheckForMMSystem();
     if (pFnOpenDriver16 &&
-        (lpDrv = pFnOpenDriver16(lpDriverName, lpSectionName, lParam2)))
+        (lpDrv = pFnOpenDriver16(lpDriverName, lpSectionName, lParam)))
     {
-        if (DRIVER_AddToList(lpDrv, 0, lParam2)) goto the_end;
+        if (DRIVER_AddToList(lpDrv, 0, lParam)) goto the_end;
         HeapFree(GetProcessHeap(), 0, lpDrv);
     }
-    TRACE("Failed to open driver %s from system.ini file, section %s\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName));
+    TRACE("Failed to open driver %s from system.ini file, section %s\n", 
+          debugstr_w(lpDriverName), debugstr_w(lpSectionName));
     return 0;
 
  the_end:
@@ -340,40 +379,6 @@
 }
 
 /**************************************************************************
- *				OpenDriver 		        [WINMM.@]
- *				DrvOpen				[WINMM.@]
- */
-HDRVR WINAPI OpenDriverW(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
-{
-    INT                 len;
-    LPSTR 		dn = NULL;
-    LPSTR 		sn = NULL;
-    HDRVR		ret;
-
-    if (lpDriverName)
-    {
-        len = WideCharToMultiByte( CP_ACP, 0, lpDriverName, -1, NULL, 0, NULL, NULL );
-        dn = HeapAlloc( GetProcessHeap(), 0, len );
-        if (!dn) return 0;
-        WideCharToMultiByte( CP_ACP, 0, lpDriverName, -1, dn, len, NULL, NULL );
-    }
-
-    if (lpSectionName)
-    {
-        len = WideCharToMultiByte( CP_ACP, 0, lpSectionName, -1, NULL, 0, NULL, NULL );
-        sn = HeapAlloc( GetProcessHeap(), 0, len );
-        if (!sn) return 0;
-        WideCharToMultiByte( CP_ACP, 0, lpSectionName, -1, sn, len, NULL, NULL );
-    }
-
-    ret = OpenDriverA(dn, sn, lParam);
-
-    HeapFree(GetProcessHeap(), 0, dn);
-    HeapFree(GetProcessHeap(), 0, sn);
-    return ret;
-}
-
-/**************************************************************************
  *			CloseDriver				[WINMM.@]
  *			DrvClose				[WINMM.@]
  */

Modified: trunk/reactos/lib/winmm/mci.c
--- trunk/reactos/lib/winmm/mci.c	2005-02-20 10:48:44 UTC (rev 13670)
+++ trunk/reactos/lib/winmm/mci.c	2005-02-20 11:03:14 UTC (rev 13671)
@@ -31,8 +31,17 @@
  * - use a default registry setting to replace the [mci] section in
  *   configuration file (layout of info in registry should be compatible
  *   with all Windows' version - which use different layouts of course)
+ * - implement automatic open
+ *      + only works on string interface, on regular devices (don't work on all
+ *        nor custom devices)
+ * - command table handling isn't thread safe
  */
 
+/* to be cross checked:
+ * - heapalloc for *sizeof(WCHAR) when needed
+ * - size of string in WCHAR or bytes? (#chars for MCI_INFO, #bytes for MCI_SYSINFO)
+ */
+
 #include "config.h"
 #include "wine/port.h"
 
@@ -49,34 +58,41 @@
 #include "winuser.h"
 #include "winnls.h"
 #include "winreg.h"
+#include "wownt32.h"
 
 #include "digitalv.h"
 #include "winemm.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mci);
 
-WINMM_MapType  (*pFnMciMapMsg16To32A)  (WORD,WORD,DWORD*) /* = NULL */;
-WINMM_MapType  (*pFnMciUnMapMsg16To32A)(WORD,WORD,DWORD) /* = NULL */;
-WINMM_MapType  (*pFnMciMapMsg32ATo16)  (WORD,WORD,DWORD,DWORD*) /* = NULL */;
-WINMM_MapType  (*pFnMciUnMapMsg32ATo16)(WORD,WORD,DWORD,DWORD) /* = NULL */;
+WINMM_MapType  (*pFnMciMapMsg16To32W)  (WORD,WORD,DWORD*) /* = NULL */;
+WINMM_MapType  (*pFnMciUnMapMsg16To32W)(WORD,WORD,DWORD) /* = NULL */;
+WINMM_MapType  (*pFnMciMapMsg32WTo16)  (WORD,WORD,DWORD,DWORD*) /* = NULL */;
+WINMM_MapType  (*pFnMciUnMapMsg32WTo16)(WORD,WORD,DWORD,DWORD) /* = NULL */;
 
 /* First MCI valid device ID (0 means error) */
 #define MCI_MAGIC 0x0001
 
 /* MCI settings */
-#define HKLM_MCI "Software\\Microsoft\\Windows NT\\CurrentVersion\\MCI"
+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};
 
 /* dup a string and uppercase it */
-inline static LPSTR str_dup_upper( LPCSTR str )
+inline static LPWSTR str_dup_upper( LPCWSTR str )
 {
-    INT len = strlen(str) + 1;
-    LPSTR p = HeapAlloc( GetProcessHeap(), 0, len );
+    INT len = (strlenW(str) + 1) * sizeof(WCHAR);
+    LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len );
     if (p)
     {
         memcpy( p, str, len );
-        CharUpperA( p );
+        CharUpperW( p );
     }
     return p;
 }
@@ -100,7 +116,7 @@
 /**************************************************************************
  * 				MCI_GetDriverFromString		[internal]
  */
-UINT	MCI_GetDriverFromString(LPCSTR lpstrName)
+UINT	MCI_GetDriverFromString(LPCWSTR lpstrName)
 {
     LPWINE_MCIDRIVER	wmd;
     UINT		ret = 0;
@@ -108,20 +124,20 @@
     if (!lpstrName)
 	return 0;
 
-    if (!lstrcmpiA(lpstrName, "ALL"))
+    if (!strcmpiW(lpstrName, wszAll))
 	return MCI_ALL_DEVICE_ID;
 
     EnterCriticalSection(&WINMM_IData->cs);
     for (wmd = WINMM_IData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
-	if (wmd->lpstrElementName && strcmp(wmd->lpstrElementName, lpstrName) == 0) {
+	if (wmd->lpstrElementName && strcmpW(wmd->lpstrElementName, lpstrName) == 0) {
 	    ret = wmd->wDeviceID;
 	    break;
 	}
-	if (wmd->lpstrDeviceType && strcasecmp(wmd->lpstrDeviceType, lpstrName) == 0) {
+	if (wmd->lpstrDeviceType && strcmpiW(wmd->lpstrDeviceType, lpstrName) == 0) {
 	    ret = wmd->wDeviceID;
 	    break;
 	}
-	if (wmd->lpstrAlias && strcasecmp(wmd->lpstrAlias, lpstrName) == 0) {
+	if (wmd->lpstrAlias && strcmpiW(wmd->lpstrAlias, lpstrName) == 0) {
 	    ret = wmd->wDeviceID;
 	    break;
 	}
@@ -134,13 +150,26 @@
 /**************************************************************************
  * 			MCI_MessageToString			[internal]
  */
-const char* MCI_MessageToString(UINT16 wMsg)
+const char* MCI_MessageToString(UINT wMsg)
 {
     static char buffer[100];
 
 #define CASE(s) case (s): return #s
 
     switch (wMsg) {
+        CASE(DRV_LOAD);
+        CASE(DRV_ENABLE);
+        CASE(DRV_OPEN);
+        CASE(DRV_CLOSE);
+        CASE(DRV_DISABLE);
+        CASE(DRV_FREE);
+        CASE(DRV_CONFIGURE);
+        CASE(DRV_QUERYCONFIGURE);
+        CASE(DRV_INSTALL);
+        CASE(DRV_REMOVE);
+        CASE(DRV_EXITSESSION);
+        CASE(DRV_EXITAPPLICATION);
+        CASE(DRV_POWER);
 	CASE(MCI_BREAK);
 	CASE(MCI_CLOSE);
 	CASE(MCI_CLOSE_DRIVER);
@@ -193,23 +222,350 @@
     }
 }
 
+LPWSTR MCI_strdupAtoW( LPCSTR str )
+{
+    LPWSTR ret;
+    INT len;
+
+    if (!str) return NULL;
+    len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+    ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+    if (ret) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+    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;
+
+    switch (msg)
+    {
+    case MCI_CLOSE:
+    case MCI_CONFIGURE:
+    case MCI_PLAY:
+    case MCI_SEEK:
+    case MCI_STOP:
+    case MCI_PAUSE:
+    case MCI_GETDEVCAPS:
+    case MCI_SPIN:
+    case MCI_SET:
+    case MCI_STEP:
+    case MCI_RECORD:
+    case MCI_BREAK:
+    case MCI_SOUND:
+    case MCI_STATUS:
+    case MCI_CUE:
+    case MCI_REALIZE:
+    case MCI_PUT:
+    case MCI_WHERE:
+    case MCI_FREEZE:
+    case MCI_UNFREEZE:
+    case MCI_CUT:
+    case MCI_COPY:
+    case MCI_PASTE:
+    case MCI_UPDATE:
+    case MCI_RESUME:
+    case MCI_DELETE:
+        return 0;
+
+    case MCI_OPEN:
+        {
+            MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA*)*dwParam2;
+            MCI_OPEN_PARMSW *mci_openW;
+            DWORD_PTR *ptr;
+
+            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD_PTR) + sizeof(*mci_openW) + 2 * sizeof(DWORD));
+            if (!ptr) return -1;
+
+            *ptr++ = *dwParam2; /* save the previous pointer */
+            *dwParam2 = (DWORD_PTR)ptr;
+            mci_openW = (MCI_OPEN_PARMSW *)ptr;
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_openW->dwCallback = mci_openA->dwCallback;
+
+            if (dwParam1 & MCI_OPEN_TYPE)
+            {
+                if (dwParam1 & MCI_OPEN_TYPE_ID)
+                    mci_openW->lpstrDeviceType = (LPWSTR)mci_openA->lpstrDeviceType;
+                else
+                    mci_openW->lpstrDeviceType = MCI_strdupAtoW(mci_openA->lpstrDeviceType);
+            }
+            if (dwParam1 & MCI_OPEN_ELEMENT)
+            {
+                if (dwParam1 & MCI_OPEN_ELEMENT_ID)
+                    mci_openW->lpstrElementName = (LPWSTR)mci_openA->lpstrElementName;
+                else
+                    mci_openW->lpstrElementName = MCI_strdupAtoW(mci_openA->lpstrElementName);
+            }
+            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));
+        }
+        return 1;
+
+    case MCI_WINDOW:
+        if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
+        {
+            MCI_ANIM_WINDOW_PARMSA *mci_windowA = (MCI_ANIM_WINDOW_PARMSA *)*dwParam2;
+            MCI_ANIM_WINDOW_PARMSW *mci_windowW;
+
+            mci_windowW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_windowW));
+            if (!mci_windowW) return -1;
+
+            *dwParam2 = (DWORD_PTR)mci_windowW;
+
+            mci_windowW->lpstrText = MCI_strdupAtoW(mci_windowA->lpstrText);
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_windowW->dwCallback = mci_windowA->dwCallback;
+            if (dwParam1 & MCI_ANIM_WINDOW_HWND)
+                mci_windowW->hWnd = mci_windowA->hWnd;
+            if (dwParam1 & MCI_ANIM_WINDOW_STATE)
+                mci_windowW->nCmdShow = mci_windowA->nCmdShow;
+
+            return 1;
+        }
+        return 0;
+
+    case MCI_SYSINFO:
+        {
+            MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)*dwParam2;
+            MCI_SYSINFO_PARMSW *mci_sysinfoW;
+            DWORD_PTR *ptr;
+
+            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_sysinfoW) + sizeof(DWORD_PTR));
+            if (!ptr) return -1;
+
+            *ptr++ = *dwParam2; /* save the previous pointer */
+            *dwParam2 = (DWORD_PTR)ptr;
+            mci_sysinfoW = (MCI_SYSINFO_PARMSW *)ptr;
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_sysinfoW->dwCallback = mci_sysinfoA->dwCallback;
+
+            mci_sysinfoW->dwRetSize = mci_sysinfoA->dwRetSize;
+            mci_sysinfoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_sysinfoW->dwRetSize);
+            mci_sysinfoW->dwNumber = mci_sysinfoA->dwNumber;
+            mci_sysinfoW->wDeviceType = mci_sysinfoA->wDeviceType;
+            return 1;
+        }
+    case MCI_INFO:
+        {
+            MCI_INFO_PARMSA *mci_infoA = (MCI_INFO_PARMSA *)*dwParam2;
+            MCI_INFO_PARMSW *mci_infoW;
+            DWORD_PTR *ptr;
+
+            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_infoW) + sizeof(DWORD_PTR));
+            if (!ptr) return -1;
+
+            *ptr++ = *dwParam2; /* save the previous pointer */
+            *dwParam2 = (DWORD_PTR)ptr;
+            mci_infoW = (MCI_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);
+            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;
+
+            mci_loadW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_loadW));
+            if (!mci_loadW) return -1;
+
+            *dwParam2 = (DWORD_PTR)mci_loadW;
+            if (dwParam1 & MCI_NOTIFY)
+                mci_loadW->dwCallback = mci_loadA->dwCallback;
+            mci_loadW->lpfilename = MCI_strdupAtoW(mci_loadA->lpfilename);
+            return 1;
+        }
+
+    case MCI_ESCAPE:
+        {
+            MCI_VD_ESCAPE_PARMSA *mci_vd_escapeA = (MCI_VD_ESCAPE_PARMSA *)*dwParam2;
+            MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW;
+
+            mci_vd_escapeW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_vd_escapeW));
+            if (!mci_vd_escapeW) return -1;
+
+            *dwParam2 = (DWORD_PTR)mci_vd_escapeW;
+            if (dwParam1 & MCI_NOTIFY)
+                mci_vd_escapeW->dwCallback = mci_vd_escapeA->dwCallback;
+            mci_vd_escapeW->lpstrCommand = MCI_strdupAtoW(mci_vd_escapeA->lpstrCommand);
+            return 1;
+        }
+    default:
+        FIXME("Message %s needs translation\n", MCI_MessageToString(msg));
+        return -1;
+    }
+}
+
+static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
+                              DWORD result)
+{
+    switch (msg)
+    {
+    case MCI_OPEN:
+        {
+            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_openA->wDeviceID = mci_openW->wDeviceID;
+
+            if (dwParam1 & MCI_OPEN_TYPE)
+            {
+                if (!(dwParam1 & MCI_OPEN_TYPE_ID))
+                    HeapFree(GetProcessHeap(), 0, mci_openW->lpstrDeviceType);
+            }
+            if (dwParam1 & MCI_OPEN_ELEMENT)
+            {
+                if (!(dwParam1 & MCI_OPEN_ELEMENT_ID))
+                    HeapFree(GetProcessHeap(), 0, mci_openW->lpstrElementName);
+            }
+            if (dwParam1 & MCI_OPEN_ALIAS)
+                HeapFree(GetProcessHeap(), 0, mci_openW->lpstrAlias);
+            HeapFree(GetProcessHeap(), 0, ptr);
+        }
+        break;
+    case MCI_WINDOW:
+        if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
+        {
+            MCI_ANIM_WINDOW_PARMSW *mci_windowW = (MCI_ANIM_WINDOW_PARMSW *)dwParam2;
+
+            HeapFree(GetProcessHeap(), 0, (void*)mci_windowW->lpstrText);
+            HeapFree(GetProcessHeap(), 0, mci_windowW);
+        }
+        break;
+
+    case MCI_SYSINFO:
+        {
+            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);
+
+            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);
+            }
+
+            HeapFree(GetProcessHeap(), 0, mci_sysinfoW->lpstrReturn);
+            HeapFree(GetProcessHeap(), 0, ptr);
+        }
+        break;
+    case MCI_INFO:
+        {
+            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);
+
+            if (!result)
+            {
+                WideCharToMultiByte(CP_ACP, 0,
+                                    mci_infoW->lpstrReturn, mci_infoW->dwRetSize / sizeof(WCHAR),
+                                    mci_infoA->lpstrReturn, mci_infoA->dwRetSize,
+                                    NULL, NULL);
+            }
+
+            HeapFree(GetProcessHeap(), 0, mci_infoW->lpstrReturn);
+            HeapFree(GetProcessHeap(), 0, ptr);
+        }
+        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;
+
+            HeapFree(GetProcessHeap(), 0, (void*)mci_loadW->lpfilename);
+            HeapFree(GetProcessHeap(), 0, mci_loadW);
+        }
+        break;
+    case MCI_ESCAPE:
+        {
+            MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW = (MCI_VD_ESCAPE_PARMSW *)dwParam2;
+
+            HeapFree(GetProcessHeap(), 0, (void*)mci_vd_escapeW->lpstrCommand);
+            HeapFree(GetProcessHeap(), 0, mci_vd_escapeW);
+        }
+        break;
+
+    default:
+        FIXME("Message %s needs unmapping\n", MCI_MessageToString(msg));
+        break;
+    }
+
+    return result;
+}
+
 /**************************************************************************
  * 				MCI_GetDevTypeFromFileName	[internal]
  */
-static	DWORD	MCI_GetDevTypeFromFileName(LPCSTR fileName, LPSTR buf, UINT len)
+static	DWORD	MCI_GetDevTypeFromFileName(LPCWSTR fileName, LPCWSTR buf, UINT len)
 {
-    LPSTR	tmp;
+    LPCWSTR	tmp;
     HKEY	hKey;
-
-    if ((tmp = strrchr(fileName, '.'))) {
-	if (RegOpenKeyExA( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\MCI Extensions",
+    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,
 			   0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS) {
 	    DWORD dwLen = len;
-	    LONG lRet = RegQueryValueExA( hKey, tmp + 1, 0, 0, buf, &dwLen ); 
+	    LONG lRet = RegQueryValueExW( hKey, tmp + 1, 0, 0, (void*)buf, &dwLen ); 
 	    RegCloseKey( hKey );
 	    if (lRet == ERROR_SUCCESS) return 0;
         }
-	TRACE("No ...\\MCI Extensions entry for '%s' found.\n", tmp);
+	TRACE("No ...\\MCI Extensions entry for %s found.\n", debugstr_w(tmp));
     }
     return MCIERR_EXTENSION_NOT_FOUND;
 }
@@ -219,9 +575,9 @@
 
 typedef struct tagWINE_MCICMDTABLE {
     UINT		uDevType;
-    LPCSTR		lpTable;
+    const BYTE*		lpTable;
     UINT		nVerbs;		/* number of verbs in command table */
-    LPCSTR*		aVerbs;		/* array of verbs to speed up the verb look up process */
+    LPCWSTR*		aVerbs;		/* array of verbs to speed up the verb look up process */
 } WINE_MCICMDTABLE, *LPWINE_MCICMDTABLE;
 
 static WINE_MCICMDTABLE S_MciCmdTable[MAX_MCICMDTABLE];
@@ -231,7 +587,8 @@
  */
 static	BOOL		MCI_IsCommandTableValid(UINT uTbl)
 {
-    LPCSTR	lmem, str;
+    const BYTE* lmem;
+    LPCWSTR     str;
     DWORD	flg;
     WORD	eid;
     int		idx = 0;
@@ -245,28 +602,26 @@
 
     lmem = S_MciCmdTable[uTbl].lpTable;
     do {
-	do {
-	    str = lmem;
-	    lmem += strlen(lmem) + 1;
-	    flg = *(const DWORD*)lmem;
-	    eid = *(const WORD*)(lmem + sizeof(DWORD));
-	    lmem += sizeof(DWORD) + sizeof(WORD);
-	    idx ++;
-	    /* EPP 	    TRACE("cmd='%s' %08lx %04x\n", str, flg, eid); */
-	    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_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;
-	    case MCI_FLAG:		if (!*str) return FALSE;					break;
-	    case MCI_END_COMMAND_LIST:	if (*str || flg) return FALSE;	idx = 0;			break;
-	    case MCI_RECT:		if (!*str || inCst) return FALSE;				break;
-	    case MCI_CONSTANT:          if (inCst) return FALSE; inCst = TRUE;				break;
-	    case MCI_END_CONSTANT:	if (*str || flg || !inCst) return FALSE; inCst = FALSE;		break;
-	    default:			return FALSE;
-	    }
-	} while (eid != MCI_END_COMMAND_LIST);
+        str = (LPCWSTR)lmem;
+        lmem += (strlenW(str) + 1) * sizeof(WCHAR);
+        flg = *(const DWORD*)lmem;
+        eid = *(const WORD*)(lmem + sizeof(DWORD));
+        lmem += sizeof(DWORD) + sizeof(WORD);
+        idx ++;
+        /* TRACE("cmd=%s %08lx %04x\n", debugstr_w(str), flg, eid); */
+        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_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;
+        case MCI_FLAG:		        if (!*str) return FALSE;				break;
+        case MCI_END_COMMAND_LIST:	if (*str || flg) return FALSE;	idx = 0;		break;
+        case MCI_RECT:		        if (!*str || inCst) return FALSE;			break;
+        case MCI_CONSTANT:              if (inCst) return FALSE; inCst = TRUE;			break;
+        case MCI_END_CONSTANT:	        if (*str || flg || !inCst) return FALSE; inCst = FALSE; break;
+        default:			return FALSE;
+        }
     } while (eid != MCI_END_COMMAND_LIST);
     return TRUE;
 }
@@ -276,8 +631,8 @@
  */
 static	BOOL		MCI_DumpCommandTable(UINT uTbl)
 {
-    LPCSTR	lmem;
-    LPCSTR	str;
+    const BYTE*	lmem;
+    LPCWSTR	str;
     DWORD	flg;
     WORD	eid;
 
@@ -289,14 +644,14 @@
     lmem = S_MciCmdTable[uTbl].lpTable;
     do {
 	do {
-	    str = lmem;
-	    lmem += strlen(lmem) + 1;
+	    str = (LPCWSTR)lmem;
+	    lmem += (strlenW(str) + 1) * sizeof(WCHAR);
 	    flg = *(const DWORD*)lmem;
 	    eid = *(const WORD*)(lmem + sizeof(DWORD));
-	    TRACE("cmd='%s' %08lx %04x\n", str, flg, eid);
+            /* TRACE("cmd=%s %08lx %04x\n", debugstr_w(str), flg, eid); */
 	    lmem += sizeof(DWORD) + sizeof(WORD);
 	} while (eid != MCI_END_COMMAND && eid != MCI_END_COMMAND_LIST);
-	TRACE(" => end of command%s\n", (eid == MCI_END_COMMAND_LIST) ? " list" : "");
+        /* EPP TRACE(" => end of command%s\n", (eid == MCI_END_COMMAND_LIST) ? " list" : ""); */
     } while (eid != MCI_END_COMMAND_LIST);
     return TRUE;
 }
@@ -308,8 +663,8 @@
 static	UINT		MCI_GetCommandTable(UINT uDevType)
 {
     UINT	uTbl;
-    char	buf[32];
-    LPCSTR	str = NULL;
+    WCHAR	buf[32];
+    LPCWSTR	str = NULL;
 
     /* first look up existing for existing devType */
     for (uTbl = 0; uTbl < MAX_MCICMDTABLE; uTbl++) {
@@ -319,15 +674,16 @@
 
     /* well try to load id */
     if (uDevType >= MCI_DEVTYPE_FIRST && uDevType <= MCI_DEVTYPE_LAST) {
-	if (LoadStringA(WINMM_IData->hWinMM32Instance, uDevType, buf, sizeof(buf))) {
+	if (LoadStringW(WINMM_IData->hWinMM32Instance, uDevType, buf, sizeof(buf) / sizeof(WCHAR))) {
 	    str = buf;
 	}
     } else if (uDevType == 0) {
-	str = "CORE";
+        static const WCHAR wszCore[] = {'C','O','R','E',0};
+	str = wszCore;
     }
     uTbl = MCI_NO_COMMAND_TABLE;
     if (str) {
-	HRSRC 	hRsrc = FindResourceA(WINMM_IData->hWinMM32Instance, str, (LPCSTR)RT_RCDATA);
+	HRSRC 	hRsrc = FindResourceW(WINMM_IData->hWinMM32Instance, str, (LPCWSTR)RT_RCDATA);
 	HANDLE	hMem = 0;
 
 	if (hRsrc) hMem = LoadResource(WINMM_IData->hWinMM32Instance, hRsrc);
@@ -335,7 +691,7 @@
 	    uTbl = MCI_SetCommandTable(LockResource(hMem), uDevType);
 	} else {
 	    WARN("No command table found in resource %p[%s]\n",
-		 WINMM_IData->hWinMM32Instance, str);
+		 WINMM_IData->hWinMM32Instance, debugstr_w(str));
 	}
     }
     TRACE("=> %d\n", uTbl);
@@ -359,10 +715,11 @@
 	bInitDone = TRUE;
 	MCI_GetCommandTable(0);
     }
-
+    TRACE("(%p, %u)\n", table, uDevType);
     for (uTbl = 0; uTbl < MAX_MCICMDTABLE; uTbl++) {
 	if (!S_MciCmdTable[uTbl].lpTable) {
-	    LPCSTR 	lmem, str;
+	    const BYTE* lmem;
+	    LPCWSTR 	str;
 	    WORD	eid;
 	    WORD	count;
 
@@ -378,21 +735,22 @@
 	    lmem = S_MciCmdTable[uTbl].lpTable;
 	    count = 0;
 	    do {
-		lmem += strlen(lmem) + 1;
+		str = (LPCWSTR)lmem;
+		lmem += (strlenW(str) + 1) * sizeof(WCHAR);
 		eid = *(const WORD*)(lmem + sizeof(DWORD));
 		lmem += sizeof(DWORD) + sizeof(WORD);
 		if (eid == MCI_COMMAND_HEAD)
 		    count++;
 	    } while (eid != MCI_END_COMMAND_LIST);
 
-	    S_MciCmdTable[uTbl].aVerbs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(LPCSTR));
+	    S_MciCmdTable[uTbl].aVerbs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(LPCWSTR));
 	    S_MciCmdTable[uTbl].nVerbs = count;
 
 	    lmem = S_MciCmdTable[uTbl].lpTable;
 	    count = 0;
 	    do {
-		str = lmem;
-		lmem += strlen(lmem) + 1;
+		str = (LPCWSTR)lmem;
+		lmem += (strlenW(str) + 1) * sizeof(WCHAR);
 		eid = *(const WORD*)(lmem + sizeof(DWORD));
 		lmem += sizeof(DWORD) + sizeof(WORD);
 		if (eid == MCI_COMMAND_HEAD)
@@ -409,11 +767,12 @@
 /**************************************************************************
  * 				MCI_DeleteCommandTable		[internal]
  */
-static	BOOL	MCI_DeleteCommandTable(UINT uTbl)
+BOOL	MCI_DeleteCommandTable(UINT uTbl, BOOL delete)
 {
     if (uTbl >= MAX_MCICMDTABLE || !S_MciCmdTable[uTbl].lpTable)
 	return FALSE;
 
+    if (delete) HeapFree(GetProcessHeap(), 0, (void*)S_MciCmdTable[uTbl].lpTable);
     S_MciCmdTable[uTbl].lpTable = NULL;
     HeapFree(GetProcessHeap(), 0, S_MciCmdTable[uTbl].aVerbs);
     S_MciCmdTable[uTbl].aVerbs = 0;
@@ -455,33 +814,33 @@
 /**************************************************************************
  * 				MCI_OpenMciDriver		[internal]
  */
-static	BOOL	MCI_OpenMciDriver(LPWINE_MCIDRIVER wmd, LPCSTR drvTyp, LPARAM lp)
+static	BOOL	MCI_OpenMciDriver(LPWINE_MCIDRIVER wmd, LPCWSTR drvTyp, LPARAM lp)
 {
-    char	libName[128];
+    WCHAR	libName[128];
 
-    if (!DRIVER_GetLibName(drvTyp, "mci", libName, sizeof(libName)))
+    if (!DRIVER_GetLibName(drvTyp, wszMci, libName, sizeof(libName)))
 	return FALSE;
 
     wmd->bIs32 = 0xFFFF;
     /* First load driver */
     if ((wmd->hDriver = (HDRVR)DRIVER_TryOpenDriver32(libName, lp))) {
 	wmd->bIs32 = TRUE;
-    } else if (WINMM_CheckForMMSystem() && pFnMciMapMsg32ATo16) {
+    } else if (WINMM_CheckForMMSystem() && pFnMciMapMsg32WTo16) {
 	WINMM_MapType 	res;
 
-	switch (res = pFnMciMapMsg32ATo16(0, DRV_OPEN, 0, &lp)) {
+	switch (res = pFnMciMapMsg32WTo16(0, DRV_OPEN, 0, &lp)) {
 	case WINMM_MAP_MSGERROR:
 	    TRACE("Not handled yet (DRV_OPEN)\n");
 	    break;
 	case WINMM_MAP_NOMEM:
-	    TRACE("Problem mapping msg=DRV_OPEN from 32a to 16\n");
+	    TRACE("Problem mapping msg=DRV_OPEN from 32W to 16\n");
 	    break;
 	case WINMM_MAP_OK:
 	case WINMM_MAP_OKMEM:
-	    if ((wmd->hDriver = OpenDriverA(drvTyp, "mci", lp)))
+	    if ((wmd->hDriver = OpenDriver(drvTyp, wszMci, lp)))
 		wmd->bIs32 = FALSE;
 	    if (res == WINMM_MAP_OKMEM)
-		pFnMciUnMapMsg32ATo16(0, DRV_OPEN, 0, lp);
+		pFnMciUnMapMsg32WTo16(0, DRV_OPEN, 0, lp);
 	    break;
 	}
     }
@@ -491,11 +850,11 @@
 /**************************************************************************
  * 				MCI_LoadMciDriver		[internal]
  */
-static	DWORD	MCI_LoadMciDriver(LPCSTR _strDevTyp, LPWINE_MCIDRIVER* lpwmd)
+static	DWORD	MCI_LoadMciDriver(LPCWSTR _strDevTyp, LPWINE_MCIDRIVER* lpwmd)
 {
-    LPSTR			strDevTyp = str_dup_upper(_strDevTyp);
+    LPWSTR			strDevTyp = str_dup_upper(_strDevTyp);
     LPWINE_MCIDRIVER		wmd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wmd));
-    MCI_OPEN_DRIVER_PARMSA	modp;
+    MCI_OPEN_DRIVER_PARMSW	modp;
     DWORD			dwRet = 0;
 
     if (!wmd || !strDevTyp) {
@@ -530,13 +889,13 @@
 	/* silence warning if all is used... some bogus program use commands like
 	 * 'open all'...
 	 */
-	if (strcasecmp(strDevTyp, "all") == 0) {
+	if (strcmpiW(strDevTyp, wszAll) == 0) {
 	    dwRet = MCIERR_CANNOT_USE_ALL;
 	} else {
 	    FIXME("Couldn't load driver for type %s.\n"
 		  "If you don't have a windows installation accessible from Wine,\n"
 		  "you perhaps forgot to create a [mci] section in system.ini\n",
-		  strDevTyp);
+		  debugstr_w(strDevTyp));
 	    dwRet = MCIERR_DEVICE_NOT_INSTALLED;
[truncated at 1000 lines; 5412 more skipped]