Add support for some other MCI_ commands and implement mciSendCommandW

Dmitry Timoshkov dmitry at baikal.ru
Tue Dec 16 09:16:22 CST 2003


Hello,

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add Unicode->ANSI MCI message mapping, implement mciSendCommandW,
    fix a bug with a window creation belonging to another hInstance,
    add support for MCI_WINDOW command in mciavi.drv, add support
    for MCI_PLAY and MCI_STOP in the MCIWndClass implementation.

diff -u cvs/hq/wine/dlls/msvideo/mciwnd.c wine/dlls/msvideo/mciwnd.c
--- cvs/hq/wine/dlls/msvideo/mciwnd.c	Tue Dec 16 16:45:47 2003
+++ wine/dlls/msvideo/mciwnd.c	Tue Dec 16 22:49:58 2003
@@ -60,7 +60,7 @@ typedef struct
         SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYMODE, (WPARAM)(info)->hWnd, (LPARAM)SendMessageW((info)->hWnd, MCIWNDM_GETMODEW, 0, 0))
 
 #define MCIWND_NOTIFY_SIZE(info) \
-    if (mwi->dwStyle & MCIWNDF_NOTIFYSIZE) \
+    if ((info)->dwStyle & MCIWNDF_NOTIFYSIZE) \
         SendMessageW((info)->hwndOwner, MCIWNDM_NOTIFYSIZE, (WPARAM)(info)->hWnd, 0);
 
 #define MCIWND_NOTIFY_ERROR(info) \
