EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
win-deskutils.js
Go to the documentation of this file.
1/*
2Copyright 2022 Intel Corporation
3@author Bryan Roe
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16*/
17
18//
19// win-deskutils is a utility module that exposes various desktop related features for Windows
20// such as MouseTrails Accessability and Windows Desktop Background
21//
22
23//
24// MSDN documention for the system call this module relies on can be found at:
25// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa
26//
27
28var SPI_GETDESKWALLPAPER = 0x0073;
29var SPI_SETDESKWALLPAPER = 0x0014;
30var SPI_GETMOUSETRAILS = 0x005E;
31var SPI_SETMOUSETRAILS = 0x005D;
32
33var GM = require('_GenericMarshal');
34var user32 = GM.CreateNativeProxy('user32.dll');
35user32.CreateMethod('SystemParametersInfoA');
36
37//
38// This function is a helper method to dispatch method calls to different user sessions
39//
40function sessionDispatch(tsid, parent, method, args)
41{
42 //
43 // Check to see if the process owner of the current processor is root
44 //
45 var sid = undefined;
46 var stype = require('user-sessions').getProcessOwnerName(process.pid).tsid == 0 ? 1 : 0;
47 /*
48 The following is the list of possible values for stype.
49 If the current process owner is root, we set the stype to user,
50 because we cannot set/get any properties from this user, we
51 must switch to a user session.. Default behavior for stype(1)
52 is that it will context switch to the logged in user. If
53 this is not intended, then an actual user TSID must be specified, using
54 ILibProcessPipe_SpawnTypes_SPECIFIED_USER and the actual TSID
55 ------------------------------------------------------------------------
56 ILibProcessPipe_SpawnTypes_DEFAULT = 0,
57 ILibProcessPipe_SpawnTypes_USER = 1,
58 ILibProcessPipe_SpawnTypes_WINLOGON = 2,
59 ILibProcessPipe_SpawnTypes_TERM = 3,
60 ILibProcessPipe_SpawnTypes_DETACHED = 4,
61 ILibProcessPipe_SpawnTypes_SPECIFIED_USER = 5,
62 ILibProcessPipe_SpawnTypes_POSIX_DETACHED = 0x8000
63 ------------------------------------------------------------------------
64 */
65 console.log('stype: ' + stype);
66 if (stype == 1)
67 {
68 if (tsid == null && require('MeshAgent')._tsid != null)
69 {
70 stype = 5; // ILibProcessPipe_SpawnTypes_SPECIFIED_USER
71 sid = require('MeshAgent')._tsid; // If this is set, it was set via user selection UI
72 }
73 else
74 {
75 sid = tsid; // Set the SID to be whatever was passed in
76 }
77 }
78
79 // Spawn a child process in the appropriate user session, and relay the response back via stdout
80 var mod = Buffer.from(getJSModule('win-deskutils')).toString('base64');
81 var prog = "try { addModule('win-deskutils', process.env['win_deskutils']);} catch (x) { } var x;try{x=require('win-deskutils').dispatch('" + parent + "', '" + method + "', " + JSON.stringify(args) + ");console.log(x);}catch(z){console.log(z);process.exit(1);}process.exit(0);";
82 var child = require('child_process').execFile(process.execPath, [process.execPath.split('\\').pop(), '-b64exec', Buffer.from(prog).toString('base64')], { type: stype, uid: sid, env: { win_deskutils: getJSModule('win-deskutils') } });
83
84 child.stdout.str = '';
85 child.stdout.on('data', function (c) { this.str += c.toString(); });
86 child.stderr.on('data', function (c) { });
87 child.on('exit', function (c) { this.exitCode = c; });
88 child.waitExit();
89 if (child.exitCode == 0)
90 {
91 return (child.stdout.str.trim()); // If the return code was 0, then relay the response from stdout
92 }
93 else
94 {
95 throw (child.stdout.str.trim()); // If the return code was nonzero, then the stdout response is the exception that should be bubbled
96 }
97}
98
99//
100// This function gets the path of the windows desktop background of the specified user desktop session
101//
102function background_get(tsid)
103{
104 if (tsid != null || tsid === null) // TSID is not undefined or is explicitly null
105 {
106 // Need to disatch to different session first
107 return (sessionDispatch(tsid, 'background', 'get', []));
108 }
109 var v = GM.CreateVariable(1024);
110 var ret = user32.SystemParametersInfoA(SPI_GETDESKWALLPAPER, v._size, v, 0);
111 if (ret.Val == 0)
112 {
113 throw ('Error occured trying to fetch wallpaper');
114 }
115 return (v.String);
116}
117
118//
119// This function sets the path for the windows desktop background of the specified user desktop session
120//
121function background_set(path, tsid)
122{
123 if (tsid != null || tsid === null) // TSID is not undefined or is explicitly null
124 {
125 // Need to disatch to different session first
126 return (sessionDispatch(tsid, 'background', 'set', [path]));
127 }
128 var nb = GM.CreateVariable(path);
129 var ret = user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, nb._size, nb, 0);
130 if (ret.Val == 0)
131 {
132 throw ('Error occured trying to set wallpaper');
133 }
134 return;
135}
136
137//
138// This is a helper function that is called by the child process from sessionDispatch()
139//
140function dispatch(parent, method, args)
141{
142 try
143 {
144 return (this[parent][method].apply(this, args));
145 }
146 catch (e)
147 {
148 console.log('ERROR: ' + e);
149 throw ('Error occured trying to dispatch: ' + method);
150 }
151}
152
153//
154// This function sets the mousetrail accessibility feature, for the specified user desktop session.
155// Setting value 0 or one disables this feature
156// Otherwise, value is the number of cursors to render for this feature
157//
158function mousetrails_set(value, tsid)
159{
160 if (tsid != null || tsid === null) // TSID is not undefined or is explicitly null
161 {
162 // Need to disatch to different session first
163 return (sessionDispatch(tsid, 'mouse', 'setTrails', [value]));
164 }
165 var ret = user32.SystemParametersInfoA(SPI_SETMOUSETRAILS, value, 0, 0);
166 if (ret.Val == 0)
167 {
168 throw ('Error occured trying to fetch wallpaper');
169 }
170}
171
172//
173// This function returns the number of cursors the mousetrail accessibility feature will render
174// A value of 0 or 1 means the feature is disabled, otherwise it is the number of cursors that will be rendered
175//
176function mousetrails_get(tsid)
177{
178 if (tsid != null || tsid === null) // TSID is not undefined or is explicitly null
179 {
180 // Need to disatch to different session first
181 return (sessionDispatch(tsid, 'mouse', 'getTrails', []));
182 }
183 var v = GM.CreateVariable(4);
184 var ret = user32.SystemParametersInfoA(SPI_GETMOUSETRAILS, v._size, v, 0);
185 if (ret.Val == 0)
186 {
187 throw ('Error occured trying to fetch wallpaper');
188 }
189 return (v.toBuffer().readUInt32LE());
190}
191
192module.exports = { background: { get: background_get, set: background_set } };
193module.exports.mouse = { getTrails: mousetrails_get, setTrails: mousetrails_set };
194module.exports.dispatch = dispatch;