2 * Unix SMB/CIFS implementation.
3 * Virtual Windows Registry Layer
4 * Copyright (C) Volker Lendecke 2006
5 * Copyright (C) Michael Adam 2007-2010
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 * Higher level utility functions on top of reg_api.c
28 #include "reg_api_util.h"
29 #include "libcli/registry/util_reg.h"
32 * Utility function to open a complete registry path including the hive prefix.
34 WERROR
reg_open_path(TALLOC_CTX
*mem_ctx
, const char *orig_path
,
35 uint32_t desired_access
, const struct security_token
*token
,
36 struct registry_key
**pkey
)
38 struct registry_key
*hive
, *key
;
42 if (!(path
= SMB_STRDUP(orig_path
))) {
46 p
= strchr(path
, '\\');
48 if ((p
== NULL
) || (p
[1] == '\0')) {
50 * No key behind the hive, just return the hive
53 err
= reg_openhive(mem_ctx
, path
, desired_access
, token
,
55 if (!W_ERROR_IS_OK(err
)) {
66 err
= reg_openhive(mem_ctx
, path
, KEY_ENUMERATE_SUB_KEYS
, token
,
68 if (!W_ERROR_IS_OK(err
)) {
73 err
= reg_openkey(mem_ctx
, hive
, p
+1, desired_access
, &key
);
78 if (!W_ERROR_IS_OK(err
)) {
87 * Utility function to create a registry key without opening the hive
88 * before. Assumes the hive already exists.
91 WERROR
reg_create_path(TALLOC_CTX
*mem_ctx
, const char *orig_path
,
92 uint32_t desired_access
,
93 const struct security_token
*token
,
94 enum winreg_CreateAction
*paction
,
95 struct registry_key
**pkey
)
97 struct registry_key
*hive
;
101 if (!(path
= SMB_STRDUP(orig_path
))) {
105 p
= strchr(path
, '\\');
107 if ((p
== NULL
) || (p
[1] == '\0')) {
109 * No key behind the hive, just return the hive
112 err
= reg_openhive(mem_ctx
, path
, desired_access
, token
,
114 if (!W_ERROR_IS_OK(err
)) {
120 *paction
= REG_OPENED_EXISTING_KEY
;
126 err
= reg_openhive(mem_ctx
, path
,
127 (strchr(p
+1, '\\') != NULL
) ?
128 KEY_ENUMERATE_SUB_KEYS
: KEY_CREATE_SUB_KEY
,
130 if (!W_ERROR_IS_OK(err
)) {
135 err
= reg_createkey(mem_ctx
, hive
, p
+1, desired_access
, pkey
, paction
);
142 * Utility function to recursively delete a registry key without opening the
143 * hive before. Will not delete a hive.
146 WERROR
reg_delete_path(const struct security_token
*token
,
147 const char *orig_path
)
149 struct registry_key
*hive
;
153 if (!(path
= SMB_STRDUP(orig_path
))) {
157 p
= strchr(path
, '\\');
159 if ((p
== NULL
) || (p
[1] == '\0')) {
161 return WERR_INVALID_PARAM
;
166 err
= reg_openhive(NULL
, path
,
167 (strchr(p
+1, '\\') != NULL
) ?
168 KEY_ENUMERATE_SUB_KEYS
: KEY_CREATE_SUB_KEY
,
170 if (!W_ERROR_IS_OK(err
)) {
175 err
= reg_deletekey_recursive(hive
, p
+1);
181 struct registry_value
*registry_value_dw(TALLOC_CTX
*mem_ctx
, uint32_t dw
)
183 struct registry_value
*ret
;
185 ret
= talloc_zero(mem_ctx
, struct registry_value
);
190 ret
->data
= data_blob_talloc(ret
, NULL
, sizeof(uint32_t));
191 if (ret
->data
.data
== NULL
) {
196 ret
->type
= REG_DWORD
;
198 SIVAL(ret
->data
.data
, 0, dw
);
203 struct registry_value
*registry_value_sz(TALLOC_CTX
*mem_ctx
, const char *str
)
205 struct registry_value
*ret
;
207 ret
= talloc_zero(mem_ctx
, struct registry_value
);
212 if (!push_reg_sz(ret
, &ret
->data
, str
)) {
222 struct registry_value
*registry_value_multi_sz(TALLOC_CTX
*mem_ctx
, const char **str
)
224 struct registry_value
*ret
;
226 ret
= talloc_zero(mem_ctx
, struct registry_value
);
231 if (!push_reg_multi_sz(ret
, &ret
->data
, str
)) {
236 ret
->type
= REG_MULTI_SZ
;
241 int registry_value_cmp(const struct registry_value
* v1
, const struct registry_value
* v2
)
243 if (v1
->type
== v2
->type
) {
244 return data_blob_cmp(&v1
->data
, &v2
->data
);
246 return v1
->type
- v2
->type
;