Languages Douglas Boling How do I in a C program, ascertain which version of MS Windows is being run when my program is called in a DOS window? Also, how can I establish whether Windows is running in Real, Standard, or Enhanced mode? PC Whitaker 2A Galesend, 6 Bluff Path, The Peak, Hong Kong [[No Disk]] The techniques necessary for a DOS program to determine what version and mode Windows is running are interrelated. Unfortunately, like everything else under DOS, the techniques involved calling interrupt based functions, particularly functions using the Multiplex interrupt (Interrupt 2F hex) which is not necessarily conducive to high level languages. The process of determining the windows version is rather involved, since before Windows 3.1, there was no single function a DOS program could call that returned the mode and version of Windows. Before I explain the accompanying program that performs the process, I'll discuss the process itself. Essentially, the process involves checking for Windows 3.1. If 3.1 is not running, calling a series of functions that, by elimination, narrow the possibilities until we determine the version and operating mode of Windows. Determining the mode and version requires the following steps. First, call the 'Identify Windows Version' function by calling the multiplex interrupt with AX equal to 160A hex. If the function returns with AX zero, the Windows major version will be in BH and the minor version will be in BL. For Windows 3.1 BX returns with 30A hex. The function returns the operating mode in CX. When running in enhanced mode, CX contains 3 otherwise CX contains 2 indicating standard mode. Since the 'Identify Windows Version function is only supported in Windows 3.1 and later, if the function returns with AX not equal to zero, we know that we are running under Windows 3.0 or an earlier version of Windows. Next, call the Detect Enhanced Mode Windows' function by calling the multiplex interrupt with AX equal to 1600 hex. Here, things get a bit tricky. If the function returns with AX loaded with 1600, Windows is not running in enhanced mode. If AL returns with 0FF hex or 080 hex, Windows/386 is running. Otherwise, AX contains the major and minor version numbers of Windows. Since we know that Windows 3.1 is not running (since 'Identify Windows Version' failed) we can assume that we are running under Windows 3.0 in enhanced mode. If 'Detect Enhanced Mode Windows' fails, call the Detect Real and Standard Mode Windows' function by calling the multiplex interrupt with AX equal to 4680 hex. If this function returns with AX not zero, Windows is not running. Even if AX is zero, we can not assume that Windows is running since the DOS Task Switcher may also be running. To check for the Task Switcher, call the Multiplex interrupt with AX equal to 4B02 hex, DI zero and ES zero. If the function returns with AX zero, the task Switcher is running. If the task Switcher is not running, we can assume that Windows 3.0 is running under either Standard or Real mode. The final task is to differentiate between 3.0 running in real and standard modes. To do this, we send out a notification that Windows is about to start. If Windows is running in standard mode, it will respond to the Windows Initialization call by indicating that Windows should not be started. To simulate a Windows Initialization call, load AX with 1605 hex, clear CX, can call the Multiplex interrupt. If the call returns with CX loaded with 0FFFF hex, some program has indicated that Windows should not start. We can then assume that the program inhibiting Windows running is Windows 3.0 itself, running in standard mode. If the notification returns with CX zero, Windows is running in real mode. Finally, a program should call the Windows Termination notice in case some installed program is counting the number of initialization and termination notices. Calling the termination notice balances the call to the initialization notice. As you can see, a process as simple as determining the version of Windows is convoluted by the lack of planning by the Windows designers. A C routine that performs the steps above is shown in figure 1. The code uses the int86 and int86x functions to perform the necessary Multiplex interrupts. The int86 function is called with pointers to two structures. These first of these structures contains the values that the various registers should be loaded with on the call. The second structure is loaded with the register values when the interrupt returns. For our purposes the pointers point to the same structure that contains the necessary values on the call and is loaded with the results on the return. The routine, called GetWinVer, is called to with pointers to two integers. If the function detects that Windows is running, it returns a zero return code and the version and operating mode are loaded into the variables pointed to by the pointers. The function returns 1 if Windows is not detected.