absl::StatusOr GetSystemVersionInfo()

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;
}