Commit 7b48ddcb authored by Martin Fuchs's avatar Martin Fuchs Committed by Alexandre Julliard

Enumerate all "shell\<verb>\command" entries in the registry instead

of searching only for "shell\open\command" entries.
parent 83decd25
...@@ -54,6 +54,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(exec); ...@@ -54,6 +54,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(exec);
static const WCHAR wszOpen[] = {'o','p','e','n',0}; static const WCHAR wszOpen[] = {'o','p','e','n',0};
static const WCHAR wszExe[] = {'.','e','x','e',0}; static const WCHAR wszExe[] = {'.','e','x','e',0};
static const WCHAR wszShell[] = {'\\','s','h','e','l','l','\\',0};
/*********************************************************************** /***********************************************************************
...@@ -267,6 +268,54 @@ end: ...@@ -267,6 +268,54 @@ end:
return found; return found;
} }
static UINT SHELL_FindExecutableByOperation(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation, LPWSTR key, LPWSTR filetype, LPWSTR command, LONG commandlen)
{
static const WCHAR wCommand[] = {'\\','c','o','m','m','a','n','d',0};
/* Looking for ...buffer\shell\<verb>\command */
strcatW(filetype, wszShell);
strcatW(filetype, lpOperation);
strcatW(filetype, wCommand);
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, command,
&commandlen) == ERROR_SUCCESS)
{
commandlen /= sizeof(WCHAR);
if (key) strcpyW(key, filetype);
#if 0
LPWSTR tmp;
WCHAR param[256];
LONG paramlen = sizeof(param);
static const WCHAR wSpace[] = {' ',0};
/* FIXME: it seems all Windows version don't behave the same here.
* the doc states that this ddeexec information can be found after
* the exec names.
* on Win98, it doesn't appear, but I think it does on Win2k
*/
/* Get the parameters needed by the application
from the associated ddeexec key */
tmp = strstrW(filetype, wCommand);
tmp[0] = '\0';
strcatW(filetype, wDdeexec);
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, param,
&paramlen) == ERROR_SUCCESS)
{
paramlen /= sizeof(WCHAR);
strcatW(command, wSpace);
strcatW(command, param);
commandlen += paramlen;
}
#endif
command[commandlen] = '\0';
return 33; /* FIXME see SHELL_FindExecutable() */
}
return 31; /* default - 'No association was found' */
}
/************************************************************************* /*************************************************************************
* SHELL_FindExecutable [Internal] * SHELL_FindExecutable [Internal]
* *
...@@ -284,8 +333,6 @@ end: ...@@ -284,8 +333,6 @@ end:
static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation, static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation,
LPWSTR lpResult, LPWSTR key, void **env) LPWSTR lpResult, LPWSTR key, void **env)
{ {
static const WCHAR wShell[] = {'\\','s','h','e','l','l','\\',0};
static const WCHAR wCommand[] = {'\\','c','o','m','m','a','n','d',0};
static const WCHAR wWindows[] = {'w','i','n','d','o','w','s',0}; static const WCHAR wWindows[] = {'w','i','n','d','o','w','s',0};
static const WCHAR wPrograms[] = {'p','r','o','g','r','a','m','s',0}; static const WCHAR wPrograms[] = {'p','r','o','g','r','a','m','s',0};
static const WCHAR wExtensions[] = {'e','x','e',' ','p','i','f',' ','b','a','t',' ','c','m','d',' ','c','o','m',0}; static const WCHAR wExtensions[] = {'e','x','e',' ','p','i','f',' ','b','a','t',' ','c','m','d',' ','c','o','m',0};
...@@ -294,7 +341,6 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera ...@@ -294,7 +341,6 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
WCHAR filetype[256]; /* registry name for this filetype */ WCHAR filetype[256]; /* registry name for this filetype */
LONG filetypelen = sizeof(filetype); /* length of above */ LONG filetypelen = sizeof(filetype); /* length of above */
WCHAR command[256]; /* command from registry */ WCHAR command[256]; /* command from registry */
LONG commandlen = sizeof(command); /* This is the most DOS can handle :) */
WCHAR wBuffer[256]; /* Used to GetProfileString */ WCHAR wBuffer[256]; /* Used to GetProfileString */
UINT retval = 31; /* default - 'No association was found' */ UINT retval = 31; /* default - 'No association was found' */
WCHAR *tok; /* token pointer */ WCHAR *tok; /* token pointer */
...@@ -392,46 +438,46 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera ...@@ -392,46 +438,46 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
filetypelen /= sizeof(WCHAR); filetypelen /= sizeof(WCHAR);
filetype[filetypelen] = '\0'; filetype[filetypelen] = '\0';
TRACE("File type: %s\n", debugstr_w(filetype)); TRACE("File type: %s\n", debugstr_w(filetype));
}
/* Looking for ...buffer\shell\lpOperation\command */ if (*filetype)
strcatW(filetype, wShell); {
strcatW(filetype, lpOperation); if (lpOperation)
strcatW(filetype, wCommand);
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, command,
&commandlen) == ERROR_SUCCESS)
{ {
commandlen /= sizeof(WCHAR); /* pass the operation string to SHELL_FindExecutableByOperation() */
if (key) strcpyW(key, filetype); filetype[filetypelen] = '\0';
#if 0 retval = SHELL_FindExecutableByOperation(lpPath, lpFile, lpOperation, key, filetype, command, sizeof(command));
LPWSTR tmp; }
WCHAR param[256]; else
LONG paramlen = sizeof(param); {
static const WCHAR wSpace[] = {' ',0}; WCHAR operation[MAX_PATH];
HKEY hkey;
/* FIXME: it seems all Windows version don't behave the same here.
* the doc states that this ddeexec information can be found after /* Looking for ...buffer\shell\<operation>\command */
* the exec names. strcatW(filetype, wszShell);
* on Win98, it doesn't appear, but I think it does on Win2k
*/ /* enumerate the operation subkeys in the registry and search for one with an associated command */
/* Get the parameters needed by the application if (RegOpenKeyW(HKEY_CLASSES_ROOT, filetype, &hkey) == ERROR_SUCCESS)
from the associated ddeexec key */
tmp = strstrW(filetype, wCommand);
tmp[0] = '\0';
strcatW(filetype, wDdeexec);
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, param,
&paramlen) == ERROR_SUCCESS)
{ {
paramlen /= sizeof(WCHAR); int idx = 0;
strcatW(command, wSpace); for(;; ++idx)
strcatW(command, param); {
commandlen += paramlen; if (RegEnumKeyW(hkey, idx, operation, MAX_PATH) != ERROR_SUCCESS)
break;
filetype[filetypelen] = '\0';
retval = SHELL_FindExecutableByOperation(lpPath, lpFile, operation, key, filetype, command, sizeof(command));
if (retval > 32)
break;
} }
#endif RegCloseKey(hkey);
command[commandlen] = '\0'; }
}
if (retval > 32)
{
SHELL_ArgifyW(lpResult, 1024 /*FIXME*/, command, xlpFile); SHELL_ArgifyW(lpResult, 1024 /*FIXME*/, command, xlpFile);
retval = 33; /* FIXME see above */
} }
} }
else /* Check win.ini */ else /* Check win.ini */
...@@ -680,7 +726,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun ...@@ -680,7 +726,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
void *env; void *env;
int gap, len; int gap, len;
WCHAR lpstrProtocol[256]; WCHAR lpstrProtocol[256];
LPCWSTR lpFile,lpOperation; LPCWSTR lpFile;
UINT retval = 31; UINT retval = 31;
WCHAR wcmd[1024]; WCHAR wcmd[1024];
BOOL done; BOOL done;
...@@ -765,13 +811,6 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun ...@@ -765,13 +811,6 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
return FALSE; 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 = wszOpen;
else
lpOperation = sei->lpVerb;
/* Else, try to execute the filename */ /* Else, try to execute the filename */
TRACE("execute:'%s','%s'\n", debugstr_w(wszApplicationName), debugstr_w(wszCommandline)); TRACE("execute:'%s','%s'\n", debugstr_w(wszApplicationName), debugstr_w(wszCommandline));
...@@ -788,7 +827,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun ...@@ -788,7 +827,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
/* Else, try to find the executable */ /* Else, try to find the executable */
wcmd[0] = '\0'; wcmd[0] = '\0';
retval = SHELL_FindExecutable(sei->lpDirectory, lpFile, lpOperation, wcmd, lpstrProtocol, &env); retval = SHELL_FindExecutable(sei->lpDirectory, lpFile, sei->lpVerb, wcmd, lpstrProtocol, &env);
if (retval > 32) /* Found */ if (retval > 32) /* Found */
{ {
WCHAR wszQuotedCmd[MAX_PATH+2]; WCHAR wszQuotedCmd[MAX_PATH+2];
...@@ -802,7 +841,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun ...@@ -802,7 +841,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
strcatW(wszQuotedCmd, wSpace); strcatW(wszQuotedCmd, wSpace);
strcatW(wszQuotedCmd, wszCommandline); strcatW(wszQuotedCmd, wszCommandline);
} }
TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(lpOperation), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol)); TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(sei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol));
if (*lpstrProtocol) if (*lpstrProtocol)
retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei, execfunc); retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei, execfunc);
else else
...@@ -827,7 +866,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun ...@@ -827,7 +866,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
strncpyW(lpstrProtocol, lpFile, iSize); strncpyW(lpstrProtocol, lpFile, iSize);
lpstrProtocol[iSize] = '\0'; lpstrProtocol[iSize] = '\0';
strcatW(lpstrProtocol, wShell); strcatW(lpstrProtocol, wShell);
strcatW(lpstrProtocol, lpOperation); strcatW(lpstrProtocol, sei->lpVerb? sei->lpVerb: wszOpen);
strcatW(lpstrProtocol, wCommand); strcatW(lpstrProtocol, wCommand);
/* Remove File Protocol from lpFile */ /* Remove File Protocol from lpFile */
...@@ -846,7 +885,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun ...@@ -846,7 +885,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
WCHAR lpstrTmpFile[256]; WCHAR lpstrTmpFile[256];
strcpyW(lpstrTmpFile, wHttp); strcpyW(lpstrTmpFile, wHttp);
strcatW(lpstrTmpFile, lpFile); strcatW(lpstrTmpFile, lpFile);
retval = (UINT)ShellExecuteW(sei->hwnd, lpOperation, lpstrTmpFile, NULL, NULL, 0); retval = (UINT)ShellExecuteW(sei->hwnd, sei->lpVerb, lpstrTmpFile, NULL, NULL, 0);
} }
TRACE("retval %u\n", retval); TRACE("retval %u\n", retval);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment