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/e…
==============================================================================
--- 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,