https://bugs.winehq.org/show_bug.cgi?id=37609
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |obfuscation Component|-unknown |user32
--- Comment #4 from Anastasius Focht focht@gmx.net --- Hello Drew,
well I had a look at this - but didn't came to a conclusion yet.
--- quote --- The Windows created afterwards also get destroyed by the program. --- quote ---
If you look further in the logs there is no full user interface tear down sequence, so this control destruction might be part of normal program logic. The listbox control you mentioned belongs to a plugin.
--- snip --- 0027:Ret PE DLL (proc=0x4868beb,module=0x4860000 L"colorlib.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 0027:Ret KERNEL32.LoadLibraryA() retval=04860000 ret=00496c48 0027:Call KERNEL32.GetProcAddress(04860000,0086119c "MainEntry") ret=00496c59 0027:Ret KERNEL32.GetProcAddress() retval=04865660 ret=00496c59 0027:Call KERNEL32.GetProcAddress(04860000,00861194 "init") ret=00496c7d 0027:Ret KERNEL32.GetProcAddress() retval=048657b0 ret=00496c7d ... 0027:Call user32.CreateWindowExA(00000000,04871010 "Listbox",04871950 "Yo",00a00003,00000000,00000000,00000001,00000001,000101e2,00000000,04860000,00000000) ret=04866aff --- snip ---
There are indeed many controls destroyed, but on the other hand many controls remain and are later shown within tool windows/tool strips (if you pass the "hang").
--- snip --- $ grep "CreateWindow()" log.txt | wc -l 441
$ grep "DestroyWindow()" log.txt | wc -l 128 --- snip ---
Maybe the logic is more like "create everything first" (without being visible) and "destroy what's not needed afterwards" plus "make the rest visible". Lots of user interface functionality is context dependent. If you have nothing open it doesn't make sense to show all tool windows/strips with all controls/buttons visible/enabled. This approach could be used if you have a static/fixed "matrix" like layout and want to re-create the controls at the same place/position later... that's speculation on my side though :-)
The first tool window remains visible and even the main user interface (window hierarchy) is partially present but not shown due to a live loop - what you see as "hang":
--- snip --- ... 002b:Call user32.SetRectEmpty(0033cc40) ret=005aa69c 002b:Ret user32.SetRectEmpty() retval=00000001 ret=005aa69c 002b:Call user32.CopyRect(0033cc04,0033cc40) ret=005aa502 002b:Ret user32.CopyRect() retval=00000001 ret=005aa502 002b:Call user32.SendMessageA(0004027e,00000404,00000000,0033cbf4) ret=005aa514 002b:trace:msg:WINPROC_CallProcAtoW (hwnd=0x4027e,msg=TTM_ADDTOOLA,wp=00000000,lp=0033cbf4) 002b:Call window proc 0x7e32a076 (hwnd=0x4027e,msg=TTM_ADDTOOLA,wp=00000000,lp=0033cbf4) 002b:Call user32.GetWindowLongW(0004027e,00000000) ret=7e32a0a8 002b:Ret user32.GetWindowLongW() retval=001f6810 ret=7e32a0a8 002b:trace:tooltips:TOOLTIPS_WindowProc hwnd=0x4027e msg=404 wparam=0 lParam=33cbf4 002b:trace:tooltips:TOOLTIPS_AddToolT add tool (0x4027e) 0x20268 0! 002b:Call KERNEL32.LocalAlloc(00000040,0005efe4) ret=7e2a0a4b 002b:Ret KERNEL32.LocalAlloc() retval=1008eff0 ret=7e2a0a4b 002b:Call KERNEL32.LocalFree(10030030) ret=7e2a0acb 002b:Ret KERNEL32.LocalFree() retval=00000000 ret=7e2a0acb 002b:trace:tooltips:TOOLTIPS_AddToolT add CALLBACK! 002b:Call user32.GetPropW(00020268,0000c018) ret=7e2a4864 002b:Ret user32.GetPropW() retval=001e1dd8 ret=7e2a4864 002b:trace:tooltips:TOOLTIPS_AddToolT subclassing installed! 002b:Call user32.SendMessageW(00020268,00000055,0004027e,00000003) ret=7e3276c0 002b:trace:msg:WINPROC_CallProcWtoA (hwnd=0x20268,msg=WM_NOTIFYFORMAT,wp=0004027e,lp=00000003) 002b:Call window proc 0x7e2a4de2 (hwnd=0x20268,msg=WM_NOTIFYFORMAT,wp=0004027e,lp=00000003) 002b:Call user32.GetPropW(00020268,0000c018) ret=7e2a4e7a 002b:Ret user32.GetPropW() retval=001e1dd8 ret=7e2a4e7a 002b:Call user32.GetPropW(00020268,0000c018) ret=7e2a50c1 002b:Ret user32.GetPropW() retval=001e1dd8 ret=7e2a50c1 002b:Call user32.GetWindowLongW(0004027e,00000000) ret=7e329ffa 002b:Ret user32.GetWindowLongW() retval=001f6810 ret=7e329ffa 002b:Call user32.GetPropW(00020268,0000c018) ret=7e2a50c1 002b:Ret user32.GetPropW() retval=001e1dd8 ret=7e2a50c1 002b:Call user32.IsWindowUnicode(00020268) ret=7e2a513a 002b:Ret user32.IsWindowUnicode() retval=00000000 ret=7e2a513a 002b:Call user32.CallWindowProcA(005ab445,00020268,00000055,0004027e,00000003) ret=7e2a519e 002b:Call window proc 0x5ab445 (hwnd=0x20268,msg=WM_NOTIFYFORMAT,wp=0004027e,lp=00000003) 002b:Call user32.DefWindowProcA(00020268,00000055,0004027e,00000003) ret=005ab4db 002b:Ret user32.DefWindowProcA() retval=00000001 ret=005ab4db 002b:Ret window proc 0x5ab445 (hwnd=0x20268,msg=WM_NOTIFYFORMAT,wp=0004027e,lp=00000003) retval=00000001 002b:Ret user32.CallWindowProcA() retval=00000001 ret=7e2a519e 002b:Ret window proc 0x7e2a4de2 (hwnd=0x20268,msg=WM_NOTIFYFORMAT,wp=0004027e,lp=00000003) retval=00000001 002b:Ret user32.SendMessageW() retval=00000001 ret=7e3276c0 002b:trace:tooltips:TOOLTIPS_AddToolT -- WM_NOTIFYFORMAT returns: NFR_ANSI 002b:Ret window proc 0x7e32a076 (hwnd=0x4027e,msg=TTM_ADDTOOLA,wp=00000000,lp=0033cbf4) retval=00000001 002b:Ret user32.SendMessageA() retval=00000001 ret=005aa514 ... --- snip ---
I don't see an obvious error in the tooltip control creation and tool association. Maybe a missing bit somewhere during main/tool window creation which causes this abnormal condition to occur. This could be a missing message, incorrect notification, wrong order of messages, subclassing problem etc.
Debugging is a bit annoying since the target process 'FreeHand 9.tty' is a debuggee.
--- snip --- Wine-dbg>info process pid threads executable (all id:s are in hex) 00000020 1 'explorer.exe' 0000000e 5 'services.exe' 00000019 3 _ 'plugplay.exe' 00000012 4 _ 'winedevice.exe' 00000008 3 'FreeHand 9.exe' 00000024 5 _ 'FreeHand 9.tty' --- snip ---
One has to allow the child/debuggee to run a bit away from entry point. The parent writes one 4K page of "stolen" code to the child. Otherwise the child would trigger invalid instruction traps. After that, the parent must be forcefully detached from its child and a more useful debugger reattached ;-)
Anyway, the loop "hang" is not infinite. The counter will overflow and if you wait long enough, 10-20 min (depending on your host speed), the user interface is finally shown, albeit with the some tool windows and their child controls incorrectly sized.
I prepared a shortcut four you (one-liner, beware of Bugzilla line-break):
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files/Macromedia/FreeHand 9
$ printf '\x33\xC0\x90' | dd of="FreeHand 9.tty" bs=1 seek=1746036 count=3 conv=notrunc --- snip ---
The binary patch avoids the live looping but leaves the DRM in place - no one is harmed :-) Use at own risk ...
Those user32 bugs are nasty and investigation could be indeed time consuming. The the missing bit(s) could be hidden anywhere during user interface creation sequence which includes hundreds of controls (nesting, subclassing).
$ sha1sum freehand9-trial.exe a502e0d2e4590e118ea0215e947f16913a57b938 freehand9-trial.exe
$ du -sh freehand9-trial.exe 14M freehand9-trial.exe
$ wine --version wine-1.7.34-90-g5fa7402
Regards