Skip to content

Commit

Permalink
Bug 1628409 p1 - Move Windows version info determination into a reusa…
Browse files Browse the repository at this point in the history
…ble module r=rhelmer,chutten,mhowell

Differential Revision: https://phabricator.services.mozilla.com/D70548

--HG--
extra : moz-landing-system : lando
  • Loading branch information
Michael Cooper committed Apr 13, 2020
1 parent 69f64d8 commit 9a2ad7f
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 155 deletions.
80 changes: 6 additions & 74 deletions toolkit/components/telemetry/app/TelemetryEnvironment.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ ChromeUtils.defineModuleGetter(
"AttributionCode",
"resource:///modules/AttributionCode.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"ctypes",
"resource://gre/modules/ctypes.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"ProfileAge",
Expand All @@ -54,6 +49,11 @@ ChromeUtils.defineModuleGetter(
"fxAccounts",
"resource://gre/modules/FxAccounts.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"WindowsVersionInfo",
"resource://gre/modules/components-utils/WindowsVersionInfo.jsm"
);

// The maximum length of a string (e.g. description) in the addons section.
const MAX_ADDON_STRING_LENGTH = 100;
Expand Down Expand Up @@ -515,74 +515,6 @@ function getGfxAdapter(aSuffix = "") {
};
}

/**
* Gets the service pack and build information on Windows platforms. The initial version
* was copied from nsUpdateService.js.
*
* @return An object containing the service pack major and minor versions, along with the
* build number.
*/
function getWindowsVersionInfo() {
const UNKNOWN_VERSION_INFO = {
servicePackMajor: null,
servicePackMinor: null,
buildNumber: null,
};

if (AppConstants.platform !== "win") {
return UNKNOWN_VERSION_INFO;
}

const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;

// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType("OSVERSIONINFOEXW", [
{ dwOSVersionInfoSize: DWORD },
{ dwMajorVersion: DWORD },
{ dwMinorVersion: DWORD },
{ dwBuildNumber: DWORD },
{ dwPlatformId: DWORD },
{ szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH) },
{ wServicePackMajor: WORD },
{ wServicePackMinor: WORD },
{ wSuiteMask: WORD },
{ wProductType: BYTE },
{ wReserved: BYTE },
]);

let kernel32 = ctypes.open("kernel32");
try {
let GetVersionEx = kernel32.declare(
"GetVersionExW",
ctypes.winapi_abi,
BOOL,
OSVERSIONINFOEXW.ptr
);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;

if (0 === GetVersionEx(winVer.address())) {
throw new Error("Failure in GetVersionEx (returned 0)");
}

return {
servicePackMajor: winVer.wServicePackMajor,
servicePackMinor: winVer.wServicePackMinor,
buildNumber: winVer.dwBuildNumber,
};
} catch (e) {
return UNKNOWN_VERSION_INFO;
} finally {
kernel32.close();
}
}

/**
* Encapsulates the asynchronous magic interfacing with the addon manager. The builder
* is owned by a parent environment object and is an addon listener.
Expand Down Expand Up @@ -1967,7 +1899,7 @@ EnvironmentCache.prototype = {
const WINDOWS_UBR_KEY_PATH =
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";

let versionInfo = getWindowsVersionInfo();
let versionInfo = WindowsVersionInfo.get({ throwOnError: false });
this._osData.servicePackMajor = versionInfo.servicePackMajor;
this._osData.servicePackMinor = versionInfo.servicePackMinor;
this._osData.windowsBuildNumber = versionInfo.buildNumber;
Expand Down
124 changes: 124 additions & 0 deletions toolkit/components/utils/WindowsVersionInfo.jsm
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var EXPORTED_SYMBOLS = ["WindowsVersionInfo"];

ChromeUtils.defineModuleGetter(
this,
"AppConstants",
"resource://gre/modules/AppConstants.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"ctypes",
"resource://gre/modules/ctypes.jsm"
);

const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;

var WindowsVersionInfo = {
UNKNOWN_VERSION_INFO: {
servicePackMajor: null,
servicePackMinor: null,
buildNumber: null,
},

/**
* Gets the service pack and build number on Windows platforms.
*
* @param opts {Object} keyword arguments
* @param opts.throwOnError {boolean} Optional, defaults to true. If set to
* false will return an object with keys set to null instead of throwing an
* error. If set to true, errors will be thrown instead.
* @throws If `throwOnError` is true and version information cannot be
* determined.
* @return {object} An object containing keys `servicePackMajor`,
* `servicePackMinor`, and `buildNumber`. If `throwOnError` is false, these
* values may be null.
*/
get({ throwOnError = true } = {}) {
function throwOrUnknown(err) {
if (throwOnError) {
throw err;
}
Cu.reportError(err);
return WindowsVersionInfo.UNKNOWN_VERSION_INFO;
}

if (AppConstants.platform !== "win") {
return throwOrUnknown(
WindowsVersionInfo.NotWindowsError(
`Cannot get Windows version info on platform ${AppConstants.platform}`
)
);
}

// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType("OSVERSIONINFOEXW", [
{ dwOSVersionInfoSize: DWORD },
{ dwMajorVersion: DWORD },
{ dwMinorVersion: DWORD },
{ dwBuildNumber: DWORD },
{ dwPlatformId: DWORD },
{ szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH) },
{ wServicePackMajor: WORD },
{ wServicePackMinor: WORD },
{ wSuiteMask: WORD },
{ wProductType: BYTE },
{ wReserved: BYTE },
]);

let kernel32;
try {
kernel32 = ctypes.open("kernel32");
} catch (err) {
return throwOrUnknown(
new WindowsVersionInfo.CannotOpenKernelError(
`Unable to open kernel32! ${err}`
)
);
}

try {
let GetVersionEx = kernel32.declare(
"GetVersionExW",
ctypes.winapi_abi,
BOOL,
OSVERSIONINFOEXW.ptr
);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;

if (GetVersionEx(winVer.address()) === 0) {
throw new WindowsVersionInfo.GetVersionExError(
"Failure in GetVersionEx (returned 0)"
);
}

return {
servicePackMajor: winVer.wServicePackMajor,
servicePackMinor: winVer.wServicePackMinor,
buildNumber: winVer.dwBuildNumber,
};
} catch (err) {
return throwOrUnknown(err);
} finally {
if (kernel32) {
kernel32.close();
}
}
},

CannotOpenKernelError: class extends Error {},
GetVersionExError: class extends Error {},
NotWindowsError: class extends Error {},
};
1 change: 1 addition & 0 deletions toolkit/components/utils/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ EXTRA_JS_MODULES['components-utils'] = [
'mozjexl.js',
'PreferenceFilters.jsm',
'Sampling.jsm',
'WindowsVersionInfo.jsm',
]

XPCOM_MANIFESTS += [
Expand Down
117 changes: 36 additions & 81 deletions toolkit/modules/UpdateUtils.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const { FileUtils } = ChromeUtils.import(
);
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
ChromeUtils.defineModuleGetter(
this,
"WindowsVersionInfo",
"resource://gre/modules/components-utils/WindowsVersionInfo.jsm"
);
XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]); /* globals fetch */

ChromeUtils.defineModuleGetter(
Expand Down Expand Up @@ -545,92 +550,42 @@ XPCOMUtils.defineLazyGetter(UpdateUtils, "OSVersion", function() {

if (osVersion) {
if (AppConstants.platform == "win") {
const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;

// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType("OSVERSIONINFOEXW", [
{ dwOSVersionInfoSize: DWORD },
{ dwMajorVersion: DWORD },
{ dwMinorVersion: DWORD },
{ dwBuildNumber: DWORD },
{ dwPlatformId: DWORD },
{ szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH) },
{ wServicePackMajor: WORD },
{ wServicePackMinor: WORD },
{ wSuiteMask: WORD },
{ wProductType: BYTE },
{ wReserved: BYTE },
]);

let kernel32 = false;
// Add service pack and build number
try {
kernel32 = ctypes.open("Kernel32");
} catch (e) {
Cu.reportError("Unable to open kernel32! " + e);
osVersion += ".unknown (unknown)";
const {
servicePackMajor,
servicePackMinor,
buildNumber,
} = WindowsVersionInfo.get();
osVersion += `.${servicePackMajor}.${servicePackMinor}.${buildNumber}`;
} catch (err) {
Cu.reportError(
"Unable to retrieve windows version information: " + err
);
osVersion += ".unknown";
}

if (kernel32) {
try {
// Get Service pack info
try {
let GetVersionEx = kernel32.declare(
"GetVersionExW",
ctypes.winapi_abi,
BOOL,
OSVERSIONINFOEXW.ptr
);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;

if (0 !== GetVersionEx(winVer.address())) {
osVersion +=
"." +
winVer.wServicePackMajor +
"." +
winVer.wServicePackMinor +
"." +
winVer.dwBuildNumber;
} else {
Cu.reportError("Unknown failure in GetVersionEX (returned 0)");
osVersion += ".unknown";
}
} catch (e) {
Cu.reportError(
"Error getting service pack information. Exception: " + e
);
osVersion += ".unknown";
}

if (
Services.vc.compare(
Services.sysinfo.getProperty("version"),
"10"
) >= 0
) {
const WINDOWS_UBR_KEY_PATH =
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
let ubr = WindowsRegistry.readRegKey(
Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
WINDOWS_UBR_KEY_PATH,
"UBR",
Ci.nsIWindowsRegKey.WOW64_64
);
osVersion += ubr !== undefined ? "." + ubr : ".unknown";
}
} finally {
kernel32.close();
// add UBR if on Windows 10
if (
Services.vc.compare(Services.sysinfo.getProperty("version"), "10") >= 0
) {
const WINDOWS_UBR_KEY_PATH =
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
let ubr = WindowsRegistry.readRegKey(
Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
WINDOWS_UBR_KEY_PATH,
"UBR",
Ci.nsIWindowsRegKey.WOW64_64
);
if (ubr !== undefined) {
osVersion += `.${ubr}`;
} else {
osVersion += ".undefined;";
}

// Add processor architecture
osVersion += " (" + gWinCPUArch + ")";
}

// Add processor architecture
osVersion += " (" + gWinCPUArch + ")";
}

try {
Expand Down

0 comments on commit 9a2ad7f

Please sign in to comment.