--- wine-git/dlls/shell32/shlexec.c	2009-06-01 15:06:52.000000000 +0200
+++ wine-build/dlls/shell32/shlexec.c	2009-08-14 23:14:30.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,28 +1713,29 @@
 	}
 	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));
+        while((space=strchrW(buffer, ' ')))
+        {
+            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;
 		}
@@ -1747,6 +1750,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 +1760,15 @@
         wcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
         wcmdLen = len;
     }
-    strcpyW(wcmd, wszApplicationName);
+
+    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-14 22:37:53.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
 };
@@ -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)

