liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1148回复:3

从别处取系统版本号(原代码)

楼主#
更多 发布于:2008-02-01 03:30
近日给人做项目,他说在有些系统下使用API得不到真正的系统版本号。
可能是有人修改了吧。
特意写了这个函数.取系统版本号.

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD dwMajorVer,dwVer;
    dwVer = ::GetVersion();
    
    GetWindowsVerInfo(&dwMajorVer,TRUE);

    printf("Windows Version:%08X(%08X)\n",dwMajorVer,dwVer);

    return 0;
}

//////////////////////////////////////////////////////////////////////////////
//
// Liio Library
//
// GetWindowsVerInfo:
//
//        得到系统的版本号
//
//    bFlag:
//        
//        若为True,则发生失败时使用GetVersion返回版本号,函数返回值为FALSE
//        若为False,则失败时版本号返回为0.
//
//////////////////////////////////////////////////////////////////////////////

BOOL
GetWindowsVerInfo(
                  DWORD    *dwVer,
                  BOOL    bFlag
                  )
{
    BOOL        bRet = FALSE;
    FILE_OPEN    pFileOpen = {0};
    FILE_READ    pFileRead = {0};

    // Windows 所在目录
    CHAR        szWindowsPath[MAX_PATH] = {'\0'};
    CHAR        szReadFilePath[MAX_PATH] = {'\0'};

    // 存放DOS头部的缓冲区
    IMAGE_DOS_HEADER DosHeader = {0};
    IMAGE_NT_HEADERS NtHeader = {0};
    
    // 初始化返回值
    *dwVer = 0x00;
    
    pFileOpen.AccessType = GENERIC_READ;
    pFileOpen.FileType = OPEN_EXISTING;

    // 取当前系统的安装目录,失败则根据bFlag返回版本
    if(! GetWindowsDirectory(szWindowsPath ,MAX_PATH))
    {
        bRet = FALSE;
        goto done;
    }

    wsprintf(szReadFilePath ,"%s\\explorer.exe",szWindowsPath);

    // 放弃对文件小于 1KB的操作,根据bFlag返回版本
    bRet = OpenDevice(szReadFilePath,&pFileOpen);
    if(!bRet)
    {
        goto done;
    }

    if(pFileOpen.FileSize < 1024)
    {
        bRet = FALSE;
        CloseDevice(pFileOpen.hFile);
        goto done;
    }

    // 得到DOS头部内容,取PE头部地址
    pFileRead.Buffer = &DosHeader;
    pFileRead.BufferSize = sizeof(IMAGE_DOS_HEADER);
    pFileRead.hFile = pFileOpen.hFile;

    bRet = ReadDevice(&pFileRead);
    
    if(!bRet)
    {
        CloseDevice(pFileOpen.hFile);
        goto done;
    }

    // 验证是否为PE文件
    if(DosHeader.e_magic != IMAGE_DOS_SIGNATURE)
    {
        bRet = FALSE;
        CloseDevice(pFileOpen.hFile);
        goto done;
    }

    // 指定文件从 e_lfanew 开始读
    pFileRead.Li.LowPart = DosHeader.e_lfanew;
    pFileRead.Buffer = &NtHeader;
    pFileRead.BufferSize = sizeof(IMAGE_NT_HEADERS);
    pFileRead.hFile = pFileOpen.hFile;

    bRet = ReadDevice(&pFileRead);
    if(!bRet)
    {
        CloseDevice(pFileOpen.hFile);
        goto done;
    }

    // 验证PE头部合法
    if(NtHeader.Signature != IMAGE_NT_SIGNATURE)
    {
        bRet = FALSE;
        CloseDevice(pFileOpen.hFile);
        goto done;
    }

    *dwVer = ((*dwVer = NtHeader.OptionalHeader.MajorOperatingSystemVersion) << 8 ) | NtHeader.OptionalHeader.MinorOperatingSystemVersion;

    CloseDevice(pFileOpen.hFile);

    goto done;

done:
    if(bFlag && (!bRet))
    {
        *dwVer = GetVersion();
    }
    return bRet;
}
liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2008-02-01 03:31
文件读写 部分的API封装了下。大家自己改下就能用的
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-02-01 13:27
取explorer.exe不如取ntoskrnl.exe
liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2008-02-01 16:33
哈哈,对。
改之。
谢谢!
游客

返回顶部