7static wchar_t *REG_PARAM_SLASH_VE = L
"/ve ";
9wchar_t *fix_v_param(
const wchar_t *prop,
size_t prop_len,
bool *heap) {
10 wchar_t *escaped, *out;
11 escaped = out =
nullptr;
13 if (prop_len == 0 || prop ==
nullptr || !wcsncmp(L
"(default)", prop, 9)) {
15 out = REG_PARAM_SLASH_VE;
18 escaped = escape_for_batch(prop, prop_len);
19 size_t escaped_len = (7 + wcslen(escaped)) * WL;
20 out = calloc(7 + wcslen(escaped), WL);
24 memset(out, 0, escaped_len);
25 _snwprintf(out, escaped_len, L
"/v \"%ls\" ", escaped);
35wchar_t *convert_data_for_reg(DWORD reg_type,
const char *data,
size_t data_len) {
36 wchar_t *bin, *out, *s;
37 bin = out = s =
nullptr;
38 if (reg_type == REG_BINARY) {
40 size_t n_bin_chars = 2 * data_len;
41 size_t new_len = n_bin_chars + 1;
42 bin = calloc(new_len, WL);
46 wmemset(bin, L
'\0', new_len);
47 for (i = 0; i < data_len; i++) {
49 _snwprintf(conv, 3, L
"%02x", data[i]);
51 wcsncat(&bin[i], conv, 2);
53 size_t s_size = new_len + 5;
54 out = calloc(s_size, WL);
58 wmemset(out, L
'\0', s_size);
59 _snwprintf(out, s_size, L
" /d %ls ", bin);
62 if (reg_type == REG_EXPAND_SZ || reg_type == REG_SZ || reg_type == REG_MULTI_SZ) {
63 size_t w_data_len = ((data_len % WL == 0) ? data_len / WL : (data_len / WL) + 1);
64 wchar_t *w_data = (
wchar_t *)data;
65 size_t real_len = reg_type == REG_MULTI_SZ ? determine_multi_sz_size(w_data, w_data_len) : wcslen(w_data);
66 if (reg_type == REG_MULTI_SZ && real_len <= 2) {
69 s = escape_for_batch((
wchar_t *)data, real_len);
73 size_t s_size = (wcslen(s) + 8);
74 out = calloc(s_size, WL);
78 wmemset(out, L
'\0', s_size);
79 _snwprintf(out, s_size, L
" /d \"%ls\" ", s);
82 if (reg_type == REG_DWORD || reg_type == REG_QWORD) {
84 out = calloc(s_size, WL);
88 memset(out, 0, s_size);
89 if (reg_type == REG_DWORD) {
90 _snwprintf(out, s_size, L
" /d %lu ", *(DWORD *)data);
92 _snwprintf(out, s_size, L
" /d %llu ", *(UINT64 *)data);
105bool do_write_reg_command(writer_t *writer,
106 const wchar_t *full_path,
110 unsigned long type) {
112 wchar_t *out =
nullptr;
113 wchar_t *escaped_d = convert_data_for_reg(type, value, data_len);
114 wchar_t *escaped_reg_key = escape_for_batch(full_path, wcslen(full_path));
116 wchar_t *v_param = fix_v_param(prop, prop ? wcslen(prop) : 0, &v_heap);
117 wchar_t reg_type[14];
118 if (!escaped_reg_key || !v_param) {
121 if (type == REG_MULTI_SZ && !escaped_d) {
124 wmemset(reg_type, L
'\0', 14);
127 wcsncpy(reg_type, L
"REG_NONE", 8);
130 wcsncpy(reg_type, L
"REG_BINARY", 10);
133 wcsncpy(reg_type, L
"REG_SZ", 6);
136 wcsncpy(reg_type, L
"REG_EXPAND_SZ", 13);
139 wcsncpy(reg_type, L
"REG_MULTI_SZ", 12);
142 wcsncpy(reg_type, L
"REG_DWORD", 9);
145 wcsncpy(reg_type, L
"REG_QWORD", 9);
148 debug_print(L
"Invalid registry data type.\n");
151 int req_size = _snwprintf(
nullptr,
153 L
"reg add \"%ls\" %ls/t %ls%ls/f",
157 escaped_d ? escaped_d : L
" ");
158 if (req_size >= 1 && (
size_t)req_size < CMD_MAX_COMMAND_LENGTH) {
159 size_t total_size = (size_t)req_size + 1;
160 out = calloc(total_size, WL);
164 wmemset(out, L
'\0', total_size);
165 int wrote = _snwprintf(out,
167 L
"reg add \"%ls\" %ls/t %ls%ls/f",
171 escaped_d ? escaped_d : L
" ");
173 ret = write_output(out,
true, writer);
176 errno = EKEYREJECTED;
177 debug_print(L
"%ls %ls: Skipping due to length of command.\n", full_path, prop);
188 free(escaped_reg_key);