📄 dtwinver.cpp
字号:
//Call to get the underlying OS here through 16 -> 32 bit Generic Thunk
BOOL bFoundUnderlyingOS = FALSE;
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi))
{
lpVersionInformation->dwUnderlyingMajorVersion = osvi.dwMajorVersion;
lpVersionInformation->dwUnderlyingMinorVersion = osvi.dwMinorVersion;
lpVersionInformation->dwUnderlyingBuildNumber = LOWORD(osvi.dwBuildNumber); //ignore HIWORD
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, osvi.szCSDVersion);
//Explicitely map the win32 dwPlatformId to our own values
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_WINDOWS9x;
//Deterine the Win9x Service pack installed
if (IsWindows95SP1(lpVersionInformation))
lpVersionInformation->wUnderlyingServicePack = 1;
else if (IsWindows95OSR2(lpVersionInformation))
lpVersionInformation->wUnderlyingServicePack = 2;
else if (IsWindows98SP1(lpVersionInformation))
lpVersionInformation->wUnderlyingServicePack = 1;
}
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_NT;
//Determine the NT Service pack
lpVersionInformation->wUnderlyingServicePack = GetNTServicePackFromCSDString(osvi.szCSDVersion);
}
else
return FALSE;
bFoundUnderlyingOS = TRUE;
}
else
{
//We failed to get GetVersionEx so try to GetVersion instead. We known that we must be on
//Windows NT 3.5 or earlier since anything released later by MS had this function.
DWORD dwVersion = GetVersion();
if (dwVersion)
{
lpVersionInformation->dwUnderlyingMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwUnderlyingMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwUnderlyingBuildNumber = 0;
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_NT;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "");
bFoundUnderlyingOS = TRUE;
}
}
if (!bFoundUnderlyingOS)
{
//must be running on a real version of 16 bit Windows whose underlying OS is DOS
lpVersionInformation->dwUnderlyingMajorVersion = HIBYTE(HIWORD(dwVersion));
lpVersionInformation->dwUnderlyingMinorVersion = LOBYTE(HIWORD(dwVersion));
lpVersionInformation->dwUnderlyingBuildNumber = 0;
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_DOS;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "");
}
#else //Must be some version of real or emulated DOS
//Retreive the current version of emulated DOS
BYTE DosMinor;
BYTE DosMajor;
_asm
{
mov ax, 3306h
int 21h
mov byte ptr [DosMajor], bl
mov byte ptr [DosMinor], bh
}
lpVersionInformation->dwEmulatedPlatformId = DT_PLATFORM_DOS;
lpVersionInformation->dwEmulatedMajorVersion = (DWORD) DosMajor;
lpVersionInformation->dwEmulatedMinorVersion = (DWORD) DosMinor;
lpVersionInformation->dwEmulatedBuildNumber = 0; //no build number with DOS
//We can detect if NT is running as it reports DOS v5.5
if ((lpVersionInformation->dwEmulatedMajorVersion == 5) &&
(lpVersionInformation->dwEmulatedMinorVersion == 50)) //NT reports DOS v5.5
{
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "Microsoft Windows NT");
//could not find method of determing version of NT from DOS,
//so assume 3.50
lpVersionInformation->dwUnderlyingMajorVersion = 3;
lpVersionInformation->dwUnderlyingMinorVersion = 50;
lpVersionInformation->dwUnderlyingBuildNumber = 0; //cannot get access to build number from DOS
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_NT;
}
else
{
//Get the underlying OS here via the int 2FH interface of Windows
GetWinInfo();
if (bRunningWindows)
{
if (lpVersionInformation->dwEmulatedMajorVersion >= 7) //Windows 9x marks itself as DOS 7 or DOS 8
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_WINDOWS9x;
else
{
//Could not find method of differentiating between WFW & Win3.1 under DOS,
//so assume Win3.1
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_WINDOWS3x;
}
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "Microsoft Windows");
lpVersionInformation->dwUnderlyingMajorVersion = (WinVer & 0xFF00) >> 8;
lpVersionInformation->dwUnderlyingMinorVersion = WinVer & 0x00FF;
if (lpVersionInformation->dwEmulatedMajorVersion >= 8) //Windows Me reports itself as DOS v8.0
lpVersionInformation->dwUnderlyingBuildNumber = 3000; //This is the build number for Windows ME.
else
{
if (lpVersionInformation->dwEmulatedMinorVersion == 0)
lpVersionInformation->dwUnderlyingBuildNumber = 950; //Windows 95 Gold reports DOS v7.0
else if (lpVersionInformation->dwUnderlyingMinorVersion > 0 &&
lpVersionInformation->dwUnderlyingMinorVersion < 3)
{
//Testing for 95 SP1 has not been done, so the above check
//may or may not work
lpVersionInformation->dwUnderlyingBuildNumber = 1080;
}
else if (lpVersionInformation->dwUnderlyingMinorVersion == 3)
lpVersionInformation->dwUnderlyingBuildNumber = 1212; //Windows 95 OSR2 reports DOS 7.03 from 16 bit code
else
lpVersionInformation->dwUnderlyingBuildNumber = 1998; //Windows 98 or SE. There is no way to differentiate from real mode
//between the two of them
}
}
else //must be on a real version of DOS
{
lpVersionInformation->dwUnderlyingMajorVersion = (DWORD) DosMajor;
lpVersionInformation->dwUnderlyingMinorVersion = (DWORD) DosMinor;
lpVersionInformation->dwUnderlyingBuildNumber = 0; //no build number with DOS
lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_DOS;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "");
}
}
#endif
#endif
return TRUE;
}
#if defined(_WINDOWS) && !defined(UNDER_CE)
BOOL COSVersion::WhichNTProduct(TCHAR* pszProductType)
{
//Assume the worst
BOOL bSuccess = FALSE;
//Open and the product options key
HKEY hKey;
if (RegOpenKey(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\ProductOptions"), &hKey) == ERROR_SUCCESS)
{
const int MY_BUFSIZE = 100;
TCHAR sTemp[MY_BUFSIZE];
DWORD dwBufLen = MY_BUFSIZE * sizeof(TCHAR);
#if (defined(_WIN32) || defined(_WIN64))
if (::RegQueryValueEx(hKey, _T("ProductType"), NULL, NULL, (LPBYTE) sTemp, &dwBufLen) == ERROR_SUCCESS)
#else
if (RegQueryValueEx(hKey, _T("ProductType"), NULL, NULL, (LPBYTE) sTemp, &dwBufLen) == ERROR_SUCCESS)
#endif
{
_tcscpy(pszProductType, sTemp);
bSuccess = TRUE;
}
RegCloseKey(hKey);
}
return bSuccess;
}
#else
BOOL COSVersion::WhichNTProduct(TCHAR* /*pszProductType*/)
{
return FALSE;
}
#endif //#if defined(_WINDOWS) && !defined(UNDER_CE)
#ifdef _DOS
void GetWinInfo()
{
BYTE MajorVer;
BYTE MinorVer;
//use some inline assembly to determine if Windows if
//running and what version is active
_asm
{
; check for Windows 3.1
mov ax,160ah ; WIN31CHECK
int 2fh ; check if running under Win 3.1.
or ax,ax
jz RunningUnderWin31 ; can check if running in standard
; or enhanced mode
; check for Windows 3.0 enhanced mode
mov ax,1600h ; WIN386CHECK
int 2fh
test al,7fh
jnz RunningUnderWin30Enh ; enhanced mode
; check for 3.0 WINOLDAP
mov ax,4680h ; IS_WINOLDAP_ACTIVE
int 2fh
or ax,ax ; running under 3.0 derivative?
jnz NotRunningUnderWin
; rule out MS-DOS 5.0 task switcher
mov ax,4b02h ; detect switcher
push bx
push es
push di
xor bx,bx
mov di,bx
mov es,bx
int 2fh
pop di
pop es
pop bx
or ax,ax
jz NotRunningUnderWin ; MS-DOS 5.0 task switcher found
; check for standard mode Windows 3.0
mov ax,1605h ; PMODE_START
int 2fh
cmp cx,-1
jz RunningUnderWin30Std
; check for real mode Windows 3.0
mov ax,1606h ; PMODE_STOP
int 2fh ; in case someone is counting
; Real mode Windows 3.0 is running
mov byte ptr [bRunningWindows], 1
mov byte ptr [MajorVer], 3h
mov byte ptr [MinorVer], 0h
jmp ExitLabel
RunningUnderWin30Std:
; Standard mode Windows 3.0 is running
mov byte ptr [bRunningWindows], 1
mov byte ptr [MajorVer], 3h
mov byte ptr [MinorVer], 0h
jmp ExitLabel
RunningUnderWin31:
; At this point: CX == 3 means Windows 3.1 enhanced mode
; CX == 2 means Windows 3.1 standard mode
mov byte ptr [bRunningWindows], 1
; Get the version of Windows
mov ax, 1600h ; Get Enhanced-Mode Windows Installed State
int 2Fh
mov byte ptr [MajorVer], al
mov byte ptr [MinorVer], ah
jmp ExitLabel
RunningUnderWin30Enh:
; Enhanced mode Windows 3.0 is running
mov byte ptr [bRunningWindows], 1
mov byte ptr [MajorVer], 3h
mov byte ptr [MinorVer], 0h
jmp ExitLabel
NotRunningUnderWin:
mov byte ptr [bRunningWindows], 0
ExitLabel:
}
WinVer = (WORD) ((MajorVer << 8) + MinorVer);
}
#endif //_DOS
BOOL COSVersion::IsWindowsCE(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWSCE);
}
BOOL COSVersion::IsWindows95(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion == 0 &&
lpVersionInformation->dwUnderlyingBuildNumber == 950);
}
BOOL COSVersion::IsWindows95SP1(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingBuildNumber > 950 &&
lpVersionInformation->dwUnderlyingBuildNumber <= 1080);
}
BOOL COSVersion::IsWindows95OSR2(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion < 10 &&
lpVersionInformation->dwUnderlyingBuildNumber > 1080);
}
BOOL COSVersion::IsWindows98(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion == 10 &&
lpVersionInformation->dwUnderlyingBuildNumber == 1998);
}
BOOL COSVersion::IsWindows98SP1(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion == 10 &&
lpVersionInformation->dwUnderlyingBuildNumber > 1998 &&
lpVersionInformation->dwUnderlyingBuildNumber < 2183);
}
BOOL COSVersion::IsWindows98SE(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion == 10 &&
lpVersionInformation->dwUnderlyingBuildNumber >= 2183);
}
BOOL COSVersion::IsWindowsME(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_WINDOWS9x &&
lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion == 90);
}
BOOL COSVersion::IsWindowsNT31(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_NT &&
lpVersionInformation->dwUnderlyingMajorVersion == 3 &&
lpVersionInformation->dwUnderlyingMinorVersion == 10);
}
BOOL COSVersion::IsWindowsNT35(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_NT &&
lpVersionInformation->dwUnderlyingMajorVersion == 3 &&
lpVersionInformation->dwUnderlyingMinorVersion == 50);
}
BOOL COSVersion::IsWindowsNT351(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_NT &&
lpVersionInformation->dwUnderlyingMajorVersion == 3 &&
lpVersionInformation->dwUnderlyingMinorVersion == 51);
}
BOOL COSVersion::IsWindowsNT4(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_NT &&
lpVersionInformation->dwUnderlyingMajorVersion == 4);
}
BOOL COSVersion::IsWindows2000(LPOS_VERSION_INFO lpVersionInformation)
{
return (lpVersionInformation->dwUnderlyingPlatformId == DT_PLATFORM_NT &&
lpVersionInformation->dwUnderlyingMajorVersion == 5 &&
lpVersionInformation->dwUnderlyingMinorVersion == 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -