resubmit: buffer work

Aric Stewart aric at codeweavers.com
Fri Nov 3 09:47:13 CST 2006


-------------- next part --------------
>From nobody Mon Sep 17 00:00:00 2001
From: Aric Stewart <aric at codeweavers.com>
Date: Fri Nov 3 09:45:50 2006 -0600
Subject: [PATCH] creating dynamic buffers for expanded enviroment strings to allow for
parameters and such longer than MAX_PATH.

With help from Michael Moss

---

 dlls/shell32/shlexec.c       |   48 +++++++++++++++++++++++++++++++++++++-----
 dlls/shell32/tests/shlexec.c |   32 ++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 6 deletions(-)

6795d2069c01ba615e55e1529f4ec55d09682402
diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c
index f57cb6e..ff1e314 100644
--- a/dlls/shell32/shlexec.c
+++ b/dlls/shell32/shlexec.c
@@ -1198,6 +1198,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW 
 
     WCHAR *wszApplicationName, wszParameters[1024], wszDir[MAX_PATH];
     DWORD dwApplicationNameLen = MAX_PATH+2;
+    DWORD len;
     SHELLEXECUTEINFOW sei_tmp;	/* modifiable copy of SHELLEXECUTEINFO struct */
     WCHAR wfileName[MAX_PATH];
     WCHAR *env;
@@ -1351,16 +1352,51 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW 
     }
 
     /* expand environment strings */
-    if (ExpandEnvironmentStringsW(sei_tmp.lpFile, buffer, MAX_PATH))
-	lstrcpyW(wszApplicationName, buffer);
+    len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
+    if (len>0)
+    {
+        LPWSTR buf;
+        buf = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
+
+        ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len+1);
+        HeapFree(GetProcessHeap(), 0, wszApplicationName);
+        dwApplicationNameLen = len+1;
+        wszApplicationName = buf;
+
+        sei_tmp.lpFile = wszApplicationName;
+    }
 
     if (*sei_tmp.lpParameters)
-        if (ExpandEnvironmentStringsW(sei_tmp.lpParameters, buffer, MAX_PATH))
-	    lstrcpyW(wszParameters, buffer);
+    {
+        len = ExpandEnvironmentStringsW(sei_tmp.lpParameters, NULL, 0);
+        if (len > 0)
+        {
+            LPWSTR buf;
+            len++;
+            buf = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
+            ExpandEnvironmentStringsW(sei_tmp.lpParameters, buf, len);
+            if (len > 1024)
+                ERR("Parameters exceeds buffer size (%i > 1024)\n",len);
+            lstrcpynW(wszParameters, buf, min(1024,len));
+            HeapFree(GetProcessHeap(),0,buf);
+        }
+    }
 
     if (*sei_tmp.lpDirectory)
-	if (ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buffer, MAX_PATH))
-	    lstrcpyW(wszDir, buffer);
+    {
+        len = ExpandEnvironmentStringsW(sei_tmp.lpDirectory, NULL, 0);
+        if (len > 0)
+        {
+            LPWSTR buf;
+            len++;
+            buf = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
+            ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buf, len);
+            if (len > 1024)
+                ERR("Directory exceeds buffer size (%i > 1024)\n",len);
+            lstrcpynW(wszDir, buf, min(1024,len));
+            HeapFree(GetProcessHeap(),0,buf);
+        }
+    }
 
     /* Else, try to execute the filename */
     TRACE("execute:%s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index b22bf2f..bed6fd8 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -813,6 +813,37 @@ static void test_exes(void)
     }
 }
 
+static void test_exes_long(void)
+{
+    char filename[MAX_PATH];
+    char params[2024];
+    char longparam[MAX_PATH];
+    int rc;
+
+    for (rc = 0; rc < MAX_PATH; rc++)
+        longparam[rc]='a'+rc%26;
+    longparam[MAX_PATH-1]=0;
+
+
+    sprintf(params, "shlexec \"%s\" %s", child_file,longparam);
+
+    /* We need NOZONECHECKS on Win2003 to block a dialog */
+    rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, argv0, params,
+                        NULL);
+    ok(rc>=32, "%s returned %d\n", shell_call, rc);
+    okChildInt("argcA", 4);
+    okChildString("argvA3", longparam);
+
+    sprintf(filename, "%s\\test file.noassoc", tmpdir);
+    if (CopyFile(argv0, filename, FALSE))
+    {
+        rc=shell_execute(NULL, filename, params, NULL);
+        todo_wine {
+        ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc);
+        }
+    }
+}
+
 
 static void init_test(void)
 {
@@ -954,6 +985,7 @@ START_TEST(shlexec)
     test_filename();
     test_lnks();
     test_exes();
+    test_exes_long();
 
     cleanup_test();
 }
-- 
1.2.4



More information about the wine-patches mailing list