'=========================================================================== ' Subject: CHECK IF WINDOWS IS RUNNING Date: 01-08-97 (18:02) ' Author: Hans Lunsing Code: QB, PDS ' Origin: FidoNet QUIK_BAS Echo Packet: DOS.ABC '=========================================================================== ' > I was ' > wondering if I could have the programs run in the same EXE; and the ' > EXE will find out if it is being run in DOS mode, or Windows mode. 'Windows programs have DOS stubs that say "This program requires 'Microsoft Windows". 32-bit Windows (95) programs have 16-bit Windows (3) 'stubs that tell that they cannot run under 16-bit Windows. So in 'principle what you want is possible. At all events you need a linker 'able to make such a combined exe from the three different parts, but I 'don't know if a suitable linker exist. ' > How is it ' > possible to find out whether the program is run under DOS or WIN ' > '95 or WIN 3.1? Any help will be accepted! 'The following module will do that: '****************************************************************************** '* ISWIN.BAS '* '* This program will determine whether Windows is running and, if so, '* its operating mode. '* QuickBASIC must be loaded, as follows: QB /L QB '* '* Translated by Hans Lunsing from ISWIN.C by Andrew Schulman, '* February 1993, which you can find on pages 170-172 of '* '* "Undocumented DOS Second edition, A Programmer's Guide to Reserved '* MS-DOS Functions ans Data Structures", '* by Andrew Schulman, Ralf Brown, David Maxey, Raymond J. Michels, '* and Jim Kyle, '* published 1994 by Addison-Wesley Publishing Company, '* ISBN 0-201-63287-X '****************************************************************************** DEFINT A-Z ' Type for segmented address TYPE FarPtr Offset AS INTEGER 'offset Segment AS INTEGER 'segment END TYPE DECLARE FUNCTION DetectSwitcher () DECLARE SUB DOSGetVector (Number AS INTEGER, Vector AS FarPtr) DECLARE FUNCTION WinGetVM () DECLARE FUNCTION IsWin (Major AS INTEGER, Minor AS INTEGER, Mode AS INTEGER) '$INCLUDE: 'Qb.bi' 'Include file for interrupt calls CONST FALSE = 0, TRUE = NOT FALSE CONST MULTIPLEX = &H2F 'multiplex interrupt number 'Modes: CONST REALmode = 1 'Windows in real mode CONST STANDARDmode = 2 'Windows in standard mode CONST ENHANCEDmode = 3 'Windows in enhanced mode CONST SYSTEMVM = 1 'System Virtual Machine ID DIM Major AS INTEGER 'Primary version number DIM Minor AS INTEGER 'Secondary version number DIM Mode AS INTEGER 'Mode in which Windows is running DIM sMode AS STRING 'Mode string DIM Version AS STRING 'Version string IF NOT IsWin(Major, Minor, Mode) THEN PRINT "Windows is not running" ELSEIF Major = 2 THEN PRINT "Running Windows-386 V 2.x" ELSE Version = LTRIM$(STR$(Major)) + "." + RIGHT$("0" + LTRIM$(STR$(Minor)), 2) SELECT CASE Mode CASE 1: sMode = "Real" CASE 2: sMode = "Standard" CASE 3: sMode = "Enhanced" END SELECT PRINT "Running Windows "; Version; " (or higher) "; sMode; " mode" END IF IF Mode = ENHANCEDmode THEN ' If the task at hand is running within the System-VM the system must ' be some hacked version of Windows like MSDPMI, or the task must be ' running inside WINSTART.BAT. IF WinGetVM = SYSTEMVM THEN PRINT "Running DOS application in System VM:" PRINT "Must be WINSTART.BAT or hacked Windows!" END IF END IF END FUNCTION DetectSwitcher '----------------------------------------------------------------------- ' Function returns TRUE if DOSSHELL task switcher is loaded, ' and returns FALSE otherwise. '----------------------------------------------------------------------- DIM R AS RegTypeX R.BX = 0 R.DI = 0 R.ES = 0 R.AX = &H4B02 CALL InterruptX(MULTIPLEX, R, R) 'DOSSHELL 5+ installation check DetectSwitcher = (R.ES <> 0 OR R.DI <> 0) END FUNCTION SUB DOSGetVector (IntNum AS INTEGER, IntVec AS FarPtr) '----------------------------------------------------------------------- ' Function returns IntVec of interrupt number IntNum as a segmented ' address in IntVec. ' (It is the same function as MBHANCE's SaveCurrentVec.) '----------------------------------------------------------------------- DIM R AS RegTypeX R.AX = &H3500 OR (IntNum AND &HFF) CALL InterruptX(&H21, R, R) IntVec.Segment = R.ES IntVec.Offset = R.BX END SUB FUNCTION IsWin (Major AS INTEGER, Minor AS INTEGER, Mode AS INTEGER) '----------------------------------------------------------------------- ' Tests for Windows. Returns TRUE if running in Windows, and FALSE if ' otherwise. Moreover returns version number and mode as parameters. '----------------------------------------------------------------------- DIM R AS RegTypeX 'Processor registers for interrupt call DIM IntVec AS FarPtr Major = 0 'Initialize version numbers Minor = 0 Mode = 0 'Initialize mode ' Make sure someone, anyone has INT 2Fh DOSGetVector &H2F, IntVec IF IntVec.Segment = 0 AND IntVec.Offset = 0 THEN IsWin = FALSE EXIT FUNCTION END IF 'Call MULTIPLEX/160A to see if Windows 3.1+ R.AX = &H160A CALL InterruptX(MULTIPLEX, R, R) IF R.AX = 0 THEN 'AX = 0 if Windows running Mode = R.CX 'Mode, 2 = Std., 3 = Enhanced 'Calculation of major version number is 'OK as long as it is < 128 Major = R.BX \ 256 'Major version number Minor = R.BX AND 255 'Minor version number IsWin = TRUE ELSE 'Call MULTIPLEX/1600 to see if Windows 3.0 Enhanced mode or Windows/386 R.AX = &H1600 CALL InterruptX(MULTIPLEX, R, R) 'Calculation of minor version number is 'OK as long as it is < 128 Major = R.AX AND 255 'Major version number Minor = R.AX \ 256 'Minor version number SELECT CASE Major CASE 1, &HFF 'Windows/386 2.x is running Major = 2 'Windows/386 2.x Minor = 1 'don't know; assume 1 Mode = ENHANCEDmode 'Windows/386 sort of like Enhanced IsWin = TRUE CASE 0, &H80 'AL = 0 or 80h if no Windows 'Call MULTIPLEX/4680h to see if Windows 3.0 Standard or Real mode; 'but, this could be a "3.0 derivative" such as DOSSHELL task 'switcher! R.AX = &H4680 CALL InterruptX(MULTIPLEX, R, R) IF R.AX = 0 THEN 'AX = 0 if MULTIPLEX/4680 handled 'Make sure it isn't DOSSHELL task switcher IF DetectSwitcher THEN IsWin = FALSE 'DOSSHELL taskswitcher ELSE Major = 3 Minor = 0 'Either have Windows Standard mode or Real mode; to distinguish 'have to do fake Windows broadcasts with MULTIPLEX/1605h. Yuk! 'We'll avoid that here by assuming 3.0 Standard mode. If you 'really want to distinguish 3.0 Standard mode and real mode 'See Microsoft Systems Journal, March 1991, p. 113; and Micro- 'soft Knowledge Base articles Q75943 and Q75338. Mode = STANDARDmode IsWin = TRUE END IF ELSE IsWin = FALSE 'No Windows END IF CASE ELSE 'Must be Windows 3.0 Enhanced mode Mode = ENHANCEDmode IsWin = TRUE END SELECT END IF END FUNCTION FUNCTION WinGetVM '----------------------------------------------------------------------- ' Function returns Virtual machine ID within Windows Enhanced Mode. '----------------------------------------------------------------------- DIM R AS RegTypeX R.AX = &H1683 CALL InterruptX(MULTIPLEX, R, R) 'Get Virtual Machine ID WinGetVM = R.BX END FUNCTION