--- wine-git/dlls/shell32/shlexec.c	2009-06-01 15:06:52.000000000 +0200
+++ wine-build//dlls/shell32/shlexec.c	2009-08-20 14:44:31.000000000 +0200
@@ -1470,6 +1470,7 @@
  */
 static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
 {
+    static const WCHAR wQuote[] = {'\"',0};
     static const WCHAR wSpace[] = {' ',0};
     static const WCHAR wWww[] = {'w','w','w',0};
     static const WCHAR wFile[] = {'f','i','l','e',0};
@@ -1493,6 +1494,7 @@
     LPCWSTR lpFile;
     UINT_PTR retval = SE_ERR_NOASSOC;
     BOOL appKnownSingular = FALSE;
+    BOOL needs_quote;
 
     /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
     sei_tmp = *sei;
@@ -1711,32 +1713,35 @@
 	}
 	else
 	{
-	    /* If the executable name is not quoted, we have to use this search loop here,
+            /* FIXME: what versions support this? Fails on 2000/XP
+               If the executable name is not quoted, we have to use this search loop here,
 	       that in CreateProcess() is not sufficient because it does not handle shell links. */
 	    WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
-	    LPWSTR space, s;
+            LPWSTR space;
 
-	    LPWSTR beg = wszApplicationName/*sei_tmp.lpFile*/;
-	    for(s=beg; (space=strchrW(s, ' ')); s=space+1) {
-		int idx = space-sei_tmp.lpFile;
-		memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
+            lstrcpynW(buffer, wszApplicationName, sizeof(buffer)/sizeof(WCHAR));
+            space = buffer + strlenW(buffer);
+            do
+            {
+                int idx = space-buffer;
 		buffer[idx] = '\0';
 
 		/*FIXME This finds directory paths if the targeted file name contains spaces. */
 		if (SearchPathW(*sei_tmp.lpDirectory? sei_tmp.lpDirectory: NULL, buffer, wszExe, sizeof(xlpFile)/sizeof(xlpFile[0]), xlpFile, NULL))
 		{
 		    /* separate out command from parameter string */
-		    LPCWSTR p = space + 1;
+                    LPCWSTR p = wszApplicationName + idx + 1;
 
 		    while(isspaceW(*p))
 			++p;
 
 		    strcpyW(wszParameters, p);
-		    *space = '\0';
+                    wszApplicationName[idx] = '\0';
 
 		    break;
 		}
 	    }
+            while((space=strrchrW(buffer, ' ')));
 
            lstrcpynW(wfileName, sei_tmp.lpFile,sizeof(wfileName)/sizeof(WCHAR));
 	}
@@ -1747,6 +1752,9 @@
 
     wcmd = wcmdBuffer;
     len = lstrlenW(wszApplicationName) + 1;
+    needs_quote = NULL != strstrW(wszApplicationName,wSpace);
+    if(needs_quote)
+        len +=2;
     if (sei_tmp.lpParameters[0])
         len += 1 + lstrlenW(wszParameters);
     if (len > wcmdLen)
@@ -1754,7 +1762,15 @@
         wcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
         wcmdLen = len;
     }
+
+    if(needs_quote)
+    {
+        strcpyW(wcmd, wQuote);
+        strcatW(wcmd, wszApplicationName);
+        strcatW(wcmd, wQuote);
+    } else
     strcpyW(wcmd, wszApplicationName);
+
     if (sei_tmp.lpParameters[0]) {
         strcatW(wcmd, wSpace);
         strcatW(wcmd, wszParameters);
--- wine-git/dlls/shell32/tests/shlexec.c	2009-08-03 19:00:16.000000000 +0200
+++ wine-build//dlls/shell32/tests/shlexec.c	2009-08-20 15:00:40.000000000 +0200
@@ -683,6 +683,7 @@
     "%s\\masked",
     "%s\\test file.sde",
     "%s\\test file.exe",
+    "%s\\test file two.exe",
     "%s\\test2.exe",
     NULL
 };
@@ -783,7 +784,7 @@
                "%s failed: rc=%d err=%d\n", shell_call,
                rc, GetLastError());
         }
-        else todo_wine
+        else
         {
             ok(rc==test->rc, "%s failed: rc=%d err=%d\n", shell_call,
                rc, GetLastError());
@@ -1167,6 +1168,40 @@
         ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc);
         }
     }
+
+    /* the directory with the test programs contain "test file.exe"
+     * and "test file two.exe". Check we do not start the first
+     * when we specify to start the second (see bug 19666)
+     */
+    sprintf(filename, "%s\\test file.exe", tmpdir);
+    if (!CopyFile(argv0, filename, FALSE))
+    {
+        ok(0,"CopyFile(\"%s\",\"%s\",FALSE) failed\n",argv0, filename);
+        return;
+    }
+
+    sprintf(filename, "%s\\test file two.exe", tmpdir);
+    if (CopyFile(argv0, filename, FALSE))
+    {
+        rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename,
+                            params, NULL);
+        ok(rc > 32, "%s returned %d\n", shell_call, rc);
+        okChildInt("argcA", 4);
+        okChildString("argvA0", filename);
+        okChildString("argvA3", "Exec");
+
+        /* check quoted filename */
+        sprintf(filename, "\"%s\\test file two.exe\"", tmpdir);
+        rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename,
+                            params, NULL);
+        ok(rc > 32, "%s returned %d\n", shell_call, rc);
+        okChildInt("argcA", 4);
+        /* strip the quotes for the compare */
+        sprintf(filename, "%s\\test file two.exe", tmpdir);
+        okChildString("argvA0", filename);
+        okChildString("argvA3", "Exec");
+    } else
+        ok(0,"CopyFile(\"%s\",\"%s\",FALSE) failed\n", argv0, filename);
 }
 
 static void test_exes_long(void)

