http://bugs.winehq.org/show_bug.cgi?id=16013
--- Comment #9 from Anastasius Focht focht@gmx.net 2009-01-05 03:39:28 --- Hello,
after the catroot<GUID> problem is solved by precreating "C:\windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}" and placing a dummy .cat file, the installer proceeds and crashes again:
--- snip --- 0043:Call KERNEL32.GetProcAddress(795a0000,0108c97a "SetupGetLineCountA") ret=01065cf4 0043:Ret KERNEL32.GetProcAddress() retval=795b4b68 ret=01065cf4 0043:Call setupapi.SetupGetLineCountA(0014fa70,0101fb98 "DevicesToUpgrade") ret=0105f240 0043:Call ntdll.RtlCreateUnicodeStringFromAsciiz(7eb49688,0101fb98 "DevicesToUpgrade") ret=795d144a 0043:Ret ntdll.RtlCreateUnicodeStringFromAsciiz() retval=00000001 ret=795d144a 0043:trace:seh:raise_exception code=c0000005 flags=0 addr=0x795ce86d 0043:trace:seh:raise_exception info[0]=00000000 0043:trace:seh:raise_exception info[1]=00000824 0043:trace:seh:raise_exception eax=00000824 ebx=795ea7c4 ecx=00000000 edx=00163c98 esi=7eb49720 edi=7eb496a8 0043:trace:seh:raise_exception ebp=7eb49618 esp=7eb495f0 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010246 0043:trace:seh:call_stack_handlers calling handler at 0x1066099 code=c0000005 flags=0 0043:Call msvcrt._except_handler3(7eb49598,7eb499f8,7eb492cc,7eb49134) ret=7bc72a5d 0043:trace:seh:_except_handler3 exception c0000005 flags=0 at 0x795ce86d handler=0x1066099 0x7eb492cc 0x7eb49134 semi-stub 0043:trace:seh:_except_handler3 reached TRYLEVEL_END, returning ExceptionContinueSearch 0043:Ret msvcrt._except_handler3() retval=00000001 ret=7bc72a5d 0043:trace:seh:call_stack_handlers handler at 0x1066099 returned 1 0043:trace:seh:call_stack_handlers calling handler at 0x7bc79a28 code=c0000005 flags=0 0043:Call KERNEL32.UnhandledExceptionFilter(7eb490a0) ret=7bc79a64 wine: Unhandled page fault on read access to 0x00000824 at address 0x795ce86d (thread 0043), starting debugger... 0043:trace:seh:start_debugger Starting debugger "winedbg --auto 59 172" 0043:Ret KERNEL32.UnhandledExceptionFilter() retval=00000000 ret=7bc79a64 0043:trace:seh:call_stack_handlers handler at 0x7bc79a28 returned 1 Unhandled exception: page fault on read access to 0x00000824 in 32-bit code (0x795ce86d). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:795ce86d ESP:7eb495f0 EBP:7eb49618 EFLAGS:00010246( - 00 -RIZP1) EAX:00000824 EBX:795ea7c4 ECX:00000000 EDX:00163c98 ESI:7eb49720 EDI:7eb496a8 Stack dump: 0x7eb495f0: 7eb49688 0101fb98 7eb49f1c 7eb49614 0x7eb49600: 0000001e 7bc9b990 7eb49658 7bc5e7db 0x7eb49610: 00000000 795ea7c4 7eb49668 795d14cb 0x7eb49620: 0014fa70 0015a098 795ee750 00148a38 0x7eb49630: 00000001 0015a098 7eb49fc3 02020175 0x7eb49640: 001103e8 00110fc0 7eb49680 795ea7c4 Backtrace: =>0 0x795ce86d find_section+0x2c() in setupapi (0x7eb49618) 1 0x795d14cb SetupGetLineCountW+0x39() in setupapi (0x7eb49668) 2 0x795d1474 SetupGetLineCountA+0x55() in setupapi (0x7eb49698) 3 0x7bc5e594 call_entry_point+0x20() in ntdll (0x7eb496b0) 4 0x7bc5e70c relay_call+0x171() in ntdll (0x7eb49700) 5 0x795b4b7d in setupapi (+0x14b7d) (0x7eb497a8) 6 0x7eb49fb5 (0x7eb4a393) ---- snip ---
The crash also happens in other installers (.NET 3.x Framework, WIC, ..) - a general problem which needs to be solved.
First, lets look how the parameters to SetupGetLineCountA() are actually constructed. If you do the usual +relay trace you might be surprised ... There is only one RtlAllocateHeap()/RtlReAllocateHeap pair which actually refers to this handle (and the structure behind).
Fortunately, +snoop comes to help:
--- snip --- .. 003c:CALL UPDSPAPI.UpdSpOpenInfFileA(010bd080,00000000,00000002,00000000) ret=0104a430 003c:Call ntdll.RtlAllocateHeap(00110000,00000000,00000037) ret=004689d6 003c:Ret ntdll.RtlAllocateHeap() retval=0014b260 ret=004689d6 003c:Call KERNEL32.lstrlenA(0014b260 "c:\44cbd7a5c10fb3180b6fa80dec\update\update_SP2GDR.inf") ret=00468b20 003c:Ret KERNEL32.lstrlenA() retval=00000036 ret=00468b20 ... 003c:Call ntdll.RtlReAllocateHeap(00110000,00000000,0014b460,0000006e) ret=00468a08 003c:Ret ntdll.RtlReAllocateHeap() retval=0014b460 ret=00468a08 ... 003c:RET UPDSPAPI.UpdSpOpenInfFileA() retval=0014fa70 ret=0104a430 --- snip ---
Ok, the installer seems to use its own method/API from UPDSPAPI (discussed later) to create the HINF handle which is opaque datatype for internal inf file structure. This handle gets used in various calls (selection):
--- snip --- ... 003c:CALL UPDSPAPI.UpdSpGetLineCountA(0014fa70,0100b3c8) ret=010529c8 ... 0043:CALL UPDSPAPI.UpdSpGetSourceInfoA(0014fa70,00000001,00000003,7eb49794,00000104,00000000) ret=0103e7bf ... 0043:RET UPDSPAPI.UpdSpInstallFilesFromInfSectionA(0014fa70,00000000,0014b460,0100f558,010bcd20,00000006) retval=00000001 ret=0103e80c ... 0043:RET UPDSPAPI.UpdSpGetSourceFileLocationA(0014fa70,00000000,001636b0,7eb4978c,00000000,00000000,7eb49790) retval=00000000 ret=0103e846 ... 0043:CALL UPDSPAPI.UpdSpInstallFilesFromInfSectionA(0014fa70,00000000,0014b460,01012148,010bcd20,00000004) ret=0103ed87 ... 0043:CALL UPDSPAPI.UpdSpFindFirstLineA(0014fa70,0101656c,00000000,7eb49784) ret=01031ce8 ... --- snip ---
And finally ends up calling SetupGetLineCountA() with the same HINF, see first trace snippet. What's that UPDSPAPI?
Extracting the version info resource from that PE reveals:
--- snip --- $ strings -e l updspapi.dll
... VS_VERSION_INFO StringFileInfo 040904B0 CompanyName Microsoft Corporation FileDescription Windows Servicing Setup API FileVersion 6.2.0029.0 (SRV03_QFE.031113-0918) InternalName SETUPAPI.DLL LegalCopyright Microsoft Corporation. All rights reserved. OriginalFilename SETUPAPI.DLL ProductName Microsoft Windows Operating System ProductVersion 6.2.0029.0 VarFileInfo ... --- snip ---
Just to be sure an exports snippet:
--- snip --- $ winedump -j export updspapi.dll Contents of updspapi.dll: 371424 bytes
Exports table:
Name: UPDSPAPI.dll Characteristics: 00000000 TimeDateStamp: 42C17F9B Tue Jun 28 18:49:31 2005 Version: 0.00 Ordinal base: 1 # of functions: 70 # of Names: 70 Addresses of functions: 0001FE88 Addresses of name ordinals: 000200B8 Addresses of names: 0001FFA0
Entry Pt Ordn Name 00007434 1 UpdSpCloseFileQueue 00012883 2 UpdSpCloseInfFile 0000A17B 3 UpdSpCommitFileQueueA 0000A195 4 UpdSpCommitFileQueueW 00017266 5 UpdSpCopyErrorA 00016E6A 6 UpdSpCopyErrorW ... --- snip ---
This looks like some kind of stripped down setupapi, shipped with installers. The number of exported functions is reduced to a subset as compared to Wine's and M$ setupapi.dll.
The real problem is that OS internal data structures (opaque handles) are passed between this installer shipped dll and OS (Wine) dlls. Because we have no knowledge about the layout of OS internal (undocumented) structures we have a problem.
There would be no problem at all if M$ would just consistently use APIs! Either their own installer supplied APIs for the inf stuff because UPDSPAPI.dll also contains:
Winedump export snippet:
--- snip --- 0000F82C 25 UpdSpGetLineCountA 0000F62D 26 UpdSpGetLineCountW --- snip ---
or just OS (Wine) setupapi for all inf stuff!
This mixup is cleanly brain damage ... They still tend to keep this Internet explorer/installers tightly bound to OS.
The "best" solution to cope with this problem is unfortunately: SEH Any page fault caused by "foreign created" data structures passed into API will be caught and failure is returned.
This is probably something that AJ would find acceptable. Just guard SetupGetLineCountA() or SetupGetLineCountW() (to cover both cases) with SEH, e.g.
__TRY { ... <might use foreign data structures> } __EXCEPT_PAGE_FAULT { .. <set return failure (-1)> } __ENDTRY
and add some comment to state the reason (M$ installers). As already pointed out, failure of this API doesn't harm the installer at all.
Regards