www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/04/18/14:54:18

To: djgpp AT delorie DOT com
Subject: Re: My interrupt handler
References: <7fcm2k$31g$2 AT news DOT luth DOT se> <20iuatubeq DOT fsf AT Sky DOT inp DOT nsk DOT su> <7fd7i4$bns$1 AT news DOT luth DOT se>
From: Michael Bukin <M DOT A DOT Bukin AT inp DOT nsk DOT su>
Date: 19 Apr 1999 02:42:07 +0700
In-Reply-To: ams@ludd.luth.se's message of "18 Apr 1999 18:16:36 GMT"
Message-ID: <20pv51g1gw.fsf@Sky.inp.nsk.su>
Lines: 90
X-Mailer: Gnus v5.5/Emacs 19.34
Reply-To: djgpp AT delorie DOT com

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019