📄 dtwinver.cpp
字号:
/*
Module : dtwinver.cpp
Purpose: Implementation of a comprehensive function to perform OS version detection
Created: PJN / DATE/2 / 11-05-1996
History: PJN / DATE2.1 / 24-02-1997 A number of updates including support for NT 3.1,
single mode dos in Windows 95 and better Windows
version detecion under real mode dos.
Copyright (c) 1996 - 1997 by PJ Naughter.
All rights reserved.
*/
///////////////////////////////// Includes //////////////////////////////////
#ifdef _WINDOWS
#include <afxwin.h>
#else
#include <afx.h>
#endif
#include "dtwinver.h"
#include <stdarg.h>
///////////////////////////////// Local function / variables /////////////////
#ifndef _WIN32
//taken from Win32 sdk winbase.h file
#define VER_PLATFORM_WIN32s 0
#define VER_PLATFORM_WIN32_WINDOWS 1
#define VER_PLATFORM_WIN32_NT 2
#else
BOOL WhichNTProduct(DWORD& dwVersion);
#endif //ifndef _WIN32
#if defined(_WINDOWS) && defined(_WIN32)
// Function pointers to stuff in Kernel (32 bit)
typedef BOOL (WINAPI *lpfnGetVersionEx) (LPOSVERSIONINFO);
#endif //defined(_WINDOWS) && defined(_WIN32)
#if defined(_WINDOWS) && !defined(_WIN32) //required for universal thunks
#define HINSTANCE32 DWORD
#define HFILE32 DWORD
#define HWND32 DWORD
// #defines for WOWCallProc32() parameter conversion
#define PARAM_01 0x00000001
// #defines for dwCapBits
#define WOW_LOADLIBRARY 0x0001
#define WOW_FREELIBRARY 0x0002
#define WOW_GETPROCADDRESS 0x0004
#define WOW_CALLPROC 0x0008
#define WOW_VDMPTR32 0x0010
#define WOW_VDMPTR16 0x0020
#define WOW_HWND32 0x0040
// Wrappers for functions in Kernel (16 bit)
HINSTANCE32 WINAPI WOWLoadLibraryEx32 (LPSTR, HFILE32, DWORD);
BOOL WINAPI WOWFreeLibrary32 (HINSTANCE32);
FARPROC WINAPI WOWGetProcAddress32 (HINSTANCE32, LPCSTR);
DWORD WINAPI WOWGetVDMPointer32 (LPVOID, UINT);
DWORD FAR CDECL WOWCallProc32 (FARPROC, DWORD, DWORD, ...);
UINT WINAPI WOWCreateVDMPointer16(DWORD, DWORD);
UINT WINAPI WOWDeleteVDMPointer16(UINT);
HWND32 WINAPI WOWHwndToHwnd32 (HWND);
//////////////// OSVERSIONINFO taken from Win32 sdk header file
typedef struct _OSVERSIONINFO
{
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId;
char szCSDVersion[128];
} OSVERSIONINFO, *POSVERSIONINFO, FAR *LPOSVERSIONINFO;
// Function pointers to stuff in Kernel (16 bit)
typedef HINSTANCE32 (WINAPI *lpfnLoadLibraryEx32W) (LPSTR, HFILE32, DWORD);
typedef BOOL (WINAPI *lpfnFreeLibrary32W) (HINSTANCE32);
typedef FARPROC (WINAPI *lpfnGetProcAddress32W)(HINSTANCE32, LPCSTR);
typedef DWORD (WINAPI *lpfnGetVDMPointer32W) (LPVOID, UINT);
typedef DWORD (WINAPI *lpfnCallProc32W) (FARPROC, DWORD, DWORD);
typedef WORD (WINAPI *lpfnWNetGetCaps) (WORD);
DWORD dwCapBits;
lpfnLoadLibraryEx32W LoadLibraryEx32W;
lpfnFreeLibrary32W FreeLibrary32W;
lpfnGetProcAddress32W GetProcAddress32W;
lpfnGetVDMPointer32W GetVDMPointer32W;
lpfnCallProc32W CallProc32W;
BOOL WFWLoaded();
#endif //defined(_WINDOWS) && !defined(_WIN32)
#ifdef _DOS
BYTE WinMajor;
BYTE WinMinor;
WORD WinVer;
BYTE bRunningWindows;
void GetWinInfo();
#endif //ifdef _DOS
////////////////////////////////// Macros ///////////////////////////////////
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
////////////////////////////////// Implementation /////////////////////////////
BOOL IsEmulatedWindows95(LPOS_VERSION_INFO lpVersionInformation)
{
ASSERT(lpVersionInformation->dwEmulatedPlatformId == PLATFORM_WINDOWS);
return (lpVersionInformation->dwEmulatedMajorVersion == 4 &&
lpVersionInformation->dwEmulatedMinorVersion == 0);
}
BOOL IsEmulatedWindows98(LPOS_VERSION_INFO lpVersionInformation)
{
ASSERT(lpVersionInformation->dwEmulatedPlatformId == PLATFORM_WINDOWS);
return ((lpVersionInformation->dwEmulatedMajorVersion > 4) || (lpVersionInformation->dwEmulatedMajorVersion == 4 &&
lpVersionInformation->dwEmulatedMinorVersion >= 10));
}
BOOL IsUnderlyingWindows95(LPOS_VERSION_INFO lpVersionInformation)
{
ASSERT(lpVersionInformation->dwUnderlyingPlatformId == PLATFORM_WINDOWS);
return (lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion == 0);
}
BOOL IsUnderlyingWindows98(LPOS_VERSION_INFO lpVersionInformation)
{
ASSERT(lpVersionInformation->dwUnderlyingPlatformId == PLATFORM_WINDOWS);
return ((lpVersionInformation->dwUnderlyingMajorVersion > 4) || (lpVersionInformation->dwUnderlyingMajorVersion == 4 &&
lpVersionInformation->dwUnderlyingMinorVersion >= 10));
}
BOOL GetOSVersion(LPOS_VERSION_INFO lpVersionInformation)
{
//size field must be filled in prior to call,
//this is the same behaviour as the real Win32 api
if (lpVersionInformation->dwOSVersionInfoSize != sizeof(OS_VERSION_INFO))
return FALSE;
#ifdef _WIN32
//determine dynamically if GetVersionEx is available, if
//not then drop back to using GetVersion
// Get Kernel handle
HMODULE hKernel32 = GetModuleHandle(_T("KERNEL32.DLL"));
if (hKernel32 == NULL)
return FALSE;
#ifdef _UNICODE
lpfnGetVersionEx lpGetVersionEx = (lpfnGetVersionEx) GetProcAddress(hKernel32, _T("GetVersionExW"));
#else
lpfnGetVersionEx lpGetVersionEx = (lpfnGetVersionEx) GetProcAddress(hKernel32, _T("GetVersionExA"));
#endif
if (lpGetVersionEx)
{
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!lpGetVersionEx(&osvi))
return FALSE;
lpVersionInformation->dwEmulatedMajorVersion = osvi.dwMajorVersion;
lpVersionInformation->dwEmulatedMinorVersion = osvi.dwMinorVersion;
lpVersionInformation->dwEmulatedBuildNumber = LOWORD(osvi.dwBuildNumber); //ignore HIWORD
_tcscpy(lpVersionInformation->szEmulatedCSDVersion, osvi.szCSDVersion);
//Explicitely map the win32 dwPlatformId to our own values
if (osvi.dwPlatformId == VER_PLATFORM_WIN32s)
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_WIN32S;
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_WINDOWS;
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_NT_WORKSTATION;
else
return FALSE;
//Win32s is not an OS in its own right
if (lpVersionInformation->dwEmulatedPlatformId == PLATFORM_WIN32S)
{
//Could not find a portable method of determining what Win 16
//version from within win32, so just assume Windows 3.10
lpVersionInformation->dwUnderlyingMajorVersion = 3;
lpVersionInformation->dwUnderlyingMinorVersion = 10;
lpVersionInformation->dwUnderlyingBuildNumber = 0;
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_WINDOWS31;
_tcscpy(lpVersionInformation->szUnderlyingCSDVersion, _T("Microsoft Windows"));
}
else
{
lpVersionInformation->dwUnderlyingMajorVersion = lpVersionInformation->dwEmulatedMajorVersion;
lpVersionInformation->dwUnderlyingMinorVersion = lpVersionInformation->dwEmulatedMinorVersion;
lpVersionInformation->dwUnderlyingBuildNumber = lpVersionInformation->dwEmulatedBuildNumber;
lpVersionInformation->dwUnderlyingPlatformId = lpVersionInformation->dwEmulatedPlatformId;
_tcscpy(lpVersionInformation->szUnderlyingCSDVersion, lpVersionInformation->szEmulatedCSDVersion);
//determine which version of NT we're running
DWORD dwVersion=0;
if (WhichNTProduct(dwVersion))
{
lpVersionInformation->dwUnderlyingPlatformId = dwVersion;
lpVersionInformation->dwEmulatedPlatformId = dwVersion;
}
}
}
else
{
//Since GetVersionEx is not available we need to fall back on plain
//old GetVersion. Because GetVersionEx is available on all but NT 3.1
//we can fill in some of the paramters ourselves.
DWORD dwVersion = GetVersion();
lpVersionInformation->dwEmulatedMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwEmulatedMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwEmulatedBuildNumber = 0;
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_NT_WORKSTATION;
_tcscpy(lpVersionInformation->szEmulatedCSDVersion, _T("Microsoft Windows NT"));
lpVersionInformation->dwUnderlyingMajorVersion = lpVersionInformation->dwEmulatedMajorVersion;
lpVersionInformation->dwUnderlyingMinorVersion = lpVersionInformation->dwEmulatedMinorVersion;
lpVersionInformation->dwUnderlyingBuildNumber = lpVersionInformation->dwEmulatedBuildNumber;
lpVersionInformation->dwUnderlyingPlatformId = lpVersionInformation->dwEmulatedPlatformId;
_tcscpy(lpVersionInformation->szUnderlyingCSDVersion, lpVersionInformation->szEmulatedCSDVersion);
DWORD dwPlatformID;
if ((WhichNTProduct(dwPlatformID)))
{
lpVersionInformation->dwUnderlyingPlatformId = dwPlatformID;
lpVersionInformation->dwEmulatedPlatformId = dwPlatformID;
}
else
return FALSE;
}
#else //We must be runing on an emulated or real version of Win16 or Dos
#ifdef _WINDOWS //Running on some version of Windows
DWORD dwVersion = GetVersion();
// GetVersion does not differentiate between Windows 3.1 and Windows 3.11
lpVersionInformation->dwEmulatedMajorVersion = LOBYTE(LOWORD(dwVersion));
lpVersionInformation->dwEmulatedMinorVersion = HIBYTE(LOWORD(dwVersion));
lpVersionInformation->dwEmulatedBuildNumber = 0; //no build number with Win3.1x
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_WINDOWS31;
_fstrcpy(lpVersionInformation->szEmulatedCSDVersion, "Microsoft Windows");
//GetVersion returns 3.1 even on WFW, need to poke further
//to find the real difference
if (WFWLoaded())
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_WINDOWSFW;
//Call to get the underlying OS here through 16 -> 32 bit Generic Thunk
BOOL bFoundUnderlyingOS = FALSE;
// Initialize capability bits for supplied functions
dwCapBits = WOW_VDMPTR16 | WOW_HWND32;
// Get Kernel handle
HMODULE hKernel = GetModuleHandle("KERNEL");
if (hKernel == NULL)
return FALSE;
// Dynamically link to the functions we want, setting the capability
// bits as needed
LoadLibraryEx32W = (lpfnLoadLibraryEx32W) GetProcAddress(hKernel, "LoadLibraryEx32W");
if (LoadLibraryEx32W)
dwCapBits |= WOW_LOADLIBRARY;
FreeLibrary32W = (lpfnFreeLibrary32W) GetProcAddress(hKernel, "FreeLibrary32W");
if (FreeLibrary32W)
dwCapBits |= WOW_FREELIBRARY;
GetProcAddress32W = (lpfnGetProcAddress32W) GetProcAddress(hKernel, "GetProcAddress32W");
if (GetProcAddress32W)
dwCapBits |= WOW_GETPROCADDRESS;
GetVDMPointer32W = (lpfnGetVDMPointer32W) GetProcAddress(hKernel, "GetVDMPointer32W");
if (GetVDMPointer32W)
dwCapBits |= WOW_VDMPTR32;
CallProc32W = (lpfnCallProc32W) GetProcAddress(hKernel, "CallProc32W");
if (CallProc32W)
dwCapBits |= WOW_CALLPROC;
//Call thro' the thunk to the Win32 function "GetVersionEx"
HINSTANCE32 hInstKrnl32 = WOWLoadLibraryEx32("KERNEL32.DLL", NULL, NULL);
//Because we are building the call to the function at runtime, We don't
//forget to include the A at the end to call the ASCII version of GetVersionEx
FARPROC lpfnWin32GetVersionEx = WOWGetProcAddress32(hInstKrnl32, "GetVersionExA");
if (lpfnWin32GetVersionEx)
{
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
DWORD dwSuccess = WOWCallProc32(lpfnWin32GetVersionEx, PARAM_01, 1, &osvi);
if (dwSuccess)
{
lpVersionInformation->dwUnderlyingMajorVersion = osvi.dwMajorVersion;
lpVersionInformation->dwUnderlyingMinorVersion = osvi.dwMinorVersion;
lpVersionInformation->dwUnderlyingBuildNumber = LOWORD(osvi.dwBuildNumber); //ignore HIWORD
lpVersionInformation->dwUnderlyingPlatformId = osvi.dwPlatformId;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, osvi.szCSDVersion);
//Explicitely map the win32 dwPlatformId to our own values
if (lpVersionInformation->dwEmulatedPlatformId == VER_PLATFORM_WIN32s)
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_WIN32S;
else if (lpVersionInformation->dwEmulatedPlatformId == VER_PLATFORM_WIN32_WINDOWS)
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_WINDOWS;
if (lpVersionInformation->dwEmulatedPlatformId == VER_PLATFORM_WIN32_NT)
lpVersionInformation->dwEmulatedPlatformId = PLATFORM_NT_WORKSTATION;
bFoundUnderlyingOS = TRUE;
}
}
else
{
//We failed to get GetVersionEx so try to GetVersion instead
FARPROC lpfnWin32GetVersion = WOWGetProcAddress32(hInstKrnl32, "GetVersion");
if (lpfnWin32GetVersion)
{
DWORD dwVersion = WOWCallProc32(lpfnWin32GetVersion, 0, 0);
lpVersionInformation->dwUnderlyingMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwUnderlyingMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
lpVersionInformation->dwUnderlyingBuildNumber = 0;
lpVersionInformation->dwUnderlyingPlatformId = PLATFORM_NT_WORKSTATION;
_fstrcpy(lpVersionInformation->szUnderlyingCSDVersion, "");
bFoundUnderlyingOS = TRUE;
}
}
WOWFreeLibrary32(hInstKrnl32);
if (!bFoundUnderlyingOS)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -