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

📄 dtwinver.cpp

📁 一个用vc获取系统硬件信息的例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
Module : Dtwinver.cpp
Purpose: Implementation of a comprehensive function to perform OS version detection
Created: PJN / 11-05-1996
History: PJN / 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.
         PJN / 13-09-1998 1.  Added explicit support for Windows 98 
                          2.  Updated documentation to use HTML. 
                          3.  Minor update to the web page describing it. 
         PJN / 22-06-1999 1.  UNICODE enabled the code.
                          2.  Removed need for the dwOSVersionInfoSize variable
                          3.  Added support for detecting Build Number of 95 and 98 from DOS code path.
                          4.  Now ships as standard with VC 5 workspace files
                          5.  Added explicit support for Windows 95 SP 1
                          6.  Added explicit support for Windows 95 OSR 2
                          7.  Added explicit support for Windows 98 Second Edition
                          8.  Added explicit support for Windows 2000
                          9.  Added explicit support for Windows CE
                          10. Added explicit support for Windows Terminal Server's
                          11. Added explicit support for NT Stand Alone Server's.
                          12. Added explicit support for NT Primary Domain Controller's
                          13. Added explicit support for NT Backup Domain Controller's
         PJN / 23-07-1999 Tested out support for Windows 98 SE, minor changes required
         PJN / 26-07-1999 Added explicit support for Windows 98 SP 1
         PJN / 28-07-1999 1. Fixed a problem when application is build in non-huge/large 
                          memory model in Win16
                          2. Added explicit support for returning NT and Win9x service pack information 
                          from Win32 and Win16 code paths
                          3. Updated test program to not bother reporting on any info which does not 
                          exist. e.g. if there is no service pack installed, then we don't bother 
                          displaying any info about service packs
                          4. Added explicit support for NT Enterprise Edition
         PJN / 30-06-2000 1. Added explicit support for Windows Millennium Edition
         PJN / 29-01-2001 1.  Added explicit support for Windows XP (Whistler) Personal
                          2.  Added explicit support for Windows XP (Whistler) Professional
                          3.  Added explicit support for Windows XP (Whistler) Server
                          4.  Added explicit support for Windows XP (Whistler) Advanced Server
                          5.  Added explicit support for Windows XP (Whistler) Datacenter
                          6.  Added explicit support for Windows XP (Whistler) 64 bit (all flavours)
                          7.  Made all the code into a C++ class called COSVersion
                          8.  Rewrote all the generic thunk code to be easier to follow
                          9. Generic think code now uses CallProcEx32W
                          10.  Added explicit support for BackOffice Small Business Edition
                          11. Added explicit support for Terminal Services
                          12. 16 bit code path now can determine ProductSuite and ProductType type
                          thro additional generic thunk code
                          13. Provided a 64 bit test binary and make batch file (make64.bat) for 
                          those lucky enough to have an Itanium processor and a beta of 64 bit Windows XP (Whistler).
                          14. Provided a Embedded C++ workspace and X86 Release binary.
                          15. Updated copyright information           
         PJN / 10-02-2001 1. Updated function names etc following MS decision to call Whistler "Windows XP"


Copyright (c) 1997 - 2001 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 
*/


/////////////////////////////////  Includes  //////////////////////////////////
#include <windows.h> 
#if defined(_WIN32) || defined(_WIN64)
#include <tchar.h>
#else
#include <ctype.h>
#include <stdlib.h>
#include <shellapi.h>
#endif
#include <string.h>
#include <stdarg.h>
#include "dtwinver.h"


/////////////////////////////////  Local function / variables /////////////////

#if defined(_WIN32)

//Taken from Windows CE winbase.h file
#ifndef VER_PLATFORM_WIN32_CE
  #define VER_PLATFORM_WIN32_CE         3
#endif

#endif //defined(_WIN32) 

