http://bugs.winehq.org/show_bug.cgi?id=34764
--- Comment #2 from Anastasius Focht focht@gmx.net 2013-10-27 06:05:32 CDT --- Hello folks,
debugging the next crash yields:
--- snip --- Wine-dbg>ni 0x54039ece: movl 0x0(%ecx),%eax
Wine-dbg>ni 0x54039ed0: call *0x28(%eax)
Wine-dbg>x/20x $eax 0x7cc5b2a4 IMILUnknown1Impl_Vtbl: 7cbad815 7cbad938 7cbad97e 7cbad9c4 0x7cc5b2b4 IMILUnknown2Impl_Vtbl+0x4: 7cbadaeb 7cbadb31 7cbadb77 7cc641f0 0x7cc5b2c4: 00000000 00000000 00000000 00000000 0x7cc5b2d4: 00000000 00000000 00000000 7cbadf97 0x7cc5b2e4 BmpDecoder_FrameVtbl+0x4: 7cbae0e0 7cbae123 7cbae166 7cbae252
Wine-dbg>p IMILUnknown1Impl_Vtbl {QueryInterface=0x7cbad815, AddRef=0x7cbad938, Release=0x7cbad97e} Wine-dbg>p IMILUnknown2Impl_Vtbl {QueryInterface=0x7cbad9c4, AddRef=0x7cbadaeb, Release=0x7cbadb31, UnknownMethod1=0x7cbadb77} --- snip ---
The method offset is within vtable range of IMILUnknown1Impl_Vtbl or IMILUnknown2Impl_Vtbl. Unfortunately it doesn't take any parameters -> no COM interface ptr!
--- snip --- ... 54039EB9 8B7D 24 MOV EDI,DWORD PTR SS:[EBP+24] 54039EBC 807F 4C 00 CMP BYTE PTR DS:[EDI+4C],0 54039EC0 75 1A JNE SHORT 54039EDC 54039EC2 8DB3 A8000000 LEA ESI,[EBX+0A8] 54039EC8 8B0E MOV ECX,DWORD PTR DS:[ESI] 54039ECA 85C9 TEST ECX,ECX 54039ECC 74 0E JE SHORT 54039EDC 54039ECE 8B01 MOV EAX,DWORD PTR DS:[ECX] ; get vtable ptr 54039ED0 FF50 28 CALL DWORD PTR DS:[EAX+28] ; crash 54039ED3 83F8 02 CMP EAX,2 54039ED6 0F84 F6E40500 JE 540983D2 --- snip ---
It could be that we still have some layouts wrong and MIL calls this not as part of COM interface but as C++ class member function for a different thing (ecx is setup for __thiscall)?
I ended up adding stub methods #1..7 to IMILUnknown1 with "IMILUnknown1 *iface arg" and "ret E_NOTIMPL" to reach the desired offset for the missing stub. The crash is avoided after adding stub #8 with "cdecl" STDMETHODV_ (the function doesn't take any args, no 'this' iface ptr), returning 0.
It crashes again a bit later at some unknown vtable offset. Unlike the previous one this seems a real method from IMILUnknown2.
--- snip --- 54039BE6 8BFF MOV EDI,EDI 54039BE8 55 PUSH EBP 54039BE9 8BEC MOV EBP,ESP 54039BEB 51 PUSH ECX 54039BEC 8D86 A8000000 LEA EAX,[ESI+0A8] 54039BF2 8338 00 CMP DWORD PTR DS:[EAX],0 54039BF5 53 PUSH EBX 54039BF6 B3 01 MOV BL,1 54039BF8 74 26 JE SHORT 54039C20 54039BFA 8B00 MOV EAX,DWORD PTR DS:[EAX] 54039BFC 8D55 FC LEA EDX,[EBP-4] 54039BFF 83C0 10 ADD EAX,10 54039C02 8B08 MOV ECX,DWORD PTR DS:[EAX] ; this, iface 54039C04 52 PUSH EDX 54039C05 50 PUSH EAX ; iface 54039C06 FF51 14 CALL DWORD PTR DS:[ECX+14] ; crash 54039C09 85C0 TEST EAX,EAX 54039C0B 0F8C 1F090000 JL 5403A530 54039C11 8B86 84000000 MOV EAX,DWORD PTR DS:[ESI+84] 54039C17 3B45 FC CMP EAX,DWORD PTR SS:[EBP-4] 54039C1A 0F85 10090000 JNE 5403A530 54039C20 8AC3 MOV AL,BL 54039C22 5B POP EBX 54039C23 C9 LEAVE 54039C24 C3 RETN --- snip ---
Adding stub methods #2..3 to IMILUnknown2, duplicating UnknownMethod1() lets the app finally display the image on .NET Framework 3.5 SP1. The changes are backwards compatible, the test app still runs on .NET 3.0, 3.0SP1, 3.5
Though the first change to IMILUnknown1 looks somehow fishy...
Trying out more "advanced" WPF apps like "GOG.com Downloader" (which requires .NET 3.5 SP1) fails, indicating there is still something not quite right due to layout mismatch and/or stub methods (most likely IMILUnknown2Impl_UnknownMethod1):
Download: http://static.gog.com/download/d3/stable/Setup_Downloader_3.5.8_stable.exe
--- snip --- ... fixme:d3d_surface:surface_init Unknown pool 0x6. fixme:d3d:resource_access_from_pool Unhandled pool 0x6. fixme:d3d:state_lastpixel Last Pixel Drawing Disabled, not handled yet fixme:shell:URL_ParseUrl failed to parse L"UIAutomationTypes" fixme:d3d9:Direct3DShaderValidatorCreate9 stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod1 (0x30ba158,0x1,0xdb9dbb0): stub fixme:wer:WerRegisterMemoryBlock (0x5418ebf0 6144) stub fixme:wer:WerRegisterMemoryBlock (0x5418ebe8 4) stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod1 (0x30ba158,0x1,0xdb9db08): stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod1 (0x30ba158,0x1,0xdb9dad4): stub fixme:wincodecs:IMILUnknown1Impl_UnknownMethod8 : stub fixme:wincodecs:IMILUnknown1Impl_UnknownMethod8 : stub fixme:wincodecs:IMILUnknown1Impl_UnknownMethod8 : stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod3 (0x30ba158,0xdb9d664,(nil)): stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod1 (0x30bf010,0x1,0xdb9dbb0): stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod1 (0x30bf010,0x1,0xdb9db08): stub fixme:wincodecs:IMILUnknown2Impl_UnknownMethod1 (0x30bf010,0x1,0xdb9dad4): stub fixme:wincodecs:IMILUnknown1Impl_UnknownMethod8 : stub fixme:wincodecs:IMILUnknown1Impl_UnknownMethod8 : stub fixme:wincodecs:IMILUnknown1Impl_UnknownMethod8 : stub err:ntdll:vDbgPrintExWithPrefix 63: MIL FAILURE: Unexpected HRESULT 0x80004002 in caller: intermediate rendering error err:ntdll:vDbgPrintExWithPrefix 63: MIL FAILURE: Unexpected HRESULT 0x80004002 in caller: The render thread failed unexpectedly. UNHANDLED ERROR! Message: Exception from HRESULT: 0x88980406 Stack trace: at System.Windows.Media.Composition.DUCE.Channel.SyncFlush() at System.Windows.Media.MediaContext.CompleteRender() at System.Windows.Interop.HwndTarget.OnResize() at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
Inner exception: Message: Exception from HRESULT: 0x88980406 Stack trace: at System.Windows.Media.Composition.DUCE.Channel.SyncFlush() at System.Windows.Media.MediaContext.CompleteRender() at System.Windows.Interop.HwndTarget.OnResize() --- snip ---
Regards