@@ -84,7 +84,16 @@ BOOL VFWAPIV MCIWndRegisterClass(HINSTAN
 {
     WNDCLASSW wc;
 
-    wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC;
+    /* Since we are going to register a class belonging to MSVFW32
+     * and later we will create windows with a different hInstance
+     * CS_GLOBALCLASS is needed. And because the second attempt
+     * to register a global class will fail we need to test whether
+     * the class was already registered.
+     */
+    if (GetClassInfoW(MSVFW32_hModule, mciWndClassW, &wc))
+        return TRUE;
+
+    wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC | CS_GLOBALCLASS;
     wc.lpfnWndProc = MCIWndProc;
     wc.cbClsExtra = 0;
     wc.cbWndExtra = sizeof(MCIWndInfo*);
@@ -189,7 +198,7 @@ static void MCIWND_UpdateText(MCIWndInfo
             case MCI_MODE_STOP: strcatW(buffer, stoppedW); break;
             case MCI_MODE_OPEN: strcatW(buffer, openW); break;
             case MCI_MODE_RECORD: strcatW(buffer, recordingW); break;
-            case MCI_MODE_SEEK:        strcatW(buffer, seekingW); break;
+            case MCI_MODE_SEEK: strcatW(buffer, seekingW); break;
             default: strcatW(buffer, unknownW); break;
         }
     }
@@ -394,7 +403,6 @@ static LRESULT WINAPI MCIWndProc(HWND hW
         MCIWND_NOTIFY_MODE(mwi);
         return 0;
 
-
     case MCIWNDM_OPENA:
         {
             UNICODE_STRING nameW;
@@ -447,13 +455,9 @@ static LRESULT WINAPI MCIWndProc(HWND hW
                 mci_devcaps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
                 mwi->lasterror = mciSendCommandW(mwi->mci, MCI_GETDEVCAPS,
                                                  MCI_GETDEVCAPS_ITEM,
-                                                (DWORD_PTR)&mci_devcaps);
+                                                 (DWORD_PTR)&mci_devcaps);
                 if (mwi->lasterror)
                 {
-                    WCHAR error_str[MAXERRORLENGTH];
-
-                    mciGetErrorStringW(mwi->lasterror, error_str, MAXERRORLENGTH);
-
                     MCIWND_NOTIFY_ERROR(mwi);
                     goto end_of_mci_open;
                 }
@@ -486,10 +490,8 @@ static LRESULT WINAPI MCIWndProc(HWND hW
             if (!(mwi->dwStyle & MCIWNDF_NOPLAYBAR))
                 rc.bottom += 32; /* add the height of the playbar */
             SetWindowPos(hWnd, 0, 0, 0, rc.right - rc.left,
-                rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER);
+                rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 
-            if (mwi->dwStyle & MCIWNDF_NOOPEN)
-                ShowWindow(mwi->hWnd, SW_SHOW);
             MCIWND_NOTIFY_MEDIA(mwi);
 
             SendDlgItemMessageW(hWnd, CTL_TRACKBAR, TBM_SETRANGEMIN, 0L, 0L);
@@ -670,6 +672,27 @@ end_of_mci_open:
         mwi->hwndOwner = (HWND)wParam;
         return 0;
 
+    case MCI_PLAY:
+        {
+            LRESULT end = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
+            return SendMessageW(hWnd, MCIWNDM_PLAYTO, 0, end);
+        }
+
+    case MCI_STOP:
+        {
+            MCI_GENERIC_PARMS mci_generic;
+
+            mci_generic.dwCallback = 0;
+            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_STOP, 0, (DWORD_PTR)&mci_generic);
+
+            if (mwi->lasterror)
+            {
+                MCIWND_NOTIFY_ERROR(mwi);
+                return mwi->lasterror;
+            }
+            return 0;
+        }
+
     case MCI_SEEK:
         {
             MCI_SEEK_PARMS mci_seek;
@@ -697,15 +720,19 @@ end_of_mci_open:
         }
 
     case MCI_CLOSE:
-        if (mwi->mci)
         {
             MCI_GENERIC_PARMS mci_generic;
 
             mci_generic.dwCallback = 0;
-            mciSendCommandW(mwi->mci, MCI_CLOSE, 0, (DWORD_PTR)&mci_generic);
-            mwi->mci = 0;
+            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_CLOSE, 0, (DWORD_PTR)&mci_generic);
+
+            if (mwi->lasterror)
+            {
+                MCIWND_NOTIFY_ERROR(mwi);
+                return mwi->lasterror;
+            }
+            return 0;
         }
-        return 0;
     }
 
     if ((wMsg >= WM_USER) && (wMsg < WM_APP))
diff -u cvs/hq/wine/dlls/winmm/mci.c wine/dlls/winmm/mci.c
--- cvs/hq/wine/dlls/winmm/mci.c	Mon Oct 20 13:17:18 2003
+++ wine/dlls/winmm/mci.c	Tue Dec 16 21:08:18 2003
@@ -1157,7 +1157,7 @@ BOOL WINAPI mciFreeCommandResource(UINT 
 /**************************************************************************
  * 			MCI_SendCommandFrom32			[internal]
  */
-DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD		dwRet = MCIERR_INVALID_DEVICE_ID;
     LPWINE_MCIDRIVER	wmd = MCI_GetDriver(wDevID);
@@ -1192,7 +1192,7 @@ DWORD MCI_SendCommandFrom32(UINT wDevID,
 /**************************************************************************
  * 			MCI_SendCommandFrom16			[internal]
  */
-DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD MCI_SendCommandFrom16(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD		dwRet = MCIERR_INVALID_DEVICE_ID;
     LPWINE_MCIDRIVER	wmd = MCI_GetDriver(wDevID);
diff -u cvs/hq/wine/dlls/winmm/mciavi/info.c wine/dlls/winmm/mciavi/info.c
--- cvs/hq/wine/dlls/winmm/mciavi/info.c	Fri Oct 10 22:05:33 2003
+++ wine/dlls/winmm/mciavi/info.c	Tue Dec 16 21:50:03 2003
@@ -401,8 +401,8 @@ DWORD	MCIAVI_mciStatus(UINT wDevID, DWOR
 	    TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn);
 	    break;
 	case MCI_DGV_STATUS_HWND:
-	    lpParms->dwReturn = (DWORD)wma->hWnd;
-	    TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWnd);
+	    lpParms->dwReturn = (DWORD)wma->hWndPaint;
+	    TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint);
 	    break;
 #if 0
 	case MCI_DGV_STATUS_KEY_COLOR:
diff -u cvs/hq/wine/dlls/winmm/mciavi/mciavi.c wine/dlls/winmm/mciavi/mciavi.c
--- cvs/hq/wine/dlls/winmm/mciavi/mciavi.c	Tue Jul  1 16:18:00 2003
+++ wine/dlls/winmm/mciavi/mciavi.c	Tue Dec 16 21:49:11 2003
@@ -135,7 +135,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, 
 static	DWORD	MCIAVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
 {
     WINE_MCIAVI*	wma;
-    static WCHAR	mciAviWStr[] = {'M','C','I','A','V','I',0};
+    static const WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0};
 
     if (!modp) return 0xFFFFFFFF;
 
@@ -356,7 +356,7 @@ static	DWORD	MCIAVI_mciPlay(UINT wDevID,
     if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
 
     if (!wma->hFile)		return MCIERR_FILE_NOT_FOUND;
-    if (!wma->hWnd) 		return MCIERR_NO_WINDOW;
+    if (!wma->hWndPaint)	return MCIERR_NO_WINDOW;
 
     wma->dwStatus = MCI_MODE_PLAY;
 
@@ -365,7 +365,7 @@ static	DWORD	MCIAVI_mciPlay(UINT wDevID,
 				    (DWORD)lpParms, sizeof(MCI_PLAY_PARMS));
     }
 
-    ShowWindow(wma->hWnd, SW_SHOW);
+    ShowWindow(wma->hWndPaint, SW_SHOW);
 
     dwFromFrame = wma->dwCurrVideoFrame;
     dwToFrame = wma->dwPlayableVideoFrames - 1;
diff -u cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c wine/dlls/winmm/mciavi/mmoutput.c
--- cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c	Sat Nov 22 21:56:11 2003
+++ wine/dlls/winmm/mciavi/mmoutput.c	Tue Dec 16 21:50:36 2003
@@ -575,9 +575,9 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm
 	return FALSE;
     }
 
-    if (IsWindowVisible(wma->hWnd) && (hDC = GetDC(wma->hWnd)) != 0) {
+    if (IsWindowVisible(wma->hWndPaint) && (hDC = GetDC(wma->hWndPaint)) != 0) {
 	MCIAVI_PaintFrame(wma, hDC);
-	ReleaseDC(wma->hWnd, hDC);
+	ReleaseDC(wma->hWndPaint, hDC);
     }
 
     LeaveCriticalSection(&wma->cs);
diff -u cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h wine/dlls/winmm/mciavi/private_mciavi.h
--- cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h	Tue Sep  9 15:36:29 2003
+++ wine/dlls/winmm/mciavi/private_mciavi.h	Tue Dec 16 21:46:35 2003
@@ -72,7 +72,7 @@ typedef struct {
     HANDLE		hEvent;			/* for synchronization */
     DWORD		dwEventCount;		/* for synchronization */
     /* data for play back */
-    HWND		hWnd;
+    HWND		hWnd, hWndPaint;
     DWORD		dwCurrVideoFrame;	/* video frame to display and current position */
     DWORD		dwCurrAudioBlock;	/* current audio block being played */
     /* data for the background mechanism */
diff -u cvs/hq/wine/dlls/winmm/mciavi/wnd.c wine/dlls/winmm/mciavi/wnd.c
--- cvs/hq/wine/dlls/winmm/mciavi/wnd.c	Sat Oct  4 15:30:08 2003
+++ wine/dlls/winmm/mciavi/wnd.c	Tue Dec 16 22:11:23 2003
@@ -87,6 +87,7 @@ BOOL    MCIAVI_CreateWindow(WINE_MCIAVI*
     HWND	hParent = 0;
     DWORD	dwStyle = WS_OVERLAPPEDWINDOW;
     int		p = CW_USEDEFAULT;
+    RECT rc;
 
     /* what should be done ? */
     if (wma->hWnd) return TRUE;
@@ -106,11 +107,17 @@ BOOL    MCIAVI_CreateWindow(WINE_MCIAVI*
     if (dwFlags & MCI_DGV_OPEN_WS)	dwStyle = lpOpenParms->dwStyle;
     if (dwStyle & WS_CHILD)		p = 0;
 
+    rc.left = p;
+    rc.top = p;
+    rc.right = (wma->hic ? wma->outbih : wma->inbih)->biWidth;
+    rc.bottom = (wma->hic ? wma->outbih : wma->inbih)->biHeight;
+    AdjustWindowRect(&rc, dwStyle, FALSE);
+
     wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player",
-			      dwStyle, p, p,
-			      (wma->hic ? wma->outbih : wma->inbih)->biWidth,
-			      (wma->hic ? wma->outbih : wma->inbih)->biHeight,
+			      dwStyle, rc.left, rc.top,
+			      rc.right, rc.bottom,
 			      hParent, 0, MCIAVI_hInstance, wma);
+    wma->hWndPaint = wma->hWnd;
     return (BOOL)wma->hWnd;
 }
 
@@ -193,7 +200,7 @@ DWORD	MCIAVI_mciWhere(UINT wDevID, DWORD
     }
     if (dwFlags & MCI_DGV_WHERE_WINDOW) {
 	x = "Window";
-	GetClientRect(wma->hWnd, &lpParms->rc);
+	GetClientRect(wma->hWndPaint, &lpParms->rc);
     }
     TRACE("%s -> (%ld,%ld,%ld,%ld)\n",
 	  x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom);
@@ -214,20 +221,18 @@ DWORD	MCIAVI_mciWindow(UINT wDevID, DWOR
     if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
 
     if (dwFlags & MCI_DGV_WINDOW_HWND) {
-	FIXME("Setting hWnd to %08lx\n", (DWORD)lpParms->hWnd);
-#if 0
-	if (wma->hWnd) DestroyWindow(wma->hWnd);
-	/* is the window to be subclassed ? */
-	wma->hWnd = lpParms->hWnd;
-#endif
+	TRACE("Setting hWnd to %p\n", lpParms->hWnd);
+	if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE);
+	wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd;
+        InvalidateRect(wma->hWndPaint, NULL, FALSE);
     }
     if (dwFlags & MCI_DGV_WINDOW_STATE) {
 	TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
-	ShowWindow(wma->hWnd, lpParms->nCmdShow);
+	ShowWindow(wma->hWndPaint, lpParms->nCmdShow);
     }
     if (dwFlags & MCI_DGV_WINDOW_TEXT) {
 	TRACE("Setting caption to '%s'\n", lpParms->lpstrText);
-	SetWindowTextA(wma->hWnd, lpParms->lpstrText);
+	SetWindowTextA(wma->hWndPaint, lpParms->lpstrText);
     }
 
     return 0;
diff -u cvs/hq/wine/dlls/winmm/winmm.c wine/dlls/winmm/winmm.c
--- cvs/hq/wine/dlls/winmm/winmm.c	Tue Dec  9 22:42:50 2003
+++ wine/dlls/winmm/winmm.c	Tue Dec 16 22:39:49 2003
@@ -42,6 +42,7 @@
 #include "winternl.h"
 #include "winemm.h"
 #include "wownt32.h"
+#include "heap.h"
 
 #include "wine/debug.h"
 
@@ -707,20 +708,19 @@ UINT WINAPI auxOutMessage(UINT uDeviceID
 /**************************************************************************
  * 				mciGetErrorStringW		[WINMM.@]
  */
-BOOL WINAPI mciGetErrorStringW(DWORD wError, LPWSTR lpstrBuffer, UINT uLength)
+BOOL WINAPI mciGetErrorStringW(MCIERROR wError, LPWSTR lpstrBuffer, UINT uLength)
 {
-    LPSTR	bufstr = HeapAlloc(GetProcessHeap(), 0, uLength);
-    BOOL	ret = mciGetErrorStringA(wError, bufstr, uLength);
+    char	bufstr[MAXERRORLENGTH];
+    BOOL	ret = mciGetErrorStringA(wError, bufstr, MAXERRORLENGTH);
 
     MultiByteToWideChar( CP_ACP, 0, bufstr, -1, lpstrBuffer, uLength );
-    HeapFree(GetProcessHeap(), 0, bufstr);
     return ret;
 }
 
 /**************************************************************************
  * 				mciGetErrorStringA		[WINMM.@]
  */
-BOOL WINAPI mciGetErrorStringA(DWORD dwError, LPSTR lpstrBuffer, UINT uLength)
+BOOL WINAPI mciGetErrorStringA(MCIERROR dwError, LPSTR lpstrBuffer, UINT uLength)
 {
     BOOL		ret = FALSE;
 
@@ -738,18 +738,18 @@ BOOL WINAPI mciGetErrorStringA(DWORD dwE
 /**************************************************************************
  *			mciDriverNotify				[WINMM.@]
  */
-BOOL WINAPI mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
+BOOL WINAPI mciDriverNotify(HWND hWndCallBack, MCIDEVICEID wDevID, UINT wStatus)
 {
 
     TRACE("(%p, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
 
-    return PostMessageA(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
+    return PostMessageW(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
 }
 
 /**************************************************************************
  * 			mciGetDriverData			[WINMM.@]
  */
-DWORD WINAPI mciGetDriverData(UINT uDeviceID)
+DWORD WINAPI mciGetDriverData(MCIDEVICEID uDeviceID)
 {
     LPWINE_MCIDRIVER	wmd;
 
@@ -768,7 +768,7 @@ DWORD WINAPI mciGetDriverData(UINT uDevi
 /**************************************************************************
  * 			mciSetDriverData			[WINMM.@]
  */
-BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD data)
+BOOL WINAPI mciSetDriverData(MCIDEVICEID uDeviceID, DWORD data)
 {
     LPWINE_MCIDRIVER	wmd;
 
@@ -788,7 +788,7 @@ BOOL WINAPI mciSetDriverData(UINT uDevic
 /**************************************************************************
  * 				mciSendCommandA			[WINMM.@]
  */
-DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD WINAPI mciSendCommandA(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD	dwRet;
 
@@ -801,14 +801,177 @@ DWORD WINAPI mciSendCommandA(UINT wDevID
     return dwRet;
 }
 
+static int MCI_MapMsgWtoA(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
+{
+    switch(msg)
+    {
+    case MCI_CLOSE:
+    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_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*dwParam2;
+            MCI_OPEN_PARMSA *mci_openA;
+            DWORD_PTR *ptr;
+
+            ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_openA) + sizeof(DWORD_PTR));
+            if (!ptr) return -1;
+
+            *ptr++ = *dwParam2; /* save the previous pointer */
+            *dwParam2 = (DWORD_PTR)ptr;
+            mci_openA = (MCI_OPEN_PARMSA *)ptr;
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_openA->dwCallback = mci_openW->dwCallback;
+
+            if (dwParam1 & MCI_OPEN_TYPE)
+            {
+                if (dwParam1 & MCI_OPEN_TYPE_ID)
+                    mci_openA->lpstrDeviceType = (LPSTR)mci_openW->lpstrDeviceType;
+                else
+                    mci_openA->lpstrDeviceType = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_openW->lpstrDeviceType);
+            }
+            if (dwParam1 & MCI_OPEN_ELEMENT)
+            {
+                if (dwParam1 & MCI_OPEN_ELEMENT_ID)
+                    mci_openA->lpstrElementName = (LPSTR)mci_openW->lpstrElementName;
+                else
+                    mci_openA->lpstrElementName = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_openW->lpstrElementName);
+            }
+            if (dwParam1 & MCI_OPEN_ALIAS)
+                mci_openA->lpstrAlias = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_openW->lpstrAlias);
+        }
+        return 1;
+
+    case MCI_WINDOW:
+        if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
+        {
+            MCI_ANIM_WINDOW_PARMSW *mci_windowW = (MCI_ANIM_WINDOW_PARMSW *)*dwParam2;
+            MCI_ANIM_WINDOW_PARMSA *mci_windowA;
+
+            mci_windowA = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_windowA));
+            if (!mci_windowA) return -1;
+
+            *dwParam2 = (DWORD_PTR)mci_windowA;
+
+            mci_windowA->lpstrText = HEAP_strdupWtoA(GetProcessHeap(), 0, mci_windowW->lpstrText);
+
+            if (dwParam1 & MCI_NOTIFY)
+                mci_windowA->dwCallback = mci_windowW->dwCallback;
+            if (dwParam1 & MCI_ANIM_WINDOW_HWND)
+                mci_windowA->hWnd = mci_windowW->hWnd;
+            if (dwParam1 & MCI_ANIM_WINDOW_STATE)
+                mci_windowA->nCmdShow = mci_windowW->nCmdShow;
+
+            return 1;
+        }
+        return 0;
+
+    case MCI_INFO:
+    case MCI_SYSINFO:
+    case MCI_SAVE:
+    case MCI_LOAD:
+    case MCI_ESCAPE:
+    default:
+        FIXME("Message 0x%04x needs translation\n", msg);
+        return -1;
+    }
+    return 0;
+}
+
+static void MCI_UnmapMsgWtoA(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+{
+    switch(msg)
+    {
+    case MCI_OPEN:
+        {
+            DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
+            MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*ptr;
+            MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA *)(ptr + 1);
+
+            mci_openW->wDeviceID = mci_openA->wDeviceID;
+
+            if (dwParam1 & MCI_OPEN_TYPE)
+            {
+                if (!(dwParam1 & MCI_OPEN_TYPE_ID))
+                    HeapFree(GetProcessHeap(), 0, mci_openA->lpstrDeviceType);
+            }
+            if (dwParam1 & MCI_OPEN_ELEMENT)
+            {
+                if (!(dwParam1 & MCI_OPEN_ELEMENT_ID))
+                    HeapFree(GetProcessHeap(), 0, mci_openA->lpstrElementName);
+            }
+            if (dwParam1 & MCI_OPEN_ALIAS)
+                HeapFree(GetProcessHeap(), 0, mci_openA->lpstrAlias);
+            HeapFree(GetProcessHeap(), 0, ptr);
+        }
+        break;
+
+    case MCI_WINDOW:
+        if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
+        {
+            MCI_ANIM_WINDOW_PARMSA *mci_windowA = (MCI_ANIM_WINDOW_PARMSA *)dwParam2;
+
+            HeapFree(GetProcessHeap(), 0, (void *)mci_windowA->lpstrText);
+            HeapFree(GetProcessHeap(), 0, mci_windowA);
+        }
+        break;
+
+    default:
+        FIXME("Message 0x%04x needs unmapping\n", msg);
+        break;
+    }
+}
+
+
 /**************************************************************************
  * 				mciSendCommandW			[WINMM.@]
+ *
+ * FIXME: we should do the things other way around, but since our
+ * MM subsystem is not unicode aware...
  */
-DWORD WINAPI mciSendCommandW(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+DWORD WINAPI mciSendCommandW(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
-    FIXME("(%08x, %s, %08lx, %08lx): stub\n",
+    DWORD ret;
+    int mapped;
+
+    TRACE("(%08x, %s, %08lx, %08lx)\n",
 	  wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
-    return MCIERR_UNSUPPORTED_FUNCTION;
+
+    mapped = MCI_MapMsgWtoA(wMsg, dwParam1, &dwParam2);
+    if (mapped == -1)
+    {
+        FIXME("message %04x mapping failed\n", wMsg);
+        return MMSYSERR_NOMEM;
+    }
+    ret = mciSendCommandA(wDevID, wMsg, dwParam1, dwParam2);
+    if (mapped)
+        MCI_UnmapMsgWtoA(wMsg, dwParam1, dwParam2);
+    return ret;
 }
 
 /**************************************************************************
@@ -864,7 +1027,7 @@ UINT WINAPI MCI_DefYieldProc(MCIDEVICEID
 /**************************************************************************
  * 				mciSetYieldProc			[WINMM.@]
  */
-BOOL WINAPI mciSetYieldProc(UINT uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData)
+BOOL WINAPI mciSetYieldProc(MCIDEVICEID uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData)
 {
     LPWINE_MCIDRIVER	wmd;
 
@@ -897,7 +1060,7 @@ UINT WINAPI mciGetDeviceIDFromElementIDW
 /**************************************************************************
  * 				mciGetYieldProc			[WINMM.@]
  */
-YIELDPROC WINAPI mciGetYieldProc(UINT uDeviceID, DWORD* lpdwYieldData)
+YIELDPROC WINAPI mciGetYieldProc(MCIDEVICEID uDeviceID, DWORD* lpdwYieldData)
 {
     LPWINE_MCIDRIVER	wmd;
 
@@ -921,7 +1084,7 @@ YIELDPROC WINAPI mciGetYieldProc(UINT uD
 /**************************************************************************
  * 				mciGetCreatorTask		[WINMM.@]
  */
-HTASK WINAPI mciGetCreatorTask(UINT uDeviceID)
+HTASK WINAPI mciGetCreatorTask(MCIDEVICEID uDeviceID)
 {
     LPWINE_MCIDRIVER	wmd;
     HTASK ret = 0;
@@ -935,7 +1098,7 @@ HTASK WINAPI mciGetCreatorTask(UINT uDev
 /**************************************************************************
  * 			mciDriverYield				[WINMM.@]
  */
-UINT WINAPI mciDriverYield(UINT uDeviceID)
+UINT WINAPI mciDriverYield(MCIDEVICEID uDeviceID)
 {
     LPWINE_MCIDRIVER	wmd;
     UINT		ret = 0;
diff -u cvs/hq/wine/include/mmsystem.h wine/include/mmsystem.h
--- cvs/hq/wine/include/mmsystem.h	Thu Sep 18 10:44:22 2003
+++ wine/include/mmsystem.h	Tue Dec 16 21:08:18 2003
@@ -1407,8 +1407,8 @@ MMRESULT	WINAPI	mmioCreateChunk(HMMIO,MM
 
 typedef UINT (CALLBACK *YIELDPROC)(MCIDEVICEID,DWORD);
 
-DWORD		WINAPI	mciSendCommandA(UINT,UINT,DWORD,DWORD);
-DWORD		WINAPI	mciSendCommandW(UINT,UINT,DWORD,DWORD);
+DWORD		WINAPI	mciSendCommandA(MCIDEVICEID,UINT,DWORD_PTR,DWORD_PTR);
+DWORD		WINAPI	mciSendCommandW(MCIDEVICEID,UINT,DWORD_PTR,DWORD_PTR);
 #define 		mciSendCommand WINELIB_NAME_AW(mciSendCommand)
 DWORD		WINAPI	mciSendStringA(LPCSTR,LPSTR,UINT,HWND);
 DWORD		WINAPI	mciSendStringW(LPCWSTR,LPWSTR,UINT,HWND);
@@ -1416,12 +1416,12 @@ DWORD		WINAPI	mciSendStringW(LPCWSTR,LPW
 UINT		WINAPI	mciGetDeviceIDA(LPCSTR);
 UINT		WINAPI	mciGetDeviceIDW(LPCWSTR);
 #define 		mciGetDeviceID WINELIB_NAME_AW(mciGetDeviceID)
-BOOL		WINAPI	mciGetErrorStringA(DWORD,LPSTR,UINT);
-BOOL		WINAPI	mciGetErrorStringW(DWORD,LPWSTR,UINT);
+BOOL		WINAPI	mciGetErrorStringA(MCIERROR,LPSTR,UINT);
+BOOL		WINAPI	mciGetErrorStringW(MCIERROR,LPWSTR,UINT);
 #define 		mciGetErrorString WINELIB_NAME_AW(mciGetErrorString)
-BOOL		WINAPI	mciSetYieldProc(UINT,YIELDPROC,DWORD);
-HTASK		WINAPI	mciGetCreatorTask(UINT);
-YIELDPROC	WINAPI	mciGetYieldProc(UINT,DWORD*);
+BOOL		WINAPI	mciSetYieldProc(MCIDEVICEID,YIELDPROC,DWORD);
+HTASK		WINAPI	mciGetCreatorTask(MCIDEVICEID);
+YIELDPROC	WINAPI	mciGetYieldProc(MCIDEVICEID,DWORD*);
 
 #define MCIERR_INVALID_DEVICE_ID        (MCIERR_BASE + 1)
 #define MCIERR_UNRECOGNIZED_KEYWORD     (MCIERR_BASE + 3)






More information about the wine-patches mailing list