2 * Copyright 2016-2017, 2021 Hugh McMaster
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 static BOOL op_delete_key
= TRUE
;
23 static void output_error(LONG rc
)
25 if (rc
== ERROR_FILE_NOT_FOUND
)
28 output_message(STRING_KEY_NONEXIST
);
30 output_message(STRING_VALUE_NONEXIST
);
34 output_message(STRING_ACCESS_DENIED
);
38 static int run_delete(HKEY root
, WCHAR
*path
, REGSAM sam
, WCHAR
*key_name
, WCHAR
*value_name
,
39 BOOL value_empty
, BOOL value_all
, BOOL force
)
48 if (value_name
|| value_empty
)
49 ret
= ask_confirm(STRING_DELETE_VALUE
, value_name
);
51 ret
= ask_confirm(STRING_DELETE_VALUEALL
, key_name
);
53 ret
= ask_confirm(STRING_DELETE_SUBKEY
, key_name
);
57 output_message(STRING_CANCELLED
);
62 if ((rc
= RegOpenKeyExW(root
, path
, 0, KEY_READ
|KEY_SET_VALUE
|sam
, &hkey
)))
68 /* Delete registry key if no /v* option is given */
69 if (!value_name
&& !value_empty
&& !value_all
)
71 if ((rc
= RegDeleteTreeW(hkey
, NULL
)))
78 RegDeleteKeyW(hkey
, L
"");
81 output_message(STRING_SUCCESS
);
85 op_delete_key
= FALSE
;
89 DWORD max_value_len
= 256, value_len
;
92 value_name
= malloc(max_value_len
* sizeof(WCHAR
));
96 value_len
= max_value_len
;
97 rc
= RegEnumValueW(hkey
, 0, value_name
, &value_len
, NULL
, NULL
, NULL
, NULL
);
98 if (rc
== ERROR_SUCCESS
)
100 rc
= RegDeleteValueW(hkey
, value_name
);
101 if (rc
!= ERROR_SUCCESS
)
105 output_message(STRING_VALUEALL_FAILED
, key_name
);
110 else if (rc
== ERROR_MORE_DATA
)
113 value_name
= realloc(value_name
, max_value_len
* sizeof(WCHAR
));
119 else if (value_name
|| value_empty
)
121 if ((rc
= RegDeleteValueW(hkey
, value_name
)))
130 output_message(STRING_SUCCESS
);
134 int reg_delete(int argc
, WCHAR
*argvW
[])
137 WCHAR
*path
, *key_name
, *value_name
= NULL
;
138 BOOL value_all
= FALSE
, value_empty
= FALSE
, force
= FALSE
;
142 if (!parse_registry_key(argvW
[2], &root
, &path
))
145 for (i
= 3; i
< argc
; i
++)
149 if (argvW
[i
][0] != '/' && argvW
[i
][0] != '-')
154 if (!lstrcmpiW(str
, L
"va"))
156 if (value_all
) goto invalid
;
160 else if (!lstrcmpiW(str
, L
"ve"))
162 if (value_empty
) goto invalid
;
166 else if (!lstrcmpiW(str
, L
"reg:32"))
168 if (sam
& KEY_WOW64_32KEY
) goto invalid
;
169 sam
|= KEY_WOW64_32KEY
;
172 else if (!lstrcmpiW(str
, L
"reg:64"))
174 if (sam
& KEY_WOW64_64KEY
) goto invalid
;
175 sam
|= KEY_WOW64_64KEY
;
178 else if (!str
[0] || str
[1])
181 switch (towlower(*str
))
184 if (value_name
|| !(value_name
= argvW
[++i
]))
188 if (force
) goto invalid
;
196 if ((value_name
&& value_empty
) || (value_name
&& value_all
) || (value_empty
&& value_all
))
199 if (sam
== (KEY_WOW64_32KEY
|KEY_WOW64_64KEY
))
202 key_name
= get_long_key(root
, path
);
204 return run_delete(root
, path
, sam
, key_name
, value_name
, value_empty
, value_all
, force
);
207 output_message(STRING_INVALID_SYNTAX
);
208 output_message(STRING_FUNC_HELP
, wcsupr(argvW
[1]));