interrupts in when in NT version

Zsolt Rizsanyi rizsanyi at myrealbox.com
Thu Oct 24 05:26:15 CDT 2002


Hi!

I have Laurent Pinchart's safedisc patch applied and working for a while now. 
(and it works perfectly).

But the recent interrupt changes tend to cause cvs conflicts and to break it.
This patch is supposed to work only if winver is nt40 so very probably this 
applies only to NT.
What the patch relies on is that the interrupt handling code (which was 
INSTR_EmulateInstruction before the changes), return 
EXCEPTION_ACCESS_VIOLATION if interrupt 0x01 is called (if I understand it 
correctly).

This was done with the next patches:
Index: dlls/ntdll/signal_i386.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/signal_i386.c,v
retrieving revision 1.46
diff -u -p -r1.46 signal_i386.c
--- dlls/ntdll/signal_i386.c	12 Sep 2002 22:07:03 -0000	1.46
+++ dlls/ntdll/signal_i386.c	24 Oct 2002 10:13:36 -0000
@@ -729,6 +729,7 @@ static void do_segv( CONTEXT *context, i
 {
     EXCEPTION_RECORD rec;
     DWORD page_fault_code = EXCEPTION_ACCESS_VIOLATION;
+    DWORD priv_instr_code = EXCEPTION_PRIV_INSTRUCTION;
 
 #ifdef CR2_sig
     /* we want the page-fault case to be fast */
@@ -758,8 +759,8 @@ static void do_segv( CONTEXT *context, i
     case T_SEGNPFLT:  /* Segment not present exception */
     case T_PROTFLT:   /* General protection fault */
     case T_UNKNOWN:   /* Unknown fault code */
-        if (INSTR_EmulateInstruction( context )) return;
-        rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
+        if (INSTR_EmulateInstruction( context, &priv_instr_code )) return;
+        rec.ExceptionCode = priv_instr_code;
         break;
     case T_PAGEFLT:  /* Page fault */
 #ifdef CR2_sig

Index: memory/instr.c
===================================================================
RCS file: /home/wine/wine/memory/instr.c,v
retrieving revision 1.19
diff -u -p -r1.19 instr.c
--- memory/instr.c	23 Oct 2002 22:24:10 -0000	1.19
+++ memory/instr.c	24 Oct 2002 10:14:08 -0000
@@ -397,7 +397,7 @@ static void INSTR_outport( WORD port, in
  *
  * Emulate a privileged instruction. Returns TRUE if emulation successful.
  */
-BOOL INSTR_EmulateInstruction( CONTEXT86 *context )
+BOOL INSTR_EmulateInstruction( CONTEXT86 *context, DWORD *exception_code )
 {
     int prefix, segprefix, prefixlen, len, repX, long_op, long_addr;
     SEGPTR gpHandler;
@@ -685,6 +685,29 @@ BOOL INSTR_EmulateInstruction( CONTEXT86
             break;  /* Unable to emulate it */
 
         case 0xcd: /* int <XX> */
+<<<<<<< instr.c
+            if (long_op)
+            {
+                ERR("int 0x%02x from 32-bit code is not supported.\n", 
instr[1]);
+                if (instr[1] == 0x01)
+                    *exception_code = EXCEPTION_ACCESS_VIOLATION;
+                break;  /* Unable to emulate it */
+            }
+            else
+            {
+                FARPROC16 addr = INT_GetPMHandler( instr[1] );
+                WORD *stack = get_stack( context );
+                /* Push the flags and return address on the stack */
+                *(--stack) = LOWORD(context->EFlags);
+                *(--stack) = context->SegCs;
+                *(--stack) = LOWORD(context->Eip) + prefixlen + 2;
+                add_stack(context, -3 * sizeof(WORD));
+                /* Jump to the interrupt handler */
+                context->SegCs  = HIWORD(addr);
+                context->Eip = LOWORD(addr);
+            }
+            return TRUE;
+=======
            if(!Dosvm.EmulateInterruptPM && !DPMI_LoadDosSystem())
                ERR("could not initialize interrupt handling\n");
            else {
@@ -693,6 +716,7 @@ BOOL INSTR_EmulateInstruction( CONTEXT86
                return TRUE;
            }
            break;  /* Unable to emulate it */
+>>>>>>> 1.19
 
         case 0xcf: /* iret */
             if (long_op)



The second one is pretty ugly since I have not resolved the cvs conflict (I'm 
waiting for your input :), but the important part is this:
+            if (long_op)
+            {
+                ERR("int 0x%02x from 32-bit code is not supported.\n", 
instr[1]);
+                if (instr[1] == 0x01)
+                    *exception_code = EXCEPTION_ACCESS_VIOLATION;
+                break;  /* Unable to emulate it */
+            }

Here is the EXCEPTION_ACCESS_VIOLATION is returned if interrupt 0x01 is 
called.
This was good when interrupts from 32-bit code were not supported. But now we 
need a special case for this.
I think that on NT calling 0x01 is forbidden. But I have not tested this (and 
will not, because I dont have windows devel tools - I just want to run my 
Longman Dictionary :)

I would like if this could be fixed properly and that would work with the 
safedisk patch, if thats possible.

Thanks
Zsolt





More information about the wine-devel mailing list