📄 osinfo.c
字号:
/*********************************************************************
* Microsoft Diagnostics Version 2.0
*
* A diagnostic utility to detect as much useful information about a
* customer's computer system as is possible.
*
* Microsoft Diagnostics: We detect the World.
*
* OSINFO.C - Source file for determing Operating System information.
********************************************************************/
/* Include Files */
#include "msd.h"
/*********************************************************************
* GetOsVersionInfo - Gets the Operating System version number and the
* version numbers of various operating
* operating environments.
*
* Returns: TRUE if an error occured.
*********************************************************************/
BOOL GetOsVersionInfo (OS_VERSION_STRUCT *pOsVer, BOOL fMinimumInfo)
{
union REGS inregs, outregs; /* Register structures */
{
/* Get DOS Version */
/* Get Real DOS Version (intended for DOS >= 5.00) */
inregs.x.ax = 0x3306;
inregs.x.bx = 0x0000;
int86 (0x21, &inregs, &outregs);
/* Was the call supported? */
if (outregs.x.bx != 0x0000)
{
/* It was. Get the real DOS version */
pOsVer->wDosMajor = outregs.h.bl;
pOsVer->wDosMinor = outregs.h.bh;
pOsVer->wDosRevision = outregs.h.dl;
/* Determine where DOS was loaded */
pOsVer->wDosLoadedFlags = outregs.h.dh;
/* Call the standard DOS Version call */
inregs.x.ax = 0x3000;
int86 (0x21, &inregs, &outregs);
}
else
{
/* Get the DOS version from the standard DOS call */
inregs.x.ax = 0x3000;
int86 (0x21, &inregs, &outregs);
/* Set the DOS version flags */
pOsVer->wDosMajor = outregs.h.al;
pOsVer->wDosMinor = outregs.h.ah;
/* Set the DOS >= 5.00 specific flags */
pOsVer->wDosRevision = 0x00;
pOsVer->wDosLoadedFlags = 0x00;
}
/* Set user serial number and OEM number */
pOsVer->dwUserSerialNumber = ((DWORD) outregs.h.bl << 16) + outregs.x.cx;
pOsVer->wOemSerialNumber = outregs.h.bh;
/* Set the flag and values for OS/2 */
if (pOsVer->wDosMajor >= 10)
{
pOsVer->fOs2Installed = TRUE;
pOsVer->wDosMajor = pOsVer->wDosMajor / 10;
}
else
pOsVer->fOs2Installed = FALSE;
}
{
/* Check for Windows and DOSSHELL */
WinVerDetect (&(pOsVer->wWindowsType), &(pOsVer->wWindowsMajor),
&(pOsVer->wWindowsMinor), &(pOsVer->fDosShellTaskSwitcher));
}
{
/* Get OEM Name and Version */
GetDosOemStrings (pOsVer);
}
{
if (fMinimumInfo)
return (FALSE);
}
{
/* Get DOS Boot Drive */
if (pOsVer->fOs2Installed == FALSE && pOsVer->wDosMajor >= 4)
{
inregs.x.ax = 0x3305;
int86 (0x21, &inregs, &outregs);
pOsVer->chDosBootDrive = (CHAR) (outregs.h.dl + 'A' - 1);
}
else
pOsVer->chDosBootDrive = '\0';
}
{
/* DESQview Information */
inregs.x.ax = 0x2B01;
inregs.x.cx = 0x4445; /* 'DE' */
inregs.x.dx = 0x5251; /* 'SQ' */
int86 (0x21, &inregs, &outregs);
if (outregs.h.al == 0xFF)
{
/* DESQview was not installed */
pOsVer->wDesqViewMajor = 0x00;
pOsVer->wDesqViewMinor = 0x00;
}
else
{
/* DESQview was installed */
if (outregs.x.bx == 0x0002)
{
pOsVer->wDesqViewMajor = 0x02;
pOsVer->wDesqViewMinor = 0x00;
}
else
{
pOsVer->wDesqViewMajor = outregs.h.bh;
pOsVer->wDesqViewMinor = outregs.h.bl;
}
}
}
{
/* 3270 Control Program Information */
inregs.x.ax = 0x3000;
inregs.x.cx = 0x0000;
inregs.x.dx = 0x0000;
int86 (0x10, &inregs, &outregs);
if (outregs.x.cx == 0x0000 && outregs.x.dx == 0x0000)
{
/* No 3270 program is installed */
pOsVer->w3270Installed = NO_3270_PROGRAM;
pOsVer->w3270Major = 0;
pOsVer->w3270Minor = 0;
}
else
{
/* CX:DX points to a structure of 3270 info */
WORD FAR *pfwWord = NULL; /* Far pointer to a WORD */
/* Segment of version information is at offset 8 */
pfwWord = (WORD FAR *)
((((DWORD) outregs.x.cx << 16) + outregs.x.dx) + 8);
/* The version information is at offset 0 */
pfwWord = (WORD FAR *) ((DWORD) (*pfwWord) << 16);
if (*pfwWord <= 0x03FF)
{
/* This is the IBM 3270 PC Control Program */
pOsVer->w3270Installed = _3270_PC_CONTROL_PROGRAM;
pOsVer->w3270Major = *pfwWord >> 8;
pOsVer->w3270Minor = *pfwWord & 0x00FF;
}
else
{
/* This is the IBM 3270 Workstation Program */
pOsVer->w3270Installed = _3270_WORKSTATION_PROGRAM;
pOsVer->w3270Major = (*pfwWord >> 8) - 2;
pOsVer->w3270Minor = *pfwWord & 0x00FF;
}
}
}
{
/* Is DoubleDOS Installed */
inregs.x.ax = 0xF400;
int86 (0x21, &inregs, &outregs);
if (outregs.h.al == 00)
pOsVer->fDoubleDosInstalled = FALSE;
else
pOsVer->fDoubleDosInstalled = TRUE;
}
{
/* TaskView and TopView information */
if (pOsVer->wDesqViewMajor > 0)
{
/* DesqView includes all of TopView's API's */
pOsVer->fTaskViewInstalled = FALSE;
pOsVer->wTopViewMajor = 0;
pOsVer->wTopViewMinor = 0;
}
else
{
/* TopView Get Version Call */
inregs.x.ax = 0x1022;
inregs.x.bx = 0x0000;
int86 (0x15, &inregs, &outregs);
if (outregs.x.bx == 0x0000)
{
pOsVer->fTaskViewInstalled = FALSE;
pOsVer->wTopViewMajor = 0;
pOsVer->wTopViewMinor = 0;
}
if (outregs.x.bx == 0x0001)
{
pOsVer->fTaskViewInstalled = TRUE;
pOsVer->wTopViewMajor = 0;
pOsVer->wTopViewMinor = 0;
}
else
{
pOsVer->fTaskViewInstalled = FALSE;
pOsVer->wTopViewMajor = outregs.h.bl;
pOsVer->wTopViewMinor = outregs.h.bh;
}
}
}
{
/* Store the fully qualified path to the program */
strncpy (pOsVer->szPathToProgram, pszPathToProgram,
MAX_PATH_TO_PROGRAM - 1);
pOsVer->szPathToProgram[MAX_PATH_TO_PROGRAM - 1] = '\0';
}
return (FALSE);
}
/*********************************************************************
* SprintOsVersionInfo - Put Operating System/Environment information
* into a set of strings to be printed or
* displayed.
*
* Returns: NULL if an error occured.
*********************************************************************/
QSZ * SprintOsVersionInfo (OS_VERSION_STRUCT *pOsVer,
CHAR szSumStrings[][MAX_SUMM_INFO + 5])
{
WORD wNmbrStrings = 0; /* Number of strings */
WORD wNmbrChars = 0; /* Number of characters in the strings */
WORD i, u; /* Looping variables */
CHAR chBuffer[80]; /* Local string */
QSZ *pqszStrings; /* Location for storing string pointers */
WORD wAlignColumn; /* Column to align titles */
WORD wLength; /* Length of environment string */
WORD wMaxLength = 0; /* Maximum length of environment strings */
/* Summary Strings */
if (szSumStrings != NULL)
{
if (pOsVer->szOemVer[0][0] != '\0' &&
strlen (pOsVer->szOemVer[0]) < MAX_SUMM_INFO + 3)
strncpy (szSumStrings[0], pOsVer->szOemVer[0], MAX_SUMM_INFO + 3);
else
{
strncpy (szSumStrings[0], pszMsDos, MAX_SUMM_INFO);
sprintf (chBuffer, " %d.%02d", pOsVer->wDosMajor,
pOsVer->wDosMinor);
strncat (szSumStrings[0], chBuffer,
MAX_SUMM_INFO - strlen (szSumStrings[0]));
}
if (pOsVer->wWindowsType != NO_WINDOWS)
{
switch (pOsVer->wWindowsType)
{
case WIN_286:
strncpy (szSumStrings[1], pszWin286, MAX_SUMM_INFO);
strncat (szSumStrings[1], psz_2dotX,
MAX_SUMM_INFO - strlen (szSumStrings[1]));
break;
case WIN_386:
strncpy (szSumStrings[1], pszWin386, MAX_SUMM_INFO);
strncat (szSumStrings[1], psz_2dotX,
MAX_SUMM_INFO - strlen (szSumStrings[1]));
break;
default:
strncpy (szSumStrings[1], pszWindows, MAX_SUMM_INFO);
sprintf (chBuffer, " %d", pOsVer->wWindowsMajor);
strncat (szSumStrings[1], chBuffer,
MAX_SUMM_INFO - strlen (szSumStrings[1]));
if (pOsVer->wWindowsMinor == 0xFF)
strncat (szSumStrings[1], ".x ",
MAX_SUMM_INFO - strlen (szSumStrings[1]));
else
{
sprintf (chBuffer, ".%02d ", pOsVer->wWindowsMinor);
strncat (szSumStrings[1], chBuffer,
MAX_SUMM_INFO - strlen (szSumStrings[1]));
}
}
}
else if (pOsVer->fDosShellTaskSwitcher)
strncpy (szSumStrings[1], pszDosShell, MAX_SUMM_INFO);
return (NULL);
}
/* Overestimate the amount of space required for the strings */
/* Count up the environment space */
for (i = 0; environ[i][0] != '\0'; ++i)
{
wLength = strlen (environ[i]);
wNmbrStrings += (wLength / 72) + 1;
wNmbrChars += wLength + (wLength / 72) + 1;
if (wLength > 72)
wLength = 72;
if (wMaxLength < wLength)
wMaxLength = wLength;
}
wNmbrStrings += 3 + MAX_OS_TITLES;
/* Calculate the correct alignment column */
wAlignColumn = 20;
if (pOsVer->fDosShellTaskSwitcher)
wAlignColumn = 24;
if (pOsVer->w3270Installed)
wAlignColumn = 26;
/* Center the information */
wLength = strlen (pOsVer->szPathToProgram) + wAlignColumn;
if (wLength < wMaxLength)
wAlignColumn += ((wMaxLength / 2) - (wLength / 2));
wNmbrChars += MAX_OS_TITLES * (MAX_OS_VERSION_LINE_LEN +
MAX_PATH_TO_PROGRAM +
wAlignColumn);
/* Allocate space for the pointer area and string area */
pqszStrings = AllocStringSpace (wNmbrStrings, wNmbrChars);
if (pqszStrings == NULL)
return (NULL);
/* Put the information in place */
i = 0;
{
/* Operating System Version */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -