-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.v
244 lines (213 loc) · 6.68 KB
/
functions.v
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
module winreg
import winerror
#include <windows.h>
$if windows {
$if tinyc {
#flag -ladvapi32
}
}
// open_key Opens a specific Windows registry key.
//
// ### How to use:
// ```v
// handle_key := winreg.open_key(.hkey_local_machine, r'SOFTWARE\Microsoft\Windows\CurrentVersion', .key_read)!
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn open_key(hkey HKEYS, subkey string, mode AccessMode) !HandleKey {
mut result_hkey := unsafe { nil }
mut result := C.RegOpenKeyEx(u64(hkey), subkey.to_wide(), 0, int(mode), &result_hkey)
if result != winerror.error_success {
return winerror.ErrorRegistry{
code_error_c: result
}
}
return HandleKey.new(hkey, subkey, result_hkey, mode)
}
// close closes a connection to windows registry.
//
// ### How to use:
// ```v
// handle_key := winreg.open_key(.hkey_local_machine, r'SOFTWARE\Microsoft\Windows\CurrentVersion', .key_read)!
//
// handle_key.close()!
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn (h HandleKey) close() ! {
result := C.RegCloseKey(h.hkey_ptr)
if result != winerror.error_success {
return winerror.ErrorRegistry{
code_error_c: result
}
}
}
// get_value takes a value of types REG_SZ and REG_DWORD, and returns it as DwValue.
// If you don't know the type of the value, this function can help a lot.
//
// ### How to use:
// ```v
// program_files_dir := handle_key.get_value("ProgramFilesDir")!
//
// if program_files_dir is string {
// println('program_files_dir is string: "$program_files_dir"')
// } else {
// println('program_files_dir is int: "$program_files_dir"')
// }
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn (h HandleKey) get_value(reg string) !DwValue {
typ := h.get_type_reg_value(reg)!
return if typ == u32(DwType.reg_dword) {
h.query_value[int](reg)!
} else {
h.query_value[string](reg)!
}
}
// query_value[T] takes a value of types REG_SZ and REG_DWORD, and returns it with the specified generic type.
// You need to know exactly what type is expected, if the value is a REG_DWORD and T is equal to a string
// Some invalid data will then be returned.
//
// ### How to use:
// ```v
// program_files_dir := handle_key.query_value[string]("ProgramFilesDir")!
//
// println('program_files_dir is my string: "$program_files_dir"')
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn (h HandleKey) query_value[T](reg string) !T {
size := h.get_lenth_reg_value(reg)!
typ := h.get_type_reg_value(reg)!
value := unsafe { &u16(malloc(int(size))) }
mut result := 0
result = C.RegQueryValueEx(h.hkey_ptr, reg.to_wide(), 0, &typ, value, &size)
if result != winerror.error_success {
return winerror.ErrorRegistry{
code_error_c: result
}
}
$if T is $int {
return *value
} $else {
return unsafe { string_from_wide(value) }
}
}
// enumerate_values_info Enumerates the values information of a registry key.
// Retrieves information about all the values present in the registry key.
//
// ### How to use:
// ```v
// h := winreg.open_key(.hkey_current_user, r"Software\Microsoft\Windows\CurrentVersion")
//
// values := h.enumerate_values_info()!
//
// for value in values {
//
// println("Value Name: ${value.name} | Value Type: ${value.typ}")
//
// }
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn (h HandleKey) enumerate_values_info() ![]InfoValues {
mut values := []InfoValues{}
mut i := 0
for {
values << h.info_value(i, 0) or {
if err.code() == winerror.error_no_more_items {
break
} else {
return err
}
}
i++
}
return values
}
// info_value returns information about a specific value in the Windows registry.
// Parameter:
// - index: the index of the value to be queried.
// - initial_name_size: the initial size for memory allocation of the value name (256 default).
// Return:
// - InfoValues: structure containing name and type of the value.
// - !ErrorRegistry: in case of error, returns an ErrorRegistry containing the error code (.code()) and error message (.msg()).
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
@[manualfree]
fn (h HandleKey) info_value(index int, initial_name_size int) !InfoValues {
mut value := InfoValues{}
mut name_len := u32(256)
if initial_name_size > 0 {
name_len = u32(initial_name_size)
}
mut name := unsafe { &u16(malloc(name_len)) }
mut typ := u32(0)
result := C.RegEnumValue(h.hkey_ptr, index, name, &name_len, 0, &typ, 0, 0)
if result == winerror.error_more_data {
value = h.info_value(index, name_len * 2)!
} else if result == winerror.error_success {
value.name = unsafe { string_from_wide(name) }
value.typ = DwType.get(typ)!
} else {
return winerror.ErrorRegistry{
code_error_c: result
}
}
unsafe {
free(name)
}
return value
}
// delete_value deletes a value from the registry.
// To delete registry values, the application must have elevated permissions on the OS.
//
// ### How to use:
// ```v
// handle_key.delete_value("ProgramFilesDir")! // Be careful when testing! ⚠️
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn (h HandleKey) delete_value(reg string) ! {
result := C.RegDeleteValue(h.hkey_ptr, reg.to_wide())
if result != winerror.error_success {
return winerror.ErrorRegistry{
code_error_c: result
}
}
}
// set_value modifies and creates a new value in the registry.
// Its REG_SZ and REG_DWORD value is given through the value passed in dw_value.
//
// ### How to use:
// ```v
// handle_key.set_value("test", 123)! // REG_DWORD
// handle_key.set_value("test", 123.3)! // REG_SZ
// handle_key.set_value("test", "123")! // REG_SZ
// ```
//
// If any error occurs due to lack of permission, etc... it will return a winerror.ErrorRegistry
pub fn (h HandleKey) set_value(reg string, dw_value DwValue) ! {
result := if dw_value is int {
value := int(dw_value)
len_value := sizeof(value)
C.RegSetValueExW(h.hkey_ptr, reg.to_wide(), 0, u32(DwType.reg_dword), &value,
&len_value)
} else if dw_value is f32 {
value := f32(dw_value).str()
len_value := sizeof(value)
C.RegSetValueExW(h.hkey_ptr, reg.to_wide(), 0, u32(DwType.reg_sz), &value, &len_value)
} else if dw_value is string {
value := dw_value.str().to_wide()
len_value := sizeof(dw_value)
C.RegSetValueExW(h.hkey_ptr, reg.to_wide(), 0, u32(DwType.reg_sz), value, &len_value)
} else {
return error("'dw_value' type not found")
}
if result != winerror.error_success {
return winerror.ErrorRegistry{
code_error_c: result
}
}
}