Bug 1861709 replace AudioCallbackDriver::ThreadRunning() assertions that mean to...
[gecko.git] / toolkit / components / utils / WindowsInstallsInfo.sys.mjs
blobb599687e6cd70c4de8b12d24809bbf15df5ae198
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 export var WindowsInstallsInfo = {
6   /**
7    * Retrieve install paths of this app, based on the values in the TaskBarIDs registry key.
8    *
9    * Installs from unarchived packages do not have a TaskBarID registry key and
10    * therefore won't appear in the result.
11    *
12    * @param {Number} [limit] Optional, maximum number of installation paths to count.
13             Defaults to 1024.
14    * @param {Set} [exclude] Optional, an Set of paths to exclude from the count.
15    * @returns {Set} Set of install paths, lower cased.
16    */
17   getInstallPaths(limit = 1024, exclude = new Set()) {
18     // This is somewhat more complicated than just collecting all values because
19     // the same install can be listed in both HKCU and HKLM.  The strategy is to
20     // add all paths to a Set to deduplicate.
22     const lcExclude = new Set();
23     exclude.forEach(p => lcExclude.add(p.toLowerCase()));
25     // Add the names of the values under `rootKey\subKey` to `set`.
26     // All strings are lower cased first, as Windows paths are not case-sensitive.
27     function collectValues(rootKey, wowFlag, subKey, set) {
28       const key = Cc["@mozilla.org/windows-registry-key;1"].createInstance(
29         Ci.nsIWindowsRegKey
30       );
32       try {
33         key.open(rootKey, subKey, key.ACCESS_READ | wowFlag);
34       } catch (_e) {
35         // The key may not exist, ignore.
36         // (nsWindowsRegKey::Open doesn't provide detailed error codes)
37         return;
38       }
39       const valueCount = key.valueCount;
41       try {
42         for (let i = 0; i < valueCount; ++i) {
43           const path = key.getValueName(i).toLowerCase();
44           if (!lcExclude.has(path)) {
45             set.add(path);
46           }
47           if (set.size >= limit) {
48             break;
49           }
50         }
51       } finally {
52         key.close();
53       }
54     }
56     const subKeyName = `Software\\Mozilla\\${Services.appinfo.name}\\TaskBarIDs`;
58     const paths = new Set();
60     // First collect from HKLM for both 32-bit and 64-bit installs regardless of the architecture
61     // of the current application.
62     for (const wowFlag of [
63       Ci.nsIWindowsRegKey.WOW64_32,
64       Ci.nsIWindowsRegKey.WOW64_64,
65     ]) {
66       collectValues(
67         Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
68         wowFlag,
69         subKeyName,
70         paths
71       );
72       if (paths.size >= limit) {
73         break;
74       }
75     }
77     if (paths.size < limit) {
78       // Then collect from HKCU.
79       // HKCU\Software is shared between 32 and 64 so nothing special is needed for WOW64,
80       // ref https://docs.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys
81       collectValues(
82         Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
83         0 /* wowFlag */,
84         subKeyName,
85         paths
86       );
87     }
89     return paths;
90   },