ShellExecute placeholder patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As the comment to ShellExecute states, there can be placeholders in 
commandlines retrieved from the registry. For example, MS Installer has 
this string:
[Software\\CLASSES\\Msi.Package\\shell\\Open\\command] 1024260663
@="\"C:\\WINDOWS\\SYSTEM\\msiexec.exe\" /i \"%1\" %*"

The placeholders need to be filled in before passing the command to 
CreateProcessA, and this patch attempts to do that. The escaped 
characters have already been unescaped once before this routine gets it 
(at least this applies to the escaped quotes). It allows the PKZip 
installer to run, though the installation now fails later when 
apparently trying to create file associations.

A resemblance to build_argv() is not accidental, but all mistakes are of 
course mine.

Changelog: Fill in placeholders in ShellExecuteA.

Index: dlls/shell32/shellord.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellord.c,v
retrieving revision 1.99
diff -u -r1.99 shellord.c
--- dlls/shell32/shellord.c	3 Jul 2002 21:07:36 -0000	1.99
+++ dlls/shell32/shellord.c	5 Jul 2002 03:46:34 -0000
@@ -926,6 +926,72 @@
 {	FIXME("0x%08lx 0x%08lx stub\n",x,z);
 	return 0;
 }
+
+/***********************************************************************
+ *           make_cmdline
+ *
+ *    This routine copies command to cmdline, replacing %1 or %* with
+ *    param. 
+ */
+int make_cmdline( char *cmdline, int size, char *command, char *param )
+{
+    char *s,*d,*p;
+    int in_quotes,in_quotep,bcount;
+    int i;
+    
+    if ((i=strlen(command)+strlen(param)-2) > size) {
+        ERR("Command too long, needed %d bytes\n", i);
+        return i;
+    }
+     
+    s=command;
+    d=cmdline;
+    p=param;
+    bcount=0;
+    in_quotes=0;
+    while (*s) {
+        if (*s=='\\') {
+            *d++=*s++;
+            bcount++;
+        } else if (*s=='"') {
+            if ((bcount & 1)==0) {
+                /* an unescaped quote */
+                in_quotes=!in_quotes;
+            }
+            *d++=*s++;
+            bcount=0;
+        } else if (s[0]=='%' && (s[1]=='*' || (s[1]>='1'))) {
+            if (in_quotes && *p=='"') {
+                /* already in a quote, so skip this quote pair */
+                in_quotep=1;
+                p++;
+            }
+            else
+                in_quotep=0;
+            while (*p) {
+                if (in_quotep && *p=='"') 
+                    break;
+                *d++=*p++;
+            }
+            s+=2;
+            bcount=0;
+        } else {
+            *d++=*s++;
+            bcount=0;
+        }
+    }
+    /* Append any remaining param */
+    if (*p) {
+        *d++=' ';
+        while (*p)
+            *d++=*p++;
+    }
+    
+    *d=0;
+    return 0;
+}
+
+
 /*************************************************************************
  * ShellExecuteEx				[SHELL32.291]
  *
@@ -1049,7 +1115,9 @@
                 size = 1023;
                 if (!RegQueryValueA(HKEY_LOCAL_MACHINE,key,buffer,&size))
                 {
-                    sprintf(cmdline,"%s \"%s\"",buffer,szApplicationName);
+                    TRACE("Using command : %s  parameter: %s\n",
+                       debugstr_a(buffer), debugstr_a(szApplicationName));
+                    make_cmdline(cmdline, 1023, buffer, szApplicationName);
                     if (CreateProcessA(NULL,cmdline,  NULL, NULL, FALSE, 0,
                                    NULL, sei->lpDirectory, &startup, &info))
                         failed = FALSE;

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux