From 851ba662c66ef27b8fa87417829d3e134d349542 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Mar 2016 16:15:50 +0100
Subject: winmm: Do not crash in Win 9X mode when an invalid device ptr is
 passed to MCI_OPEN.

---
 dlls/winmm/mci.c | 40 +++++++++++++++++++---------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/dlls/winmm/mci.c b/dlls/winmm/mci.c
index b3c1882..3e58063 100644
--- a/dlls/winmm/mci.c
+++ b/dlls/winmm/mci.c
@@ -218,7 +218,7 @@ static LPWSTR MCI_strdupAtoW( LPCSTR str )
     return ret;
 }
 
-static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
+static DWORD MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
 {
     if (msg < DRV_RESERVED) return 0;
 
@@ -261,8 +261,12 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             MCI_ANIM_OPEN_PARMSW *mci_openW;
             DWORD_PTR *ptr;
 
+            if ((dwParam1 & (MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE &&
+                (GetVersion() & 0x80000000) && IsBadStringPtrA(mci_openA->lpstrDeviceType, -1))
+                return MCIERR_MISSING_COMMAND_STRING;
+
             ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD_PTR) + sizeof(*mci_openW));
-            if (!ptr) return -1;
+            if (!ptr) return MCIERR_OUT_OF_MEMORY;
 
             *ptr++ = *dwParam2; /* save the previous pointer */
             *dwParam2 = (DWORD_PTR)ptr;
@@ -292,7 +296,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             if (HIWORD(dwParam1))
                 memcpy(&mci_openW->dwStyle, &mci_openA->dwStyle, sizeof(MCI_ANIM_OPEN_PARMSW) - sizeof(MCI_OPEN_PARMSW));
         }
-        return 1;
+        return 0;
 
     case MCI_WINDOW:
         if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
@@ -301,7 +305,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             MCI_ANIM_WINDOW_PARMSW *mci_windowW;
 
             mci_windowW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_windowW));
-            if (!mci_windowW) return -1;
+            if (!mci_windowW) return MCIERR_OUT_OF_MEMORY;
 
             *dwParam2 = (DWORD_PTR)mci_windowW;
 
@@ -313,8 +317,6 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
                 mci_windowW->hWnd = mci_windowA->hWnd;
             if (dwParam1 & MCI_ANIM_WINDOW_STATE)
                 mci_windowW->nCmdShow = mci_windowA->nCmdShow;
-
-            return 1;
         }
         return 0;
 
@@ -326,7 +328,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             DWORD_PTR *ptr;
 
             ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_sysinfoW) + sizeof(DWORD_PTR));
-            if (!ptr) return -1;
+            if (!ptr) return MCIERR_OUT_OF_MEMORY;
 
             *ptr++ = *dwParam2; /* save the previous pointer */
             *dwParam2 = (DWORD_PTR)ptr;
@@ -340,7 +342,6 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             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:
@@ -350,7 +351,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             DWORD_PTR *ptr;
 
             ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_infoW) + sizeof(DWORD_PTR));
-            if (!ptr) return -1;
+            if (!ptr) return MCIERR_OUT_OF_MEMORY;
 
             *ptr++ = *dwParam2; /* save the previous pointer */
             *dwParam2 = (DWORD_PTR)ptr;
@@ -364,8 +365,8 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             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;
         }
+        return 0;
     case MCI_SAVE:
     case MCI_LOAD:
     case MCI_CAPTURE:
@@ -375,7 +376,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             MCI_OVLY_LOAD_PARMSW *mci_loadW;
 
             mci_loadW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_loadW));
-            if (!mci_loadW) return -1;
+            if (!mci_loadW) return MCIERR_OUT_OF_MEMORY;
 
             *dwParam2 = (DWORD_PTR)mci_loadW;
             if (dwParam1 & MCI_NOTIFY)
@@ -386,8 +387,8 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
                 (MCI_CAPTURE == msg && dwParam1 & MCI_DGV_CAPTURE_AT) ||
                 (MCI_RESTORE == msg && dwParam1 & MCI_DGV_RESTORE_AT))
                 mci_loadW->rc = mci_loadA->rc;
-            return 1;
         }
+        return 0;
     case MCI_SOUND:
     case MCI_ESCAPE:
         {   /* All these commands have the same layout: callback + string */
@@ -395,14 +396,14 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW;
 
             mci_vd_escapeW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_vd_escapeW));
-            if (!mci_vd_escapeW) return -1;
+            if (!mci_vd_escapeW) return MCIERR_OUT_OF_MEMORY;
 
             *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;
         }
+        return 0;
     case MCI_SETAUDIO:
     case MCI_SETVIDEO:
         if (!(dwParam1 & (MCI_DGV_SETVIDEO_QUALITY | MCI_DGV_SETVIDEO_ALG
@@ -515,7 +516,6 @@ static void MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
         break;
 
     default:
-        FIXME("Message %s needs unmapping\n", MCI_MessageToString(msg));
         break;
     }
 }
@@ -2304,20 +2304,18 @@ DWORD WINAPI mciSendCommandW(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1,
 DWORD WINAPI mciSendCommandA(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 {
     DWORD ret;
-    int mapped;
 
     TRACE("(%08x, %s, %08lx, %08lx)\n",
 	  wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
 
-    mapped = MCI_MapMsgAtoW(wMsg, dwParam1, &dwParam2);
-    if (mapped == -1)
+    ret = MCI_MapMsgAtoW(wMsg, dwParam1, &dwParam2);
+    if (ret)
     {
         FIXME("message %04x mapping failed\n", wMsg);
-        return MCIERR_OUT_OF_MEMORY;
+        return ret;
     }
     ret = mciSendCommandW(wDevID, wMsg, dwParam1, dwParam2);
-    if (mapped)
-        MCI_UnmapMsgAtoW(wMsg, dwParam1, dwParam2, ret);
+    MCI_UnmapMsgAtoW(wMsg, dwParam1, dwParam2, ret);
     return ret;
 }
 
-- 
2.7.1

