shlexec: buffer work

Aric Stewart aric at codeweavers.com
Thu Nov 2 13:43:13 CST 2006


-------------- next part --------------
>From nobody Mon Sep 17 00:00:00 2001
From: Aric Stewart <aric at codeweavers.com>
Date: Thu Nov 2 10:22:14 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(-)

ee4284e69f5a883fd101202d78b84e9d95e7aa43
diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c
index f57cb6e..9a42348 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..bbd7917 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