Am Friday 21 August 2009 11:37:56 schrieb Alexandre Julliard:
> Stefan Leichter <stefan.leich...@camline.com> writes:
> > @@ -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
>
> Searching from the end doesn't look right. This would need a test case.

This tests needs an additional program/binary, that does not need command line 
parameters (therefore shell32_test.exe can not be used), to be build in the 
test directory.

A possible way might be to create a recource from the second program, and 
extract this during runtime, for winetest.

The source for this is attached. It misses the modifications to Makefile.in 
and to fix the build dependencies, what i did not manage.

i give up here.

Stefan
diff -uw wine-git/dlls/shell32/tests/rsrc.rc wine-mingw/dlls/shell32/tests/rsrc.rc
--- wine-git/dlls/shell32/tests/rsrc.rc	2009-06-01 15:06:52.000000000 +0200
+++ wine-mingw/dlls/shell32/tests/rsrc.rc	2009-08-21 12:52:32.000000000 +0200
@@ -26,3 +26,6 @@
 {
   1 "Folder Name Resource"
 }
+
+/* @makedep: shlexec_child.exe */
+child_program RCDATA shlexec_child.exe
diff -uw wine-git/dlls/shell32/tests/shlexec.c wine-mingw/dlls/shell32/tests/shlexec.c
--- wine-git/dlls/shell32/tests/shlexec.c	2009-08-03 19:00:16.000000000 +0200
+++ wine-mingw/dlls/shell32/tests/shlexec.c	2009-08-21 13:34:34.000000000 +0200
@@ -57,6 +57,8 @@
 static char child_file[MAX_PATH];
 static DLLVERSIONINFO dllver;
 
+/* get the shared code of shlexec.c and shlexec_child.c */
+#include "shlexec.h"
 
 /***
  *
@@ -65,14 +67,6 @@
  ***/
 static void dump_child(void);
 
-static HANDLE hEvent;
-static void init_event(const char* child_file)
-{
-    char* event_name;
-    event_name=strrchr(child_file, '\\')+1;
-    hEvent=CreateEvent(NULL, FALSE, FALSE, event_name);
-}
-
 static void strcat_param(char* str, const char* param)
 {
     if (param!=NULL)
@@ -402,26 +396,6 @@
  *
  ***/
 
-static const char* encodeA(const char* str)
-{
-    static char encoded[2*1024+1];
-    char*       ptr;
-    size_t      len,i;
-
-    if (!str) return "";
-    len = strlen(str) + 1;
-    if (len >= sizeof(encoded)/2)
-    {
-        fprintf(stderr, "string is too long!\n");
-        assert(0);
-    }
-    ptr = encoded;
-    for (i = 0; i < len; i++)
-        sprintf(&ptr[i * 2], "%02x", (unsigned char)str[i]);
-    ptr[2 * len] = '\0';
-    return ptr;
-}
-
 static unsigned decode_char(char c)
 {
     if (c >= '0' && c <= '9') return c - '0';
@@ -450,18 +424,6 @@
     return ptr;
 }
 
-static void     childPrintf(HANDLE h, const char* fmt, ...)
-{
-    va_list     valist;
-    char        buffer[1024];
-    DWORD       w;
-
-    va_start(valist, fmt);
-    vsprintf(buffer, fmt, valist);
-    va_end(valist);
-    WriteFile(h, buffer, strlen(buffer), &w, NULL);
-}
-
 static void doChild(int argc, char** argv)
 {
     char* filename;
@@ -682,7 +644,9 @@
     "%s\\masked file.shlexec",
     "%s\\masked",
     "%s\\test file.sde",
+    "%s\\test.exe",
     "%s\\test file.exe",
+    "%s\\test file two.exe",
     "%s\\test2.exe",
     NULL
 };
@@ -1147,8 +1111,15 @@
 static void test_exes(void)
 {
     char filename[MAX_PATH];
+    char filename2[MAX_PATH];
     char params[1024];
     int rc;
+    DWORD size, wsize;
+    HRSRC rsrc;
+    LPVOID rsrcbin;
+    HGLOBAL rsrch;
+    BOOL bres;
+    HANDLE hfile;
 
     sprintf(params, "shlexec \"%s\" Exec", child_file);
 
@@ -1167,6 +1138,76 @@
         ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc);
         }
     }
