IHlink::Navigate mystery value
aeikum at codeweavers.com
Thu Jan 7 14:09:01 CST 2010
I've been working the past few days on cleaning up low-hanging-fruit
bugs relating to MSOffice. I've run into one bug for which I have a
solution, but I have no explanation as to why the solution is correct.
It's what Windows does, but I don't know why! This email's a bit long,
but it describes the problem and various things I've tried to understand
the solution. Hopefully someone reading this list has some ideas :)
The bug is in PowerPoint. On native, when a slideshow is exited (i.e.
go out of 'presentation mode'), the currently-displayed slide should
become activated in the main 'editor' PowerPoint window. In Wine,
however, the main window shows the slide that was active when the
slideshow began. This makes resuming the slideshow from where you left
off a big pain.
The problem is in the hlink module, specifically with IHlink::Navigate
(implemented in Wine as IHlink_fnNavigate around dlls/hlink/link.c:436).
IHlink objects can contain an IHlinkSite reference, which the Navigate
function makes calls to as it proceeds through navigation, as a sort of
The last call in IHlink::Navigate is to
IHlinkSite::OnNavigationComplete. This function takes an HRESULT
argument which, according to MSDN, should contain the final result of
the navigation. Again, according to MSDN, IHlink::Navigate should
return S_OK on success, error otherwise.
Of course, reality is different from what MSDN claims. On native,
IHlinkSite::OnNavigationComplete is consistently called by
IHlink::Navigate with its HRESULT argument set to 0x40100. I have no
idea what this value is supposed to represent. Every Windows version
with an hlink DLL, on both x86 and x86_64, passes 0x40100 to the
IHlinkSite when IHlink::Navigate is called. It doesn't seem to matter
what the target of the navigation is (website, file on filesystem). See
the tests linked below.
Currently in Wine our IHlink::Navigate passes S_OK, as you'd expect from
both the documentation and common sense. For whatever bizarre reason,
however, PowerPoint requires that this HRESULT value be greater than
zero. If zero (S_OK) is passed, then PowerPoint fails to restore the
proper slide and just does nothing. If an error code is passed,
PowerPoint pops up an error message, as you'd expect. But if a value
greater than zero is passed (it's not picky about 0x40100), PowerPoint
correctly opens the proper slide. So unfortunately, we need to do this
"right" for PowerPoint to behave.
Interpreted as an HRESULT, 0x40100 is DRAGDROP_S_DROP, a successful DND
operation, as returned by DoDragDrop. Is it possible that Windows
navigates to items by drag-dropping into the appropriate application?
IHlink _does_ also implement IOleObject, which is the "object" passed by
DoDragDrop. This interpretation seems unlikely, though, since all
programs that are associated with a filetype (i.e. open with
ShellExecute) must then implement IDropTarget. I'm not ruling this
interpretation out, but I can't make sense of it.
You'll note that the value looks something like a set of two bitflags.
File access permissions were the first thing to come to mind, but
Julliard said it looks nothing like permission flags that he's seen.
I've looked at every constant in include with the value 0x40000 and seen
nothing that looks relevant.
I sent a hack implementation off to wine-patches, but it was rejected.
Alexandre said he'd like a better investigation of where 0x40100 comes
from. I've exhausted my knowledge and can think of no place to derive
this value from. I'm here asking if the value stands out to anyone, or
if there are any suggestions of things to probe or functions to poke to
get some meaning attached to this number.
My hackish fix, with tests:
MSDN IHlink documentation:
MSDN IHlinkSite documentation:
More information about the wine-devel