From e741956ff79a6774a72dafd084eb5fd7425fbc3a Mon Sep 17 00:00:00 2001 From: ste Date: Wed, 8 Mar 2017 14:06:24 +0000 Subject: [PATCH 1/6] GPII-1716: Added the ability to set fWinIni SPI parameter from the solution registry. --- .../WindowsUtilities/WindowsUtilities.js | 59 +++++++++++++++++-- .../spiSettingsHandler/src/SpiChildProcess.js | 3 +- .../src/SpiSettingsHandler.js | 25 +++++--- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js index 72f56072d..501ce0286 100644 --- a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js +++ b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js @@ -170,7 +170,13 @@ windows.API_constants = { // The AccessibilityTemp values; https://msdn.microsoft.com/library/windows/desktop/bb879984.aspx disableAT: 2, - enableAT: 3 + enableAT: 3, + + // https://msdn.microsoft.com/library/ms724947 + SpiFlags: { + SPIF_UPDATEINIFILE: 0x1, + SPIF_SENDCHANGE: 0x2 + } }; fluid.each(windows.API_constants.returnCodesLookup, function (value, key) { @@ -536,21 +542,62 @@ windows.createEmptyStructure = function (structName) { * Takes an array of flag names, applies binary OR among them and returns the result. * Used to supply the "dwFlags" argument of some structures. * - * @param {Array} flagNamesArray An array of flag names. - * These should be predefined in windows.flagConstants. + * @param {Array} flagNamesArray An array of flag names, which must be in allFlags. + * @param {Array} allFlags [optional] An array of all possible flags and their value. Defaults to windows.flagConstants. + * @param {String} op [optional] The operation, either "or" (default) or "and". */ -windows.combineFlags = function (flagNamesArray) { +windows.combineFlags = function (flagNamesArray, allFlags, op) { + allFlags = allFlags || windows.flagConstants; + var or = op !== "and" && op !== "&"; + + var combine = or + ? function (left, right) { return left | right; } + : function (left, right) { return left & right; }; + var combinedFlags = 0; if (!fluid.isArrayable(flagNamesArray)) { - console.log("GPII Windows SpiSettingsHandler combineFlags: array expected!"); + fluid.log("GPII Windows SpiSettingsHandler combineFlags: array expected!"); return 0; } for (var index in flagNamesArray) { - combinedFlags = combinedFlags | windows.flagConstants[flagNamesArray[index]]; + combinedFlags = combine(combinedFlags, allFlags[flagNamesArray[index]]); } return combinedFlags; }; +/** + * Resolves a list of flags into the numeric value. Flags can either be a string, with the delimiter of either + * "|" or "&" specifying the operation, or an array of flag strings (in which case the operation is binary OR). + * + * The value of each possible flag is specified in allFlags. + * + * @param {String|Array} flags The list of flags to resolve. + * @param {Array} allFlags An associative array of every flag. + * @return {number} The numeric value of flags. + */ +windows.resolveFlags = function (flags, allFlags) { + var togo = 0; + if (!isNaN(Number(flags))) { + // Use the hard-coded number as-is + togo = Number(flags); + } else { + var op = "or"; + // Split a string into an array. + if (typeof(flags) === "string") { + var or = flags.indexOf("&") < 0; + op = or ? "or" : "and"; + flags = flags.split(/ *[&|,]+ */); + } + if (fluid.isArrayable(flags)) { + togo = gpii.windows.combineFlags(flags, allFlags, op); + } else { + fluid.log("windows.resolveFlags was passed an unknown type of flags"); + } + } + + return togo; +}; + /** * Gets the value of a given flag name. * diff --git a/gpii/node_modules/spiSettingsHandler/src/SpiChildProcess.js b/gpii/node_modules/spiSettingsHandler/src/SpiChildProcess.js index 5bf31da66..8bda36c11 100644 --- a/gpii/node_modules/spiSettingsHandler/src/SpiChildProcess.js +++ b/gpii/node_modules/spiSettingsHandler/src/SpiChildProcess.js @@ -24,6 +24,7 @@ var ffi = require("ffi"); var pvParamPrimitive = process.env.GPII_SPI_PVPARAM_PRIMITIVE === "1"; var action = process.env.GPII_SPI_ACTION; var uiParam = process.env.GPII_SPI_UIPARAM; +var fWinIni = process.env.GPII_SPI_FWININI; var pvParam, type; if (pvParamPrimitive) { @@ -40,4 +41,4 @@ var user32 = ffi.Library("user32", { ] }); -return user32.SystemParametersInfoW(action, uiParam, pvParam, 0); +return user32.SystemParametersInfoW(action, uiParam, pvParam, fWinIni); diff --git a/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js b/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js index 1b22235ec..74cf2f1c6 100644 --- a/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js +++ b/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js @@ -83,13 +83,13 @@ gpii.windows.spi.getCurrentSettings = function (payload) { return currentSettings; }; -gpii.windows.spi.systemParametersInfo = function (pvParamType, action, uiParam, pvParam) { +gpii.windows.spi.systemParametersInfo = function (pvParamType, action, uiParam, pvParam, fWinIni) { var callSuccessful = 0; if (pvParamType === "BOOL" || pvParamType === "UINT") { - callSuccessful = gpii.windows.spi.systemParametersInfoWUint.SystemParametersInfoW(action, uiParam, pvParam, 0); + callSuccessful = gpii.windows.spi.systemParametersInfoWUint.SystemParametersInfoW(action, uiParam, pvParam, fWinIni); } else { - callSuccessful = gpii.windows.spi.systemParametersInfoWPtr.SystemParametersInfoW(action, uiParam, pvParam, 0); + callSuccessful = gpii.windows.spi.systemParametersInfoWPtr.SystemParametersInfoW(action, uiParam, pvParam, fWinIni); } return callSuccessful; @@ -123,7 +123,7 @@ gpii.windows.spi.waitForSpi = function (action) { /** * Performs the SPI call in a child-process. This is used on certain SPI_SET* calls to SPI that are known to be - * troublesome and have the potential to hang. + * troublesome and have the potential to hang, or when calling with fWinIni=SPIF_SENDCHANGE. * * See GPII-2001 for an example, where a system process causes this phenomenon. While it may be possible to fix that * particular issue, it raises the question: what prevents other processes from doing the same? To work around this, @@ -136,9 +136,10 @@ gpii.windows.spi.waitForSpi = function (action) { * @param action The uiAction SPI parameter. * @param uiParam The uiParam SPI parameter. * @param pvParam The pvParam SPI parameter. + * @param fWinIni The fWinIni SPI parameter. * @return {promise} Rejects if the SPI call hangs. */ -gpii.windows.spi.callProblematicSpi = function (pvParamType, action, uiParam, pvParam) { +gpii.windows.spi.callProblematicSpi = function (pvParamType, action, uiParam, pvParam, fWinIni) { var cp = require("child_process"); var primitiveType = pvParamType in gpii.windows.types; @@ -148,7 +149,8 @@ gpii.windows.spi.callProblematicSpi = function (pvParamType, action, uiParam, pv GPII_SPI_ACTION: action, GPII_SPI_UIPARAM: uiParam, GPII_SPI_PVPARAM_PRIMITIVE: primitiveType ? 1 : 0, - GPII_SPI_PVPARAM: primitiveType ? pvParam : pvParam.toString("hex") + GPII_SPI_PVPARAM: primitiveType ? pvParam : pvParam.toString("hex"), + GPII_SPI_FWININI: fWinIni }, execArgv: [] }; @@ -190,6 +192,7 @@ gpii.windows.spi.applySettings = function (payload) { var action = gpii.windows.actionConstants[payload.options.setAction]; var uiParam = gpii.windows.spi.getUiParam(payload); var pvParam = gpii.windows.spi.getPvParam(payload); + var fWinIni = gpii.windows.resolveFlags(payload.options.fWinIni, gpii.windows.API_constants.SpiFlags); uiParam = pvParam.uiParam; // this will be updated because it looks bad pvParam = pvParam.pvParam; @@ -206,12 +209,16 @@ gpii.windows.spi.applySettings = function (payload) { // Wait for sethc.exe to end before making the SPI call gpii.windows.spi.waitForSpi() .then(function () { + // SPIF_SENDCHANGE broadcasts several messages and has the potential to block, so call it in a child + // process. + var sendChange = (fWinIni & gpii.windows.API_constants.SpiFlags.SPIF_SENDCHANGE) === + gpii.windows.API_constants.SpiFlags.SPIF_SENDCHANGE; - if (problematicSpiCalls.indexOf(action) >= 0) { - var p = gpii.windows.spi.callProblematicSpi(pvParamType, action, uiParam, pvParam); + if (sendChange || (problematicSpiCalls.indexOf(action) >= 0)) { + var p = gpii.windows.spi.callProblematicSpi(pvParamType, action, uiParam, pvParam, fWinIni); fluid.promise.follow(p, promiseTogo); } else { - var callSuccessful = gpii.windows.spi.systemParametersInfo(pvParamType, action, uiParam, pvParam); + var callSuccessful = gpii.windows.spi.systemParametersInfo(pvParamType, action, uiParam, pvParam, fWinIni); if (callSuccessful) { fluid.promise.follow(gpii.windows.spi.waitForSpi(action), promiseTogo); From c82850e4efcad1895c9aa286f1d545c4e46d8782 Mon Sep 17 00:00:00 2001 From: ste Date: Wed, 8 Mar 2017 15:44:32 +0000 Subject: [PATCH 2/6] GPII-1716: Added font-size support, via SPI_SETNONCLIENTMETRICS and SPI_SETICONTITLELOGFONT --- gpii/node_modules/WindowsUtilities/WindowsUtilities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js index 501ce0286..51968e9fd 100644 --- a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js +++ b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js @@ -580,7 +580,7 @@ windows.resolveFlags = function (flags, allFlags) { if (!isNaN(Number(flags))) { // Use the hard-coded number as-is togo = Number(flags); - } else { + } else if (flags) { var op = "or"; // Split a string into an array. if (typeof(flags) === "string") { From c2f748a0a47025dcb3e2e4c538b3daa01babe05f Mon Sep 17 00:00:00 2001 From: ste Date: Wed, 21 Jun 2017 16:01:15 +0100 Subject: [PATCH 3/6] GPII-1716: Updated reference to the working universal branch. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c1d91733..3bbe9cdfe 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "ref": "1", "ref-struct": "1", "ref-array": "1.1.2", - "universal": "gpii/universal#b58d1859e4d53303a1fdc4d74640e0c43af345e5", + "universal": "stegru/universal#GPII-1716", "nan": "amatas/nan#GPII-1929" }, "devDependencies": { From c57b1bb51f05f0e7d4df62a68eee1b18b88cf4d0 Mon Sep 17 00:00:00 2001 From: ste Date: Fri, 23 Jun 2017 10:12:12 +0100 Subject: [PATCH 4/6] GPII-1716: Minor quality improvements. --- gpii/node_modules/WindowsUtilities/WindowsUtilities.js | 4 ++-- .../node_modules/spiSettingsHandler/src/SpiSettingsHandler.js | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js index 51968e9fd..923274cca 100644 --- a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js +++ b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js @@ -586,12 +586,12 @@ windows.resolveFlags = function (flags, allFlags) { if (typeof(flags) === "string") { var or = flags.indexOf("&") < 0; op = or ? "or" : "and"; - flags = flags.split(/ *[&|,]+ */); + flags = flags.split(/ *[&|]+ */); } if (fluid.isArrayable(flags)) { togo = gpii.windows.combineFlags(flags, allFlags, op); } else { - fluid.log("windows.resolveFlags was passed an unknown type of flags"); + fluid.fail("windows.resolveFlags was passed an unknown type of flags"); } } diff --git a/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js b/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js index 74cf2f1c6..424b82d40 100644 --- a/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js +++ b/gpii/node_modules/spiSettingsHandler/src/SpiSettingsHandler.js @@ -211,8 +211,7 @@ gpii.windows.spi.applySettings = function (payload) { .then(function () { // SPIF_SENDCHANGE broadcasts several messages and has the potential to block, so call it in a child // process. - var sendChange = (fWinIni & gpii.windows.API_constants.SpiFlags.SPIF_SENDCHANGE) === - gpii.windows.API_constants.SpiFlags.SPIF_SENDCHANGE; + var sendChange = fWinIni & gpii.windows.API_constants.SpiFlags.SPIF_SENDCHANGE; if (sendChange || (problematicSpiCalls.indexOf(action) >= 0)) { var p = gpii.windows.spi.callProblematicSpi(pvParamType, action, uiParam, pvParam, fWinIni); From c2b2ac69e3a2d8cdf617e97ba2e931b437245095 Mon Sep 17 00:00:00 2001 From: ste Date: Mon, 7 May 2018 20:11:03 +0100 Subject: [PATCH 5/6] GPII-1716: Valid json. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fd52db657..ef0dd041b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "edge": "6.5.1", "edge-js": "8.8.1", "ffi": "2.0.0", - "gpii-universal": "stegru/universal#GPII-1716" + "gpii-universal": "stegru/universal#GPII-1716", "@pokusew/pcsclite": "0.4.18", "ref": "1.3.4", "ref-struct": "1.1.0", From a63c6d3c90aa31d9945c8dfbec356e0cb61fe3e7 Mon Sep 17 00:00:00 2001 From: ste Date: Sun, 24 Jun 2018 16:22:48 +0100 Subject: [PATCH 6/6] GPII-1716: Increased message pump rate to avoid timeouts in tests. A slower poll caused the WM_SETTINGCHANGE(?) broadcast from SPI_SETNONCLIENTMETRICS to delay. --- gpii/node_modules/windowMessages/src/windowMessages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpii/node_modules/windowMessages/src/windowMessages.js b/gpii/node_modules/windowMessages/src/windowMessages.js index 4d65801db..1ca0d1d0d 100644 --- a/gpii/node_modules/windowMessages/src/windowMessages.js +++ b/gpii/node_modules/windowMessages/src/windowMessages.js @@ -159,7 +159,7 @@ gpii.windows.messages.messagePump = function (that) { } if (that.messageWindow) { - setTimeout(loop, 2000); + setTimeout(loop, 300); } }; loop();