#if defined(_WINDOWS) && (!defined(_WIN32) && !defined(_WIN64))  //required for universal thunks
  DWORD COSVersion::sm_dwRefCount = 0;
  COSVersion::lpfnLoadLibraryEx32W COSVersion::sm_lpfnLoadLibraryEx32W = NULL;
  COSVersion::lpfnFreeLibrary32W COSVersion::sm_lpfnFreeLibrary32W = NULL;
  COSVersion::lpfnGetProcAddress32W COSVersion::sm_lpfnGetProcAddress32W = NULL;
  COSVersion::lpfnCallProcEx32W COSVersion::sm_lpfnCallProcEx32W = NULL;
  DWORD COSVersion::sm_hAdvApi32 = 0;    
  DWORD COSVersion::sm_hKernel32 = 0;
  DWORD COSVersion::sm_lpfnRegQueryValueExA= 0;
  DWORD COSVersion::sm_lpfnGetVersionExA = 0;
  DWORD COSVersion::sm_lpfnGetVersion = 0;
#endif //defined(_WINDOWS) && !defined(_WIN32)

#ifdef _DOS
  WORD WinVer;
  BYTE bRunningWindows;
  void GetWinInfo();
#endif //ifdef _DOS



////////////////////////////////// Implementation /////////////////////////////
COSVersion::COSVersion()
{
#if defined(_WINDOWS) && (!defined(_WIN32) && !defined(_WIN64))
  if (sm_dwRefCount == 0)
  {
    // Get Kernel dll handle
    HMODULE hKernel = GetModuleHandle("KERNEL");
    if (hKernel)
    {
      // Dynamically link to the functions we want, setting the capability
      sm_lpfnLoadLibraryEx32W  = (lpfnLoadLibraryEx32W)  GetProcAddress(hKernel, "LoadLibraryEx32W");
      sm_lpfnFreeLibrary32W    = (lpfnFreeLibrary32W)    GetProcAddress(hKernel, "FreeLibrary32W");
      sm_lpfnGetProcAddress32W = (lpfnGetProcAddress32W) GetProcAddress(hKernel, "GetProcAddress32W");
      sm_lpfnCallProcEx32W     = (lpfnCallProcEx32W)     GetProcAddress(hKernel, "_CallProcEx32W");
      if (sm_lpfnLoadLibraryEx32W && sm_lpfnFreeLibrary32W)
      {
        sm_hAdvApi32 = sm_lpfnLoadLibraryEx32W("ADVAPI32.DLL", NULL, 0);
        if (sm_hAdvApi32)                                                   
          sm_lpfnRegQueryValueExA = sm_lpfnGetProcAddress32W(sm_hAdvApi32, "RegQueryValueExA"); 
        sm_hKernel32 = sm_lpfnLoadLibraryEx32W("KERNEL32.DLL", NULL, 0);
        if (sm_hKernel32)
        {                                                               
          sm_lpfnGetVersionExA = sm_lpfnGetProcAddress32W(sm_hKernel32, "GetVersionExA");
          sm_lpfnGetVersion = sm_lpfnGetProcAddress32W(sm_hKernel32, "GetVersion");
        }
      }
    }
  }
  ++sm_dwRefCount;
#endif
}

COSVersion::~COSVersion()
{                        
#if defined(_WINDOWS) && (!defined(_WIN32) && !defined(_WIN64))
  --sm_dwRefCount;
  if (sm_dwRefCount == 0)
  {
    if (sm_lpfnFreeLibrary32W)
    {           
      if (sm_hAdvApi32)
        sm_lpfnFreeLibrary32W(sm_hAdvApi32);
      if (sm_hKernel32)
        sm_lpfnFreeLibrary32W(sm_hKernel32);
    }
  }
#endif
}


#if defined(_WINDOWS) && (!defined(_WIN32) && !defined(_WIN64))
BOOL COSVersion::WFWLoaded()
{
  const WORD WNNC_NET_MultiNet         = 0x8000;
  const WORD WNNC_SUBNET_WinWorkgroups = 0x0004;
  const WORD WNNC_NET_TYPE             = 0x0002;
  BOOL rVal;
   
  HINSTANCE hUserInst = LoadLibrary("USER.EXE");
  lpfnWNetGetCaps lpWNetGetCaps = (lpfnWNetGetCaps) GetProcAddress(hUserInst, "WNetGetCaps");
  if (lpWNetGetCaps != NULL)
  {
    // Get the network type
    WORD wNetType = lpWNetGetCaps(WNNC_NET_TYPE);
    if (wNetType & WNNC_NET_MultiNet)
    {
      // a multinet driver is installed
      if (LOBYTE(wNetType) & WNNC_SUBNET_WinWorkgroups) // It is WFW
        rVal = TRUE;
      else // It is not WFW
        rVal = FALSE;
    }
    else
     rVal = FALSE;
  }
  else
    rVal = FALSE;
   
  // Clean up the module instance
  if (hUserInst)
    FreeLibrary(hUserInst);
    
  return rVal;  
}

