/
registry.ts
140 lines (122 loc) · 3.82 KB
/
registry.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const nativeModule =
process.platform === "win32"
? require("../../build/Release/registry.node")
: null;
/**
* Utility function used to achieve exhaustive type checks at compile time.
*
* If the type system is bypassed or this method will throw an exception
* using the second parameter as the message.
*
* @param {x} Placeholder parameter in order to leverage the type
* system. Pass the variable which has been type narrowed
* in an exhaustive check.
*
* @param {message} The message to be used in the runtime exception.
*
*/
function assertNever(x: never, message: string): never {
throw new Error(message);
}
/**
* Note: not all of these are currently implemented.
*
* Source: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884(v=vs.85).aspx
*/
export enum RegistryValueType {
REG_BINARY = "REG_BINARY",
REG_DWORD = "REG_DWORD",
REG_DWORD_LITTLE_ENDIAN = "REG_DWORD_LITTLE_ENDIAN",
REG_DWORD_BIG_ENDIAN = "REG_DWORD_BIG_ENDIAN",
REG_EXPAND_SZ = "REG_EXPAND_SZ",
REG_LINK = "REG_LINK",
REG_MULTI_SZ = "REG_MULTI_SZ",
REG_NONE = "REG_NONE",
REG_QWORD = "REG_QWORD",
REG_QWORD_LITTLE_ENDIAN = "REG_QWORD_LITTLE_ENDIAN",
REG_SZ = "REG_SZ",
}
export type RegistryStringEntry = {
readonly name: string;
readonly type: RegistryValueType.REG_SZ | RegistryValueType.REG_EXPAND_SZ;
readonly data: string;
};
export type RegistryNumberEntry = {
readonly name: string;
readonly type: RegistryValueType.REG_DWORD;
readonly data: number;
};
// TODO: define some other shapes of data
export type RegistryValue = RegistryStringEntry | RegistryNumberEntry;
export enum HKEY {
HKEY_CLASSES_ROOT = "HKEY_CLASSES_ROOT",
HKEY_CURRENT_CONFIG = "HKEY_CURRENT_CONFIG",
HKEY_DYN_DATA = "HKEY_DYN_DATA",
HKEY_CURRENT_USER_LOCAL_SETTINGS = "HKEY_CURRENT_USER_LOCAL_SETTINGS",
HKEY_CURRENT_USER = "HKEY_CURRENT_USER",
HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE",
HKEY_PERFORMANCE_DATA = "HKEY_PERFORMANCE_DATA",
HKEY_PERFORMANCE_TEXT = "HKEY_PERFORMANCE_TEXT",
HKEY_PERFORMANCE_NLSTEXT = "HKEY_PERFORMANCE_NLSTEXT",
HKEY_USERS = "HKEY_USERS",
}
function mapToLong(key: HKEY): number {
if (key === HKEY.HKEY_CLASSES_ROOT) return 0x80000000;
if (key === HKEY.HKEY_CURRENT_USER) return 0x80000001;
if (key === HKEY.HKEY_LOCAL_MACHINE) return 0x80000002;
if (key === HKEY.HKEY_USERS) return 0x80000003;
if (key === HKEY.HKEY_PERFORMANCE_DATA) return 0x80000004;
if (key === HKEY.HKEY_CURRENT_CONFIG) return 0x80000005;
if (key === HKEY.HKEY_DYN_DATA) return 0x80000006;
if (key === HKEY.HKEY_CURRENT_USER_LOCAL_SETTINGS) return 0x80000007;
if (key === HKEY.HKEY_PERFORMANCE_TEXT) return 0x80000050;
if (key === HKEY.HKEY_PERFORMANCE_NLSTEXT) return 0x80000060;
return assertNever(key, "The key does not map to an expected number value");
}
export function enumerateValues(
key: HKEY,
subkey: string
): ReadonlyArray<RegistryValue> {
if (!nativeModule) {
// this code is a no-op when the module is missing
return [];
}
const hkey = mapToLong(key);
const result: ReadonlyArray<RegistryValue> = nativeModule.readValues(
hkey,
subkey
);
return result;
}
export function enumerateValuesSafe(
key: HKEY,
subkey: string
): ReadonlyArray<RegistryValue> {
try {
return enumerateValues(key, subkey);
} catch {
return [];
}
}
export function enumerateKeys(
key: HKEY,
subkey?: string | null
): ReadonlyArray<string> {
if (!nativeModule) {
// this code is a no-op when the module is missing
return [];
}
const hkey = mapToLong(key);
const result: ReadonlyArray<string> = nativeModule.enumKeys(hkey, subkey);
return result;
}
export function enumerateKeysSafe(
key: HKEY,
subkey?: string | null
): ReadonlyArray<string> {
try {
return enumerateKeys(key, subkey);
} catch {
return [];
}
}