⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtwinver.cpp

📁 检测机器操作系统的版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
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 + -