wine/dlls/shell32 shellord.c shlexec.c
Duane Clark
dclark at akamail.com
Wed Jul 24 15:05:21 CDT 2002
Alexandre Julliard wrote:
> Duane Clark <dclark at akamail.com> writes:
>
>
>>Ouch, that version had some serious bugs. It would be much better to
>>apply the version I posted to wine-devel, which I think works pretty
>>good.
>
>
> Oops sorry, that was the one I intended to apply, I didn't notice it
> was only sent to wine-devel.
>
>
>>I can supply a diff between this version and the fixed one, if
>>desired.
>
>
> Yes please.
>
Okay, here are the diffs to get shlexec.c to a good version. shellord.c
should be fine.
-------------- next part --------------
--- dlls/shell32/shlexec.c.orig Wed Jul 24 13:01:02 2002
+++ dlls/shell32/shlexec.c Wed Jul 24 13:01:22 2002
@@ -57,7 +57,7 @@
* %S ???
* %* all following parameters (see batfile)
*/
-static void argify(char* res, int len, const char* fmt, const char* lpFile)
+static BOOL argify(char* res, int len, const char* fmt, const char* lpFile)
{
char xlpFile[1024];
BOOL done = FALSE;
@@ -97,6 +97,47 @@
*res++ = *fmt++;
}
*res = '\0';
+ return done;
+}
+
+/*************************************************************************
+ * SHELL_ExecuteA [Internal]
+ *
+ */
+static HINSTANCE SHELL_ExecuteA(char *lpCmd, LPSHELLEXECUTEINFOA sei, BOOL is32)
+{
+ STARTUPINFOA startup;
+ PROCESS_INFORMATION info;
+ HINSTANCE retval = 31;
+
+ TRACE("Execute %s from directory %s\n", lpCmd, sei->lpDirectory);
+ ZeroMemory(&startup,sizeof(STARTUPINFOA));
+ startup.cb = sizeof(STARTUPINFOA);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = sei->nShow;
+ if (is32)
+ {
+ if (CreateProcessA(NULL, lpCmd, NULL, NULL, FALSE, 0,
+ NULL, sei->lpDirectory, &startup, &info))
+ {
+ retval = (HINSTANCE)33;
+ if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
+ sei->hProcess = info.hProcess;
+ else
+ CloseHandle( info.hProcess );
+ CloseHandle( info.hThread );
+ }
+ else if ((retval = GetLastError()) >= (HINSTANCE)32)
+ {
+ FIXME("Strange error set by CreateProcess: %d\n", retval);
+ retval = (HINSTANCE)ERROR_BAD_FORMAT;
+ }
+ }
+ else
+ retval = WinExec16(lpCmd, sei->nShow);
+
+ sei->hInstApp = retval;
+ return retval;
}
/*************************************************************************
@@ -113,7 +154,7 @@
* command (it'll be used afterwards for more information
* on the operation)
*/
-static HINSTANCE SHELL_FindExecutable(LPCSTR lpFile, LPCSTR lpOperation,
+static HINSTANCE SHELL_FindExecutable(LPCSTR lpPath, LPCSTR lpFile, LPCSTR lpOperation,
LPSTR lpResult, LPSTR key)
{
char *extension = NULL; /* pointer to file extension */
@@ -140,7 +181,7 @@
return 2; /* File not found. Close enough, I guess. */
}
- if (SearchPathA(NULL, lpFile, ".exe", sizeof(xlpFile), xlpFile, NULL))
+ if (SearchPathA(lpPath, lpFile, ".exe", sizeof(xlpFile), xlpFile, NULL))
{
TRACE("SearchPathA returned non-zero\n");
lpFile = xlpFile;
@@ -298,7 +339,7 @@
*/
static unsigned dde_connect(char* key, char* start, char* ddeexec,
const char* lpFile,
- int iCmdShow, BOOL is32)
+ LPSHELLEXECUTEINFOA sei, BOOL is32)
{
char* endkey = key + strlen(key);
char app[256], topic[256], ifexec[256], res[256];
@@ -338,7 +379,7 @@
if (!hConv)
{
TRACE("Launching '%s'\n", start);
- ret = (is32) ? WinExec(start, iCmdShow) : WinExec16(start, iCmdShow);
+ ret = SHELL_ExecuteA(start, sei, is32);
if (ret < 32)
{
TRACE("Couldn't launch\n");
@@ -369,7 +410,10 @@
return ret;
}
-static HINSTANCE execute_from_key(LPSTR key, LPCSTR lpFile, INT iShowCmd, BOOL is32)
+/*************************************************************************
+ * execute_from_key [Internal]
+ */
+static HINSTANCE execute_from_key(LPSTR key, LPCSTR lpFile, LPSHELLEXECUTEINFOA sei, BOOL is32)
{
char cmd[1024] = "";
LONG cmdlen = sizeof(cmd);
@@ -391,15 +435,14 @@
if (RegQueryValueA(HKEY_CLASSES_ROOT, key, param, ¶mlen) == ERROR_SUCCESS)
{
TRACE("Got ddeexec %s => %s\n", key, param);
- retval = dde_connect(key, cmd, param, lpFile, iShowCmd, is32);
+ retval = dde_connect(key, cmd, param, lpFile, sei, is32);
}
else
{
/* Is there a replace() function anywhere? */
cmd[cmdlen] = '\0';
argify(param, sizeof(param), cmd, lpFile);
-
- retval = (is32) ? WinExec(param, iShowCmd) : WinExec16(param, iShowCmd);
+ retval = SHELL_ExecuteA(param, sei, is32);
}
}
else TRACE("ooch\n");
@@ -433,7 +476,7 @@
SetCurrentDirectoryA(lpDirectory);
}
- retval = SHELL_FindExecutable(lpFile, "open", lpResult, NULL);
+ retval = SHELL_FindExecutable(lpDirectory, lpFile, "open", lpResult, NULL);
TRACE("returning %s\n", lpResult);
if (lpDirectory)
@@ -455,24 +498,22 @@
*/
BOOL WINAPI ShellExecuteExA32 (LPSHELLEXECUTEINFOA sei, BOOL is32)
{
- CHAR szApplicationName[MAX_PATH],szCommandline[MAX_PATH],szPidl[20];
+ CHAR szApplicationName[MAX_PATH],szCommandline[MAX_PATH],szPidl[20],fileName[MAX_PATH];
LPSTR pos;
int gap, len;
- STARTUPINFOA startup;
- PROCESS_INFORMATION info;
char lpstrProtocol[256];
- LPCSTR lpFile, lpOperation;
+ LPCSTR lpFile,lpOperation;
HINSTANCE retval = 31;
- char old_dir[1024];
char cmd[1024];
- INT iShowCmd;
+ BOOL done;
- TRACE("mask=0x%08lx hwnd=0x%04x verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s incomplete\n",
+ TRACE("mask=0x%08lx hwnd=0x%04x verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
sei->fMask, sei->hwnd, debugstr_a(sei->lpVerb),
debugstr_a(sei->lpFile), debugstr_a(sei->lpParameters),
debugstr_a(sei->lpDirectory), sei->nShow,
(sei->fMask & SEE_MASK_CLASSNAME) ? debugstr_a(sei->lpClass) : "not used");
-
+
+ sei->hProcess = (HANDLE)NULL;
ZeroMemory(szApplicationName,MAX_PATH);
if (sei->lpFile)
strcpy(szApplicationName, sei->lpFile);
@@ -481,7 +522,8 @@
if (sei->lpParameters)
strcpy(szCommandline, sei->lpParameters);
- if (sei->fMask & (SEE_MASK_CLASSKEY | SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
+ if (sei->fMask & ((SEE_MASK_CLASSKEY & ~SEE_MASK_CLASSNAME) |
+ SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE |
SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
@@ -489,16 +531,6 @@
FIXME("flags ignored: 0x%08lx\n", sei->fMask);
}
- /* launch a document by fileclass like 'Wordpad.Document.1' */
- if (sei->fMask & SEE_MASK_CLASSNAME)
- {
- /* FIXME: szCommandline should not be of a fixed size. Plus MAX_PATH is way too short! */
- /* the commandline contains 'c:\Path\wordpad.exe "%1"' */
- HCR_GetExecuteCommand(sei->lpClass, (sei->lpVerb) ? sei->lpVerb : "open", szCommandline, sizeof(szCommandline));
- /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
- TRACE("SEE_MASK_CLASSNAME->'%s'\n", szCommandline);
- }
-
/* process the IDList */
if ( (sei->fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
{
@@ -525,54 +557,65 @@
}
}
}
-
+
+ if (sei->fMask & SEE_MASK_CLASSNAME)
+ {
+ /* launch a document by fileclass like 'WordPad.Document.1' */
+ /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
+ /* FIXME: szCommandline should not be of a fixed size. Plus MAX_PATH is way too short! */
+ HCR_GetExecuteCommand(sei->lpClass, (sei->lpVerb) ? sei->lpVerb : "open", szCommandline, sizeof(szCommandline));
+ /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
+ TRACE("SEE_MASK_CLASSNAME->'%s', doc->'%s'\n", szCommandline, szApplicationName);
+
+ cmd[0] = '\0';
+ done = argify(cmd, sizeof(cmd), szCommandline, szApplicationName);
+ if (!done && szApplicationName[0])
+ {
+ strcat(cmd, " ");
+ strcat(cmd, szApplicationName);
+ }
+ retval = SHELL_ExecuteA(cmd, sei, is32);
+ if (retval > 32)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ /* We set the default to open, and that should generally work.
+ But that is not really the way the MS docs say to do it. */
+ if (sei->lpVerb == NULL)
+ lpOperation = "open";
+ else
+ lpOperation = sei->lpVerb;
+
+ /* Else, try to execute the filename */
TRACE("execute:'%s','%s'\n",szApplicationName, szCommandline);
+ strcpy(fileName, szApplicationName);
+ lpFile = fileName;
if (szCommandline[0]) {
strcat(szApplicationName, " ");
strcat(szApplicationName, szCommandline);
}
- ZeroMemory(&startup,sizeof(STARTUPINFOA));
- startup.cb = sizeof(STARTUPINFOA);
-
- if (CreateProcessA(NULL, szApplicationName,
- NULL, NULL, FALSE, 0,
- NULL, sei->lpDirectory,
- &startup, &info))
- {
- sei->hInstApp = 33;
- if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
- sei->hProcess = info.hProcess;
- else
- CloseHandle( info.hProcess );
- CloseHandle( info.hThread );
+ retval = SHELL_ExecuteA(szApplicationName, sei, is32);
+ if (retval > 32)
return TRUE;
- }
-
- if (sei->lpVerb == NULL) /* default is open */
- lpOperation = "open";
- else
- lpOperation = sei->lpVerb;
- lpFile = sei->lpFile;
- iShowCmd = sei->nShow;
- if (sei->lpDirectory)
- {
- GetCurrentDirectoryA(sizeof(old_dir), old_dir);
- SetCurrentDirectoryA(sei->lpDirectory);
- }
-
+ /* Else, try to find the executable */
cmd[0] = '\0';
- retval = SHELL_FindExecutable(lpFile, lpOperation, cmd, lpstrProtocol);
-
+ retval = SHELL_FindExecutable(sei->lpDirectory, lpFile, lpOperation, cmd, lpstrProtocol);
if (retval > 32) /* Found */
{
- TRACE("%s/%s => %s/%s\n", lpFile, lpOperation, cmd, lpstrProtocol);
+ if (szCommandline[0]) {
+ strcat(cmd, " ");
+ strcat(cmd, szCommandline);
+ }
+ TRACE("%s/%s => %s/%s\n", szApplicationName, lpOperation, cmd, lpstrProtocol);
if (*lpstrProtocol)
- retval = execute_from_key(lpstrProtocol, lpFile, iShowCmd, is32);
- else
- retval = (is32) ? WinExec(cmd, iShowCmd) : WinExec16(cmd, iShowCmd);
+ retval = execute_from_key(lpstrProtocol, szApplicationName, sei, is32);
+ else
+ retval = SHELL_ExecuteA(cmd, sei, is32);
}
else if (PathIsURLA((LPSTR)lpFile)) /* File not found, check for URL */
{
@@ -601,7 +644,7 @@
lpFile += iSize;
while (*lpFile == ':') lpFile++;
}
- retval = execute_from_key(lpstrProtocol, lpFile, iShowCmd, is32);
+ retval = execute_from_key(lpstrProtocol, lpFile, sei, is32);
}
/* Check if file specified is in the form www.??????.*** */
else if (!strncasecmp(lpFile, "www", 3))
@@ -612,9 +655,6 @@
retval = ShellExecuteA(sei->hwnd, lpOperation, lpstrTmpFile, NULL, NULL, 0);
}
- if (sei->lpDirectory)
- SetCurrentDirectoryA(old_dir);
-
if (retval <= 32)
{
sei->hInstApp = retval;
@@ -622,12 +662,6 @@
}
sei->hInstApp = 33;
-
- if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
- sei->hProcess = info.hProcess;
- else
- CloseHandle( info.hProcess );
- CloseHandle( info.hThread );
return TRUE;
}
More information about the wine-patches
mailing list