LONG COSVersion::RegQueryValueEx(HKEY32 hKey, LPSTR  lpszValueName, LPDWORD lpdwReserved, LPDWORD lpdwType, LPBYTE  lpbData, LPDWORD lpcbData)
{                                             
  //Assume the worst
  DWORD dwResult = ERROR_CALL_NOT_IMPLEMENTED;

  if (sm_lpfnRegQueryValueExA)
    dwResult = sm_lpfnCallProcEx32W(CPEX_DEST_STDCALL | 6, 0x3e, sm_lpfnRegQueryValueExA, hKey, lpszValueName, lpdwReserved, lpdwType, lpbData, lpcbData);

  return dwResult;
}                 

BOOL COSVersion::GetVersionEx(LPOSVERSIONINFO lpVersionInfo)
{
  //Assume the worst
  BOOL bSuccess = FALSE;

  if (sm_lpfnGetVersionExA)
    bSuccess = (BOOL) sm_lpfnCallProcEx32W(CPEX_DEST_STDCALL | 1, 1, sm_lpfnGetVersionExA, lpVersionInfo, 0);

  return bSuccess;
}

DWORD COSVersion::GetVersion()
{
  //Assume the worst
  DWORD dwVersion = 0;

  if (sm_lpfnGetVersion)
    dwVersion = (BOOL) sm_lpfnCallProcEx32W(CPEX_DEST_STDCALL | 0, 0, sm_lpfnGetVersion, 0);

  return dwVersion;
}
#endif //defined(_WINDOWS) && !defined(_WIN32)

