diff options
Diffstat (limited to 'base/win/windows_version.cc')
-rw-r--r-- | base/win/windows_version.cc | 110 |
1 files changed, 77 insertions, 33 deletions
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index 7a8b8fd..d2f766e 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc @@ -6,17 +6,81 @@ #include <windows.h> +#include "base/file_version_info_win.h" +#include "base/files/file_path.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "base/strings/utf_string_conversions.h" #include "base/win/registry.h" namespace { typedef BOOL (WINAPI *GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD); -} +} // namespace namespace base { namespace win { +namespace { + +// Helper to map a major.minor.x.build version (e.g. 6.1) to a Windows release. +Version MajorMinorBuildToVersion(int major, int minor, int build) { + if ((major == 5) && (minor > 0)) { + // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003. + return (minor == 1) ? VERSION_XP : VERSION_SERVER_2003; + } else if (major == 6) { + switch (minor) { + case 0: + // Treat Windows Server 2008 the same as Windows Vista. + return VERSION_VISTA; + case 1: + // Treat Windows Server 2008 R2 the same as Windows 7. + return VERSION_WIN7; + case 2: + // Treat Windows Server 2012 the same as Windows 8. + return VERSION_WIN8; + default: + DCHECK_EQ(minor, 3); + return VERSION_WIN8_1; + } + } else if (major == 10) { + if (build < 10586) { + return VERSION_WIN10; + } else { + return VERSION_WIN10_TH2; + } + } else if (major > 6) { + NOTREACHED(); + return VERSION_WIN_LAST; + } + + NOTREACHED(); + return VERSION_WIN_LAST; +} + +// Retrieve a version from kernel32. This is useful because when running in +// compatibility mode for a down-level version of the OS, the file version of +// kernel32 will still be the "real" version. +Version GetVersionFromKernel32() { + scoped_ptr<FileVersionInfoWin> file_version_info( + static_cast<FileVersionInfoWin*>( + FileVersionInfoWin::CreateFileVersionInfo( + base::FilePath(FILE_PATH_LITERAL("kernel32.dll"))))); + if (file_version_info) { + const int major = + HIWORD(file_version_info->fixed_file_info()->dwFileVersionMS); + const int minor = + LOWORD(file_version_info->fixed_file_info()->dwFileVersionMS); + const int build = + HIWORD(file_version_info->fixed_file_info()->dwFileVersionLS); + return MajorMinorBuildToVersion(major, minor, build); + } + + NOTREACHED(); + return VERSION_WIN_LAST; +} + +} // namespace + // static OSInfo* OSInfo::GetInstance() { // Note: we don't use the Singleton class because it depends on AtExitManager, @@ -35,6 +99,8 @@ OSInfo* OSInfo::GetInstance() { OSInfo::OSInfo() : version_(VERSION_PRE_XP), + kernel32_version_(VERSION_PRE_XP), + got_kernel32_version_(false), architecture_(OTHER_ARCHITECTURE), wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) { OSVERSIONINFOEX version_info = { sizeof version_info }; @@ -42,38 +108,8 @@ OSInfo::OSInfo() version_number_.major = version_info.dwMajorVersion; version_number_.minor = version_info.dwMinorVersion; version_number_.build = version_info.dwBuildNumber; - if ((version_number_.major == 5) && (version_number_.minor > 0)) { - // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003. - version_ = (version_number_.minor == 1) ? VERSION_XP : VERSION_SERVER_2003; - } else if (version_number_.major == 6) { - switch (version_number_.minor) { - case 0: - // Treat Windows Server 2008 the same as Windows Vista. - version_ = VERSION_VISTA; - break; - case 1: - // Treat Windows Server 2008 R2 the same as Windows 7. - version_ = VERSION_WIN7; - break; - case 2: - // Treat Windows Server 2012 the same as Windows 8. - version_ = VERSION_WIN8; - break; - default: - DCHECK_EQ(version_number_.minor, 3); - version_ = VERSION_WIN8_1; - break; - } - } else if (version_number_.major == 10) { - if (version_number_.build < 10586) { - version_ = VERSION_WIN10; - } else { - version_ = VERSION_WIN10_TH2; - } - } else if (version_number_.major > 6) { - NOTREACHED(); - version_ = VERSION_WIN_LAST; - } + version_ = MajorMinorBuildToVersion( + version_number_.major, version_number_.minor, version_number_.build); service_pack_.major = version_info.wServicePackMajor; service_pack_.minor = version_info.wServicePackMinor; @@ -149,6 +185,14 @@ OSInfo::OSInfo() OSInfo::~OSInfo() { } +Version OSInfo::Kernel32Version() const { + if (!got_kernel32_version_) { + kernel32_version_ = GetVersionFromKernel32(); + got_kernel32_version_ = true; + } + return kernel32_version_; +} + std::string OSInfo::processor_model_name() { if (processor_model_name_.empty()) { const wchar_t kProcessorNameString[] = |