http://bugs.winehq.org/show_bug.cgi?id=16626
--- Comment #4 from Anastasius Focht focht@gmx.net 2009-01-05 06:41:18 --- Hello,
--- quote --- Something like this... --- quote ---
yes it helps to overcome the general problem by in-place updating page protection but there is a problem with this approach.
The problem is there might cases where file i/o buffers are partly accessible, e.g. have correct protection on initial pages while the rest is not accessible.
If posix read calls manage to partially read file contents into buffer until hitting EFAULT due to incorrect protection the file pointer has already advanced. The second "try" after adjusting page protection will incorrectly update buffer with already advanced file ptr when requested again with full length.
Example (buffer partly accessible, file pointer advanced on second try):
--- snip --- ... 0033:Call KERNEL32.VirtualAlloc(01852000,0006a000,00001000,00000004) ret=79e74a2b 0033:Ret KERNEL32.VirtualAlloc() retval=01852000 ret=79e74a2b 0033:Call KERNEL32.InterlockedCompareExchange(009372a8,00000008,00000004) ret=79ef5742 0033:Ret KERNEL32.InterlockedCompareExchange() retval=00000004 ret=79ef5742 0033:Call KERNEL32.ReadFile(00000250,018492ba,000720ec,0033f05c,00000000) ret=007fa8bb 0033:trace:ntdll:NtReadFile (0x250,(nil),(nil),(nil),0x33ef28,0x18492ba,0x000720ec,(nil),(nil)),partial stub! 0033:trace:ntdll:NtReadFile = 0xc00000e8 0033:trace:ntdll:NtReadFile (0x250,(nil),(nil),(nil),0x33ef28,0x18492ba,0x000720ec,(nil),(nil)),partial stub! 0033:trace:ntdll:NtReadFile = SUCCESS (467180) 0033:fixme:file:ReadFile Could not access memory (0x18492ba,467180) at first, now OK. Protected by DIBSection code? 0033:Ret KERNEL32.ReadFile() retval=00000001 ret=007fa8bb ... 0033:Call KERNEL32.RaiseException(e0434f4d,00000001,00000001,0033f03c) ret=79f97065 0033:trace:seh:raise_exception code=e0434f4d flags=1 addr=0x7b844f78 0033:trace:seh:raise_exception info[0]=8013150c 0033:trace:seh:raise_exception eax=7b82ccb1 ebx=7b8c3940 ecx=00000000 edx=0033f01c esi=0033f01c edi=0033ef90 0033:trace:seh:raise_exception ebp=0033ef78 esp=0033ef14 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00000246 0033:trace:seh:call_stack_handlers calling handler at 0x79f9a3c8 code=e0434f4d flags=1 0033:CALL MSVCR80._except_handler4_common(7a381240,79e717fb,0033ef24,0033f054,0033ebb4,0033ea50) ret=79f9a3e7 0033:RET MSVCR80._except_handler4_common() retval=00000001 ret=79f9a3e7 0033:trace:seh:call_stack_handlers handler at 0x79f9a3c8 returned 1 0033:trace:seh:call_stack_handlers calling handler at 0x7a3197d4 code=e0434f4d flags=1 ... 0033:Call user32.MessageBoxW(00000000,0094985c L"Failed to update Select Dialog resources from an external resource file. Please verify that the SetupManagerResource.resx files resides beside executable and is valid. Error details: Binary stream '98' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change"...,00935a38 L"SetupManager Error",00000010) ret=03fe14b3 ... --- snip ---
The partial success (file ptr advanced) on first try needs to be taken into account when making the second try. I tested a quick fix for myself, taking that information into account and it seems to solve problem ;-)
Regards