Author: fireball Date: Tue May 2 01:33:26 2006 New Revision: 21763
URL: http://svn.reactos.ru/svn/reactos?rev=21763&view=rev Log: - Patch by Thomas Weidenmueller: Adds a workaround for buggy installshield installers (which crash without this patch) - Fixes e.g. ATI Catalyst 5.5 installer and some other
Modified: trunk/reactos/dll/win32/kernel32/except/except.c
Modified: trunk/reactos/dll/win32/kernel32/except/except.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/kernel32/except/ex... ============================================================================== --- trunk/reactos/dll/win32/kernel32/except/except.c (original) +++ trunk/reactos/dll/win32/kernel32/except/except.c Tue May 2 01:33:26 2006 @@ -115,28 +115,83 @@ DbgPrint("EDI: %.8x EFLAGS: %.8x\n", pc->Edi, pc->EFlags); }
+static LONG +BasepCheckForReadOnlyResource(IN PVOID Ptr) +{ + PVOID Data; + ULONG Size, OldProtect; + MEMORY_BASIC_INFORMATION mbi; + NTSTATUS Status; + LONG Ret = EXCEPTION_CONTINUE_SEARCH; + + /* Check if it was an attempt to write to a read-only image section! */ + Status = NtQueryVirtualMemory(NtCurrentProcess(), + Ptr, + MemoryBasicInformation, + &mbi, + sizeof(mbi), + NULL); + if (NT_SUCCESS(Status) && + mbi.Protect == PAGE_READONLY && mbi.Type == MEM_IMAGE) + { + /* Attempt to treat it as a resource section. We need to + use SEH here because we don't know if it's actually a + resource mapping */ + + _SEH_TRY + { + Data = RtlImageDirectoryEntryToData(mbi.AllocationBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_RESOURCE, + &Size); + + if (Data != NULL && + (ULONG_PTR)Ptr >= (ULONG_PTR)Data && + (ULONG_PTR)Ptr < (ULONG_PTR)Data + Size) + { + /* The user tried to write into the resources. Make the page + writable... */ + Size = 1; + Status = NtProtectVirtualMemory(NtCurrentProcess(), + &Ptr, + &Size, + PAGE_READWRITE, + &OldProtect); + if (NT_SUCCESS(Status)) + { + Ret = EXCEPTION_CONTINUE_EXECUTION; + } + } + } + _SEH_HANDLE + { + } + _SEH_END; + } + + return Ret; +} + /* * @unimplemented */ LONG STDCALL UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) { -#if 0 - DWORD RetValue; -#endif + LONG RetValue; HANDLE DebugPort = NULL; NTSTATUS ErrCode;
-#if 0 if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION && ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) { - RetValue = _BasepCheckForReadOnlyResource( - ExceptionInfo->ExceptionRecord->ExceptionInformation[1]); + /* Change the protection on some write attempts, some InstallShield setups + have this bug */ + RetValue = BasepCheckForReadOnlyResource( + (PVOID)ExceptionInfo->ExceptionRecord->ExceptionInformation[1]); if (RetValue == EXCEPTION_CONTINUE_EXECUTION) return EXCEPTION_CONTINUE_EXECUTION; } -#endif
/* Is there a debugger running ? */ ErrCode = NtQueryInformationProcess(NtCurrentProcess(), ProcessDebugPort,