CVS: winex/server macosx.c,1.1,1.2

[email protected] 31 Jul 2007 19:50:20 -0000
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/server macosx.c,1.1,1.2Update of /var/lib/cvsd/cvsroot/winex/server
In directory agravaine:/tmp/cvs-serv1010/server

Modified Files:
	macosx.c 
Log Message:

- fix WriteProcessMemory on the Mac to work on write-protected sections


Index: macosx.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/server/macosx.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- macosx.c	30 Mar 2007 15:55:03 -0000	1.1
+++ macosx.c	31 Jul 2007 19:50:17 -0000	1.2
@@ -140,6 +140,11 @@
                            size_t check_len)
 {
     struct thread *thread = process->thread_list;
+    vm_address_t RegionAddr = addr;
+    vm_size_t RegionSize;
+    struct vm_region_basic_info Info;
+    mach_msg_type_number_t InfoSize;
+    mach_port_t ObjectName;
     kern_return_t Err;
 
     if (!thread)  /* process is dead */
@@ -152,6 +157,30 @@
     if (!(thread->sched_mode & SCDM_INTERNAL))
        suspend_for_ptrace (thread);
 
+    InfoSize = sizeof (Info);
+    if ((Err = vm_region (thread->process->task_port, &RegionAddr,
+                          &RegionSize, VM_REGION_BASIC_INFO,
+                          (vm_region_info_t)&Info,
+                          &InfoSize, &ObjectName)))
+    {
+       fprintf (stderr, "Warn: vm_region failed: 0x%x\n", Err);
+       set_error (STATUS_ACCESS_DENIED);
+       resume_thread (thread);
+       return;
+    }
+
+    if (!(Info.protection & VM_PROT_WRITE))
+    {
+       if ((Err = vm_protect (thread->process->task_port, addr, len, 0,
+                              Info.protection | VM_PROT_WRITE)))
+       {
+          fprintf (stderr, "Warn: vm_protect failed: 0x%x\n", Err);
+          set_error (STATUS_ACCESS_DENIED);
+          resume_thread (thread);
+          return;
+       }
+    }
+
     Err = vm_write (thread->process->task_port, addr, (vm_offset_t)src, len);
     if (Err == KERN_PROTECTION_FAILURE)
        set_error (STATUS_ACCESS_DENIED);
@@ -161,5 +190,17 @@
     if (Err != KERN_SUCCESS)
        fprintf (stderr, "Warn: write_process_memory failed: 0x%x\n", Err);
 
+    if (!(Info.protection & VM_PROT_WRITE))
+    {
+       if ((Err = vm_protect (thread->process->task_port, addr, len, 0,
+                              Info.protection)))
+       {
+          fprintf (stderr, "Warn: second vm_protect failed: 0x%x\n", Err);
+          set_error (STATUS_ACCESS_DENIED);
+          resume_thread (thread);
+          return;
+       }
+    }
+
     resume_thread (thread);
 }