+
+    /* create "test.exe", "test file.exe" and "test file two.exe" in the
+     * test directory. Check the filename passed to ShellExecuteA is   
+     * started and not one of the other two files (see bug 19666)
+     */
+    rsrc = FindResourceA(GetModuleHandle(NULL), "child_program", RT_RCDATA);
+    ok(NULL != rsrc, "Resource not found %d\n", GetLastError());
+    if(!rsrc) return;
+
+    size = SizeofResource(GetModuleHandle(NULL), rsrc);
+    ok(0 != size, "SizeofResource failed %d\n", GetLastError());
+    if(!size) return;
+    
+    rsrch = LoadResource(GetModuleHandle(NULL), rsrc);
+    ok(NULL != rsrch, "LoadResource failed %d\n", GetLastError());
+    if(!rsrch) return;
+    
+    rsrcbin = LockResource(rsrch);
+    ok(NULL != rsrcbin, "LockResource failed %d\n", GetLastError());
+    if(!rsrcbin) return;
+
+    sprintf(filename, "%s\\test.exe", tmpdir);
+    hfile=CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+                     FILE_ATTRIBUTE_NORMAL, NULL);
+    ok(hfile!=INVALID_HANDLE_VALUE, "CreateFile %s failed %d\n", filename, GetLastError());
+    if (hfile==INVALID_HANDLE_VALUE) return;
+
+    bres = WriteFile(hfile, rsrcbin, size, &wsize, NULL);
+    ok(bres, "WriteFile failed %d\n", GetLastError());
+    CloseHandle(hfile);
+    if(!bres) return;
+    
+    bres = SetEnvironmentVariable("SHLEXEC_CHILD_FILE",child_file);
+    ok(bres, "SetEnvironmentVariable failed %d\n", GetLastError());
+    if(!bres) return;
+
+    sprintf(filename2, "%s\\test file.exe", tmpdir);
+    if (!CopyFile(filename, filename2, FALSE))
+    {
+        ok(0,"CopyFile(\"%s\",\"%s\",FALSE) failed\n",argv0, filename);
+        return;
+    }
+
+    sprintf(filename2, "%s\\test file two.exe", tmpdir);
+    if (CopyFile(filename, filename2, FALSE))
+    {
+        rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename2,
+                            params, NULL);
+        ok(rc > 32, "%s returned %d\n", shell_call, rc);
+        todo_wine okChildInt("argcA", 4);
+        todo_wine okChildString("argvA0", filename2);
+        todo_wine 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);
+        todo_wine okChildInt("argcA", 4);
+        /* strip the quotes for the compare */
+        sprintf(filename, "%s\\test file two.exe", tmpdir);
+        todo_wine okChildString("argvA0", filename);
+        todo_wine okChildString("argvA3", "Exec");
+
+        rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename2,
+                            "", NULL);
+        todo_wine okChildInt("argcA", 1);
+        todo_wine okChildString("argvA0", filename2);
+    } else
+        ok(0,"CopyFile(\"%s\",\"%s\",FALSE) failed\n", argv0, filename);
 }
 
 static void test_exes_long(void)
--- /dev/null	2009-08-21 10:07:07.509018817 +0200
+++ wine-mingw/dlls/shell32/tests/shlexec.h	2009-08-20 10:32:26.000000000 +0200
@@ -0,0 +1,60 @@
+/*
+ * Shared code of shlexec.c and shlexec_child.c
+ *
+ * Copyright 2005 Francois Gouget for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+static HANDLE hEvent;
+static void init_event(const char* child_file)
+{
+    char* event_name;
+    event_name=strrchr(child_file, '\\')+1;
+    hEvent=CreateEvent(NULL, FALSE, FALSE, event_name);
+}
+
+static const char* encodeA(const char* str)
+{
+    static char encoded[2*1024+1];
+    char*       ptr;
+    size_t      len,i;
+
+    if (!str) return "";
+    len = strlen(str) + 1;
+    if (len >= sizeof(encoded)/2)
+    {
+        fprintf(stderr, "string is too long!\n");
+        assert(0);
+    }
+    ptr = encoded;
+    for (i = 0; i < len; i++)
+        sprintf(&ptr[i * 2], "%02x", (unsigned char)str[i]);
+    ptr[2 * len] = '\0';
+    return ptr;
+}
+
+static void     childPrintf(HANDLE h, const char* fmt, ...)
+{
+    va_list     valist;
+    char        buffer[1024];
+    DWORD       w;
+
+    va_start(valist, fmt);
+    vsprintf(buffer, fmt, valist);
+    va_end(valist);
+    WriteFile(h, buffer, strlen(buffer), &w, NULL);
+}
+
--- /dev/null	2009-08-21 10:07:07.509018817 +0200
+++ wine-mingw/dlls/shell32/tests/shlexec_child.c	2009-08-20 10:25:00.000000000 +0200
@@ -0,0 +1,57 @@
+/*
+ * Child program for ShellExecuteEx tests requiring not command line args
+ *
+ * Copyright 2009 Stefan Leichter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "wtypes.h"
+#include "winbase.h"
+
+/* get the shared code of shlexec.c and shlexec_child.c */
+#include "shlexec.h"
+
+int main(int argc, char** argv)
+{
+    char filename[MAX_PATH];
+    HANDLE hFile;
+    DWORD i = GetEnvironmentVariableA("SHLEXEC_CHILD_FILE", filename, MAX_PATH);
+
+    if(!i || i > MAX_PATH)
+	return 1;
+
+    hFile=CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+    if (hFile == INVALID_HANDLE_VALUE)
+        return 2;
+
+    /* Arguments */
+    childPrintf(hFile, "[Arguments]\r\n");
+    childPrintf(hFile, "argcA=%u\r\n", argc);
+    for (i = 0; i < argc; i++)
+    {
+        childPrintf(hFile, "argvA%u=%s\r\n", i, encodeA(argv[i]));
+    }
+    CloseHandle(hFile);
+
+    init_event(filename);
+    SetEvent(hEvent);
+    CloseHandle(hEvent);
+
+    return 0;
+}


Reply via email to