in common/platform_win.cc [43:104]
absl::StatusOr<SystemVersionInfo> GetSystemVersionInfo() {
constexpr LPCSTR kKey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\";
HKEY key_handle;
LSTATUS open_status =
RegOpenKeyEx(HKEY_LOCAL_MACHINE, kKey, 0, KEY_READ, &key_handle);
if (open_status != ERROR_SUCCESS) {
return absl::InternalError(
absl::StrFormat("at %s: error %d opening key '%s'.",
SOURCE_LOCATION.ToString(), open_status, kKey));
}
absl::Cleanup c = [&] {
ABSL_DCHECK_EQ(RegCloseKey(key_handle), ERROR_SUCCESS);
};
auto read_string =
[&](const LPCSTR value_name) -> absl::StatusOr<std::string> {
DWORD length;
LSTATUS query_status = RegQueryValueEx(key_handle, value_name, nullptr,
nullptr, nullptr, &length);
if (query_status != ERROR_SUCCESS) {
return absl::InternalError(absl::StrFormat(
"at %s: error %d retrieving length for '%s'.",
SOURCE_LOCATION.ToString(), query_status, value_name));
}
DWORD type = REG_SZ;
std::string result(length, 0);
query_status =
RegQueryValueEx(key_handle, value_name, nullptr, &type,
reinterpret_cast<LPBYTE>(result.data()), &length);
if (query_status != ERROR_SUCCESS) {
return absl::InternalError(absl::StrFormat(
"at %s: error %d retrieving value for '%s'.",
SOURCE_LOCATION.ToString(), query_status, value_name));
}
return result;
};
auto read_dword = [&](const LPCSTR value_name) -> absl::StatusOr<DWORD> {
DWORD type = REG_DWORD;
DWORD value;
DWORD value_size = sizeof(value);
LSTATUS query_status =
RegQueryValueEx(key_handle, value_name, nullptr, &type,
reinterpret_cast<LPBYTE>(&value), &value_size);
if (query_status != ERROR_SUCCESS) {
return absl::InternalError(absl::StrFormat(
"at %s: error %d retrieving value for '%s'.",
SOURCE_LOCATION.ToString(), query_status, value_name));
}
return value;
};
SystemVersionInfo result;
ASSIGN_OR_RETURN(result.product_name, read_string("ProductName"));
ASSIGN_OR_RETURN(result.major_version,
read_dword("CurrentMajorVersionNumber"));
ASSIGN_OR_RETURN(result.minor_version,
read_dword("CurrentMinorVersionNumber"));
ASSIGN_OR_RETURN(result.release_id, read_string("ReleaseId"));
ASSIGN_OR_RETURN(result.current_build, read_string("CurrentBuild"));
return result;
}