www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/09/23/02:09:17

From: sandmann AT clio DOT rice DOT edu (Charles Sandmann)
Message-Id: <10109230603.AA14592@clio.rice.edu>
Subject: Win2K/XP nesting fix
To: djgpp-workers AT delorie DOT com (DJGPP developers)
Date: Sun, 23 Sep 2001 01:03:38 -0500 (CDT)
Cc: theowl AT freemail DOT c3 DOT hu
X-Mailer: ELM [version 2.5 PL2]
Mime-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

On my long list of things to do was to test alternate ways of fixing the
nesting crash on Win2K and XP.  On the basis of a "maybe" from The Owl,
I tried to replace our set psp call with a PM get psp call.  At the
same time I replaced the call to int86 with a line of in-line 
assembler to avoid namespace issues with int86 and code bloat.

The getpsp call seems to work just as well as the setpsp call on the 
tests I've run.  The getpsp code is much safer (it could be called under
any DPMI provider) and requires less code to set up.

I would recommend getting rid of the windows version test code and
testing entirely on the DOS version 0x532 (which will someday be stored
in a global variable ...) - and on that basis doing the very simple 
getpsp code.  If some strange DOS version advertises like NT the getpsp
will still be harmless and just waste an interrupt call.

Included is prelim difference for comments - doing more testing now.
It would have been nice to have this in Andrew's most recent update
on clio, but that's life.

*** dpmiexcp.c_	Fri Sep  7 00:38:42 2001
--- dpmiexcp.c	Sun Sep 23 01:02:30 2001
***************
*** 21,27 ****
  #include <sys/exceptn.h>
  #include <sys/nearptr.h>		/* For DS base/limit info */
  #include <libc/internal.h>
- #include <stubinfo.h>
  
  #define err(x) _write(STDERR_FILENO, x, sizeof(x)-1)
  
--- 21,26 ----
*************** __djgpp_set_ctrl_c(int enable_sigs)
*** 586,614 ****
    return oldenable;
  }
  
- unsigned short _windows_major, _windows_minor;
- 
- /* Compute the version Windows reports via Int 2Fh/AX=1600h.  */
- static void
- get_windows_version(void)
- {
-   if (!_windows_major)
-     {
-       __dpmi_regs r;
- 
-       r.x.ax = 0x1600;
-       __dpmi_int(0x2f, &r);
-       if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
- 	  && (r.h.al > 3 || r.h.ah > 0))
- 	{
- 	  _windows_major = r.h.al;
- 	  _windows_minor = r.h.ah;
- 	}
-       else
- 	_windows_major = 0xff;	/* meaning no Windows */
-     }
- }
- 
  /* A work-around for a bug in W2K's NTVDM, suggested by
     The Owl <theowl AT freemail DOT c3 DOT hu>.
  
--- 585,590 ----
*************** get_windows_version(void)
*** 628,641 ****
     DOSX does pass the parent PSP selector to NTVDM when it notifies it
     about a DPMI program exit, but NTVDM does not use this information.)
  
!    To work around that, we force NTVDM to record a valid PSP before we
!    exit.  We do that by invoking a PM Int 21h, function 50h, passing
!    it our PM selector for the PSP, as it was returned by the PM switch
!    entry point we called at startup to enter protected mode.  We do
!    that just before exiting, to make sure that even an application
!    which crashes (e.g., due to SIGSEGV or Ctrl-BREAK) immediately
!    after its child returns will always leave its valid PSP recorded by
!    NTVDM before it exits.
  
     (To play it safe in the face of non-DJGPP DPMI programs and old
     DJGPP programs, we also restore the PSP in dosexec.c, which see.)
--- 604,616 ----
     DOSX does pass the parent PSP selector to NTVDM when it notifies it
     about a DPMI program exit, but NTVDM does not use this information.)
  
!    To work around that, we ask NTVDM to record a valid PSP before we
!    exit.  We do that by invoking a PM Int 21h, function 51h, which gets
!    the PM selector for the PSP (which triggers NTVDM to record the
!    correct internal value).  We do that just before exiting, to make 
!    sure that even an application which crashes (e.g., due to SIGSEGV 
!    or Ctrl-BREAK) immediately after its child returns will always leave 
!    its valid PSP recorded by NTVDM before it exits.
  
     (To play it safe in the face of non-DJGPP DPMI programs and old
     DJGPP programs, we also restore the PSP in dosexec.c, which see.)
*************** get_windows_version(void)
*** 646,667 ****
  void
  __maybe_fix_w2k_ntvdm_bug(void)
  {
!   /* The _osmajor == 0 case takes care of a crash that happens before
!      we had a chance to get DOS version.  (Yes, I am being paranoiac!)  */
!   if ((_osmajor == 5 || _osmajor == 0) && _osminor == 0
!       && _get_dos_version(1) == 0x0532) /* NT or Windows 2000? */
!     {
!       get_windows_version();
!       if (_windows_major == 0xff) /* this is NT or W2K */
! 	{
! 	  extern int _int86(int ivec, union REGS *in, union REGS *out);
! 	  union REGS regs;
! 
! 	  regs.h.ah = 0x50;
! 	  regs.d.ebx = _stubinfo->psp_selector;
! 	  _int86 (0x21, &regs, &regs);
! 	}
!     }
  }
  
  void __attribute__((noreturn))
--- 621,632 ----
  void
  __maybe_fix_w2k_ntvdm_bug(void)
  {
!   if (_osmajor == 5 && _get_dos_version(1) == 0x0532) /* NT or Windows 2000? */
!   {
!     /* Protected mode call to GetPSP - may return RM PSP if not extended */
!     asm volatile("movb $0x51, %%ah ; int $0x21"
!                   : : : "ax", "bx" );    /* input, output, regs */
!   }
  }
  
  void __attribute__((noreturn))

- Raw text -


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