BOOL COSVersion::GetVersion(LPOS_VERSION_INFO lpVersionInformation)
{                
  //By Default assume no service pack is installed
  lpVersionInformation->wEmulatedServicePack = 0;
  lpVersionInformation->wUnderlyingServicePack = 0;

  #ifdef UNDER_CE
    OSVERSIONINFO osvi;
    memset(&osvi, 0, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (!GetVersionEx(&osvi))
      return FALSE;

    lpVersionInformation->dwEmulatedMajorVersion = osvi.dwMajorVersion; 
    lpVersionInformation->dwEmulatedMinorVersion = osvi.dwMinorVersion; 
    lpVersionInformation->dwEmulatedBuildNumber = LOWORD(osvi.dwBuildNumber); //ignore HIWORD
    _tcscpy(lpVersionInformation->szEmulatedCSDVersion, osvi.szCSDVersion);
    lpVersionInformation->dwEmulatedPlatformId = DT_PLATFORM_WINDOWSCE;

    //underlying OS is the same
    lpVersionInformation->dwUnderlyingMajorVersion = lpVersionInformation->dwEmulatedMajorVersion; 
    lpVersionInformation->dwUnderlyingMinorVersion = lpVersionInformation->dwEmulatedMinorVersion; 
    lpVersionInformation->dwUnderlyingBuildNumber = lpVersionInformation->dwEmulatedBuildNumber;
    lpVersionInformation->dwUnderlyingPlatformId = lpVersionInformation->dwEmulatedPlatformId;
    _tcscpy(lpVersionInformation->szUnderlyingCSDVersion, lpVersionInformation->szEmulatedCSDVersion);
  #elif defined(_WIN32) || defined(_WIN64)
    //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, "GetVersionExW");
    #else
      lpfnGetVersionEx lpGetVersionEx = (lpfnGetVersionEx) GetProcAddress(hKernel32, "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 
      //Also work out the various service packs which are installed
      if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
      {
        lpVersionInformation->dwEmulatedPlatformId = DT_PLATFORM_WINDOWS9x;

        //Deterine the Win9x Service pack installed
        if (IsWindows95SP1(lpVersionInformation))
        {
          lpVersionInformation->wEmulatedServicePack = 1;
          lpVersionInformation->wUnderlyingServicePack = 1;
        }
        else if (IsWindows95OSR2(lpVersionInformation))
        {
          lpVersionInformation->wEmulatedServicePack = 2;
          lpVersionInformation->wUnderlyingServicePack = 2;
        }
        else if (IsWindows98SP1(lpVersionInformation))
        {
          lpVersionInformation->wEmulatedServicePack = 1;
          lpVersionInformation->wUnderlyingServicePack = 1;
        }
      }
      else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
      {
        lpVersionInformation->dwEmulatedPlatformId = DT_PLATFORM_NT;

        //Determine the NT Service pack
        lpVersionInformation->wEmulatedServicePack = GetNTServicePackFromCSDString(osvi.szCSDVersion);
        lpVersionInformation->wUnderlyingServicePack = lpVersionInformation->wEmulatedServicePack;
      }
      else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_CE)
        lpVersionInformation->dwEmulatedPlatformId = DT_PLATFORM_WINDOWSCE;

      if (osvi.dwPlatformId == VER_PLATFORM_WIN32s)  //32 bit app running on Windows 3.x
      {
        lpVersionInformation->dwEmulatedPlatformId = DT_PLATFORM_WINDOWS9x;

        lpVersionInformation->dwUnderlyingMajorVersion = 3; 
        lpVersionInformation->dwUnderlyingMinorVersion = 10; 
        lpVersionInformation->dwUnderlyingBuildNumber = 0;
        lpVersionInformation->dwUnderlyingPlatformId = DT_PLATFORM_WINDOWS3x;
        _tcscpy(lpVersionInformation->szUnderlyingCSDVersion, _T(""));
      }
      else
      {
        lpVersionInformation->dwUnderlyingMajorVersion = lpVersionInformation->dwEmulatedMajorVersion; 
        lpVersionInformation->dwUnderlyingMinorVersion = lpVersionInformation->dwEmulatedMinorVersion; 
        lpVersionInformation->dwUnderlyingBuildNumber = lpVersionInformation->dwEmulatedBuildNumber;
        lpVersionInformation->dwUnderlyingPlatformId = lpVersionInformation->dwEmulatedPlatformId;
        _tcscpy(lpVersionInformation->szUnderlyingCSDVersion, lpVersionInformation->szEmulatedCSDVersion);
      }
    }
    else
    {
      //Since GetVersionEx is not available we need to fall back on plain
      //old GetVersion. Because GetVersionEx is available on all but v3.1 of NT
      //we can fill in some of the parameters ourselves.
      DWORD dwVersion = ::GetVersion();

      lpVersionInformation->dwEmulatedMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
      lpVersionInformation->dwEmulatedMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
      lpVersionInformation->dwEmulatedBuildNumber = 0;
      lpVersionInformation->dwEmulatedPlatformId   = DT_PLATFORM_NT;   
      lpVersionInformation->dwUnderlyingMajorVersion = lpVersionInformation->dwEmulatedMajorVersion;
      lpVersionInformation->dwUnderlyingMinorVersion = lpVersionInformation->dwEmulatedMinorVersion;
      lpVersionInformation->dwUnderlyingBuildNumber  = lpVersionInformation->dwEmulatedBuildNumber;
      lpVersionInformation->dwUnderlyingPlatformId   = lpVersionInformation->dwEmulatedPlatformId;   
      _tcscpy(lpVersionInformation->szUnderlyingCSDVersion, lpVersionInformation->szEmulatedCSDVersion);

      //Need to determine the NT Service pack by querying the registry directory.
      lpVersionInformation->wEmulatedServicePack = GetNTServicePackFromRegistry();
      lpVersionInformation->wUnderlyingServicePack = lpVersionInformation->wEmulatedServicePack;
    }
  #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   = DT_PLATFORM_WINDOWS3x;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -