Mail Archives: djgpp/1999/04/18/14:54:18
ams AT ludd DOT luth DOT se (Martin Str|mberg) writes:
> Yes. I tried that first. However as the program reports "New:
> selector:offset = 319:5472." and "Old: selector:offset = 59:528." and
> it didn't work I just thought it best to really use that (old)
> selector.
It will try to get jump destination from memory with offset _old_isr
in segment pointed by %fs selector.  Because this segment does not
belong to your program (it belongs to DPMI server), trying to access
it for reading will lead to unpredictable results.
> 
> So any ideas?
I have tried the following program.  It works for me.
#include <dpmi.h>
#include <go32.h>
#include <sys/segments.h>
#include <stdio.h>
#include <stdlib.h>
__dpmi_paddr old_addr, new_addr;
void handler (void);
void handler_end (void);
__asm__ (".globl _handler
_handler:
	ljmp %cs:_old_addr
	.globl _handler_end
_handler_end:
	nop");
int
main (void)
{
  int selector;
  __dpmi_paddr tmp_addr;
  _go32_dpmi_lock_data (&old_addr, sizeof (old_addr));
  _go32_dpmi_lock_code (handler, ((unsigned long) handler_end
                                  - (unsigned long) handler));
  printf ("memory locked\n");
  if (__dpmi_get_protected_mode_interrupt_vector (0x31, &old_addr))
    {
      fprintf (stderr, "can not get interrupt\n");
      exit (EXIT_FAILURE);
    }
  printf ("got interrupt vector\n");
  new_addr.selector = _my_cs ();
  new_addr.offset32 = (unsigned long) handler;
  if (__dpmi_set_protected_mode_interrupt_vector (0x31, &new_addr))
    {
      fprintf (stderr, "can not set interrupt\n");
      exit (EXIT_FAILURE);
    }
  printf ("set interrupt vector\n");
  selector = __dpmi_allocate_ldt_descriptors (1);
  if (selector == -1)
    fprintf (stderr, "can not allocate selector\n");
  else
    __dpmi_free_ldt_descriptor (selector);
  printf ("allocated LDT descriptor?\n");
  while (__dpmi_get_protected_mode_interrupt_vector (0x31, &tmp_addr)
         || (tmp_addr.selector != new_addr.selector)
         || (tmp_addr.offset32 != new_addr.offset32)
         || __dpmi_set_protected_mode_interrupt_vector (0x31, &old_addr))
    {
      fprintf (stderr, "can not restore interrupt\n");
      system ("");
    }
  printf ("restored interrupt vector\n");
  return EXIT_SUCCESS;
}
-- 
Michael Bukin
- Raw text -