/*
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 = lpV