shell32 patch 23 c
Martin Fuchs
martin-fuchs at gmx.net
Wed Mar 3 14:12:03 CST 2004
Changelog:
- enumerate all "shell\<verb>\command" entries in the registry instead of searching only for "shell\open\command" entries
To make the code more readable, I moved that part of SHELL_FindExecutable(), which is now called in two different cases
into a new subfunction SHELL_FindExecutableByOperation().
In effect this patch eliminates this TODO:
/* 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. */
Index: shlexec.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlexec.c,v
retrieving revision 1.32
diff -u -p -d -w -b -r1.32 shlexec.c
--- shlexec.c 3 Mar 2004 05:26:30 -0000 1.32
+++ shlexec.c 3 Mar 2004 20:07:46 -0000
@@ -267,6 +267,54 @@ end:
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,
+ ¶mlen) == 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]
*
@@ -294,7 +342,6 @@ static UINT SHELL_FindExecutable(LPCWSTR
WCHAR filetype[256]; /* registry name for this filetype */
LONG filetypelen = sizeof(filetype); /* length of above */
WCHAR command[256]; /* command from registry */
- LONG commandlen = sizeof(command); /* This is the most DOS can handle :) */
WCHAR wBuffer[256]; /* Used to GetProfileString */
UINT retval = 31; /* default - 'No association was found' */
WCHAR *tok; /* token pointer */
@@ -392,46 +439,46 @@ static UINT SHELL_FindExecutable(LPCWSTR
filetypelen /= sizeof(WCHAR);
filetype[filetypelen] = '\0';
TRACE("File type: %s\n", debugstr_w(filetype));
+ }
- /* Looking for ...buffer\shell\lpOperation\command */
- strcatW(filetype, wShell);
- strcatW(filetype, lpOperation);
- strcatW(filetype, wCommand);
-
- if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, command,
- &commandlen) == ERROR_SUCCESS)
+ if (*filetype)
{
- commandlen /= sizeof(WCHAR);
- if (key) strcpyW(key, filetype);
-#if 0
- LPWSTR tmp;
- WCHAR param[256];
- LONG paramlen = sizeof(param);
- static const WCHAR wSpace[] = {' ',0};
+ if (lpOperation)
+ {
+ /* pass the operation string to SHELL_FindExecutableByOperation() */
+ filetype[filetypelen] = '\0';
+ retval = SHELL_FindExecutableByOperation(lpPath, lpFile, lpOperation, key, filetype, command, sizeof(command));
+ }
+ else
+ {
+ 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
- * 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);
+ /* Looking for ...buffer\shell\<operation>\command */
+ strcatW(filetype, wszShell);
- if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, param,
- ¶mlen) == ERROR_SUCCESS)
+ /* enumerate the operation subkeys in the registry and search for one with an associated command */
+ if (RegOpenKeyW(HKEY_CLASSES_ROOT, filetype, &hkey) == ERROR_SUCCESS)
{
- paramlen /= sizeof(WCHAR);
- strcatW(command, wSpace);
- strcatW(command, param);
- commandlen += paramlen;
+ int idx = 0;
+ for(;; ++idx)
+ {
+ 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
- command[commandlen] = '\0';
+ RegCloseKey(hkey);
+ }
+ }
+
+ if (retval > 32)
+ {
SHELL_ArgifyW(lpResult, 1024 /*FIXME*/, command, xlpFile);
- retval = 33; /* FIXME see above */
}
}
else /* Check win.ini */
@@ -680,7 +727,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
void *env;
int gap, len;
WCHAR lpstrProtocol[256];
- LPCWSTR lpFile,lpOperation;
+ LPCWSTR lpFile;
UINT retval = 31;
WCHAR wcmd[1024];
BOOL done;
@@ -765,13 +812,6 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
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 */
TRACE("execute:'%s','%s'\n", debugstr_w(wszApplicationName), debugstr_w(wszCommandline));
@@ -788,7 +828,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
/* Else, try to find the executable */
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 */
{
WCHAR wszQuotedCmd[MAX_PATH+2];
@@ -827,7 +867,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
strncpyW(lpstrProtocol, lpFile, iSize);
lpstrProtocol[iSize] = '\0';
strcatW(lpstrProtocol, wShell);
- strcatW(lpstrProtocol, lpOperation);
+ strcatW(lpstrProtocol, sei->lpVerb? sei->lpVerb: wszOpen);
strcatW(lpstrProtocol, wCommand);
/* Remove File Protocol from lpFile */
@@ -846,7 +886,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
WCHAR lpstrTmpFile[256];
strcpyW(lpstrTmpFile, wHttp);
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);
More information about the wine-patches
mailing list