ShellExecute IE compatibility problems
Francois Gouget
fgouget at codeweavers.com
Thu Apr 8 19:03:37 CDT 2004
This patch fixes two IE compatibility problems.
The first one is a mundane issue. IE calls ShellExecuteEx with a NULL
verb. Our implementation fails when it should use some sophisticated
algorithm described in the MSDN to choose a default verb. Well most of
the time we just want 'open' anyway so that's what this patch does. I've
left it as an exercise to the reader to head over to the MSDN and
implement the series of fallbacks we're supposed to implement.
The other one is much more interesting. One thing that was puzzling me
is that IE makes calls like ShellExecute("\"foo.pdf\""). Notice the
extra quotes. These extra quotes make the call fail on Wine. I checked
that on NT and got the same result as on Wine: a failure. Yet further
investigation showed that IE really expected this to work.
What happens is that IE first calls SHLWAPI.276, i.e. WhichPlatform().
If WhichPlatform() returns 2, then IE adds extra quotes, otherwise it
doesn't. And WhichPlatform() returns 2 if shell32.dll has the
DllGetVersion() entry point.
On the NT box I used for testing I had shell32.dll 4.0 which does not
have this entry point, and that shell32.dll happened to refuse filenames
with the extra quotes. On an XP test machine I had shell32.dll 6.0.xxx
which did have DllGetEntryPoint and which accepted the extra quotes.
A further check showed that on XP ShellExecute("\"notepad.exe\"") works
just fine. So, unless we want to throw back our shell32.dll
implementation to the stone age, we must really accept the extra quotes
in ShellExecuteEx().
Once this patch is applied it should be possible to click on a file,
e.g. a PDF, an have IE invoke the appropriate external application
(assuming it is installed).
Changelog:
* dlls/shell32/shlexec.c
Francois Gouget <fgouget at codeweavers.com>
Fix two IE compatibility issues:
- If the verb is NULL, use 'open'.
- The filename may have surrounding quotes. Strip them and proceed
as usual.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: dlls/shell32/shlexec.c
===================================================================
RCS file: /var/cvs/wine/dlls/shell32/shlexec.c,v
retrieving revision 1.40
diff -u -r1.40 shlexec.c
--- a/dlls/shell32/shlexec.c 7 Apr 2004 03:49:51 -0000 1.40
+++ b/dlls/shell32/shlexec.c 8 Apr 2004 23:12:53 -0000
@@ -917,6 +911,7 @@
{
static const WCHAR wQuote[] = {'"',0};
static const WCHAR wSpace[] = {' ',0};
+ static const WCHAR wOpen[] = {'o','p','e','n',0};
static const WCHAR wWww[] = {'w','w','w',0};
static const WCHAR wFile[] = {'f','i','l','e',0};
static const WCHAR wHttp[] = {'h','t','t','p',':','/','/',0};
@@ -948,10 +943,27 @@
/* make copies of all path/command strings */
if (sei_tmp.lpFile)
- strcpyW(wszApplicationName, sei_tmp.lpFile);
+ {
+ int len=lstrlenW(sei_tmp.lpFile);
+ if (sei_tmp.lpFile[0]=='\"' && sei_tmp.lpFile[len-1]=='\"') {
+ lstrcpynW(wszApplicationName,sei_tmp.lpFile+1,sizeof(wszApplicationName)/sizeof(*wszApplicationName));
+ wszApplicationName[len-2]='\0';
+ } else {
+ lstrcpynW(wszApplicationName,sei_tmp.lpFile,sizeof(wszApplicationName)/sizeof(*wszApplicationName));
+ }
+ }
else
*wszApplicationName = '\0';
+ if (!sei_tmp.lpVerb)
+ {
+ /* Determining the real verb to use is much more complex than that.
+ * See the MSDN.
+ */
+ FIXME("lpVerb==NULL, using 'open'\n");
+ sei_tmp.lpVerb=wOpen;
+ }
+
if (sei_tmp.lpParameters)
strcpyW(wszCommandline, sei_tmp.lpParameters);
else
More information about the wine-patches
mailing list