mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
r128: Another registry update. Changes:
- Start with the LDB backend - The API is now more windows-like, which should make it easier to use in rpc_server - Added a GTK+ front-end - Added some more IDL More updates will follow, especially in the RPC field.. (This used to be commit 3adffa021779b26047a20f16a3c0b53d74751560)
This commit is contained in:
parent
d907dcf383
commit
aebfb3b9f4
@ -140,6 +140,7 @@ DCERPC_LIBS = @DCERPC_LIBS@
|
||||
|
||||
REG_OBJS = @REG_OBJS@
|
||||
REG_LIBS = @REG_LIBS@
|
||||
GTK_LIBS = @GTK_LIBS@
|
||||
|
||||
TORTURE_RAW_OBJS = @TORTURE_RAW_OBJS@
|
||||
|
||||
@ -191,6 +192,7 @@ NDRDUMP_OBJS = utils/ndrdump.o utils/rewrite.o \
|
||||
NDRDUMP_LIBS = $(LIBSMB_LIBS) $(CONFIG_LIBS) $(LIBBASIC_LIBS)
|
||||
|
||||
REGTREE_OBJ = $(REG_OBJS) lib/registry/tools/regtree.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
|
||||
GREGEDIT_OBJ = $(REG_OBJS) lib/registry/tools/gregedit.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
|
||||
REGSHELL_OBJ = $(REG_OBJS) lib/registry/tools/regshell.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBCMDLINE_OBJS) $(LIBSMB_OBJS)
|
||||
REGPATCH_OBJ = $(REG_OBJS) lib/registry/tools/regpatch.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
|
||||
REGDIFF_OBJ = $(REG_OBJS) lib/registry/tools/regdiff.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
|
||||
@ -350,6 +352,10 @@ bin/regtree@EXEEXT@: $(REGTREE_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(REGTREE_OBJ) $(LDFLAGS) $(LIBS) $(REG_LIBS)
|
||||
|
||||
bin/gregedit@EXEEXT@: $(GREGEDIT_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLGS) -o $@ $(GREGEDIT_OBJ) $(LDFLAGS) $(LIBS) $(REG_LIBS) $(GTK_LIBS)
|
||||
|
||||
bin/regpatch@EXEEXT@: $(REGPATCH_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(REGPATCH_OBJ) $(LDFLAGS) $(LIBS) $(REG_LIBS)
|
||||
|
@ -231,4 +231,7 @@
|
||||
#define WERR_DFS_INTERNAL_ERROR W_ERROR(NERR_BASE+590)
|
||||
#define WERR_DFS_CANT_CREATE_JUNCT W_ERROR(NERR_BASE+569)
|
||||
|
||||
|
||||
#define WERR_FOOBAR WERR_GENERAL_FAILURE
|
||||
|
||||
#endif /* _DOSERR_H */
|
||||
|
@ -1,126 +0,0 @@
|
||||
#ifndef _PROTO_H_
|
||||
#define _PROTO_H_
|
||||
|
||||
/* This file is automatically generated with "make proto". DO NOT EDIT */
|
||||
|
||||
|
||||
/* The following definitions come from common/ldb.c */
|
||||
|
||||
struct ldb_context *ldb_connect(const char *url, unsigned int flags,
|
||||
const char *options[]);
|
||||
int ldb_close(struct ldb_context *ldb);
|
||||
int ldb_search(struct ldb_context *ldb,
|
||||
const char *base,
|
||||
enum ldb_scope scope,
|
||||
const char *expression,
|
||||
const char *attrs[], struct ldb_message ***res);
|
||||
int ldb_search_free(struct ldb_context *ldb, struct ldb_message **msgs);
|
||||
int ldb_add(struct ldb_context *ldb,
|
||||
const struct ldb_message *message);
|
||||
int ldb_modify(struct ldb_context *ldb,
|
||||
const struct ldb_message *message);
|
||||
int ldb_delete(struct ldb_context *ldb, const char *dn);
|
||||
const char *ldb_errstring(struct ldb_context *ldb);
|
||||
|
||||
/* The following definitions come from common/ldb_ldif.c */
|
||||
|
||||
char *ldb_base64_encode(const char *buf, int len);
|
||||
int ldb_should_b64_encode(const struct ldb_val *val);
|
||||
int ldif_write(int (*fprintf_fn)(void *, const char *, ...),
|
||||
void *private,
|
||||
const struct ldb_message *msg);
|
||||
void ldif_read_free(struct ldb_message *msg);
|
||||
struct ldb_message *ldif_read(int (*fgetc_fn)(void *), void *private);
|
||||
struct ldb_message *ldif_read_file(FILE *f);
|
||||
struct ldb_message *ldif_read_string(const char *s);
|
||||
int ldif_write_file(FILE *f, const struct ldb_message *msg);
|
||||
|
||||
/* The following definitions come from common/ldb_parse.c */
|
||||
|
||||
struct ldb_parse_tree *ldb_parse_tree(const char *s);
|
||||
void ldb_parse_tree_free(struct ldb_parse_tree *tree);
|
||||
|
||||
/* The following definitions come from common/util.c */
|
||||
|
||||
void *realloc_array(void *ptr, size_t el_size, unsigned count);
|
||||
int list_find(const void *needle,
|
||||
const void *base, size_t nmemb, size_t size, comparison_fn_t comp_fn);
|
||||
|
||||
/* The following definitions come from ldb_ldap/ldb_ldap.c */
|
||||
|
||||
struct ldb_context *lldb_connect(const char *url,
|
||||
unsigned int flags,
|
||||
const char *options[]);
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldb_index.c */
|
||||
|
||||
int ltdb_search_indexed(struct ldb_context *ldb,
|
||||
const char *base,
|
||||
enum ldb_scope scope,
|
||||
struct ldb_parse_tree *tree,
|
||||
const char *attrs[], struct ldb_message ***res);
|
||||
int ltdb_index_add(struct ldb_context *ldb, const struct ldb_message *msg);
|
||||
int ltdb_index_del(struct ldb_context *ldb, const struct ldb_message *msg);
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldb_match.c */
|
||||
|
||||
int ldb_message_match(struct ldb_context *ldb,
|
||||
struct ldb_message *msg,
|
||||
struct ldb_parse_tree *tree,
|
||||
const char *base,
|
||||
enum ldb_scope scope);
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldb_pack.c */
|
||||
|
||||
int ltdb_pack_data(struct ldb_context *ctx,
|
||||
const struct ldb_message *message,
|
||||
struct TDB_DATA *data);
|
||||
int ltdb_unpack_data(struct ldb_context *ctx,
|
||||
const struct TDB_DATA *data,
|
||||
struct ldb_message *message);
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldb_search.c */
|
||||
|
||||
int ldb_msg_find_attr(const struct ldb_message *msg, const char *attr);
|
||||
int ltdb_has_wildcard(const struct ldb_val *val);
|
||||
void ltdb_search_dn1_free(struct ldb_context *ldb, struct ldb_message *msg);
|
||||
int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message *msg);
|
||||
int ltdb_search_dn(struct ldb_context *ldb, char *dn,
|
||||
const char *attrs[], struct ldb_message ***res);
|
||||
int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg,
|
||||
const char *attrs[],
|
||||
unsigned int *count,
|
||||
struct ldb_message ***res);
|
||||
int ltdb_search_free(struct ldb_context *ldb, struct ldb_message **msgs);
|
||||
int ltdb_search(struct ldb_context *ldb, const char *base,
|
||||
enum ldb_scope scope, const char *expression,
|
||||
const char *attrs[], struct ldb_message ***res);
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldb_tdb.c */
|
||||
|
||||
struct TDB_DATA ltdb_key(const char *dn);
|
||||
int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs);
|
||||
int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn);
|
||||
struct ldb_context *ltdb_connect(const char *url,
|
||||
unsigned int flags,
|
||||
const char *options[]);
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldbadd.c */
|
||||
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldbdel.c */
|
||||
|
||||
|
||||
/* The following definitions come from ldb_tdb/ldbsearch.c */
|
||||
|
||||
|
||||
/* The following definitions come from tools/ldbadd.c */
|
||||
|
||||
|
||||
/* The following definitions come from tools/ldbdel.c */
|
||||
|
||||
|
||||
/* The following definitions come from tools/ldbsearch.c */
|
||||
|
||||
|
||||
#endif /* _PROTO_H_ */
|
@ -1,10 +1,6 @@
|
||||
- support subtrees
|
||||
- ../../, /bla/blie support in regshell
|
||||
- use memory pools?
|
||||
- get rid of all the nasty memory leaks..
|
||||
- security stuff
|
||||
- clean up code
|
||||
- rpc_server
|
||||
- ..\..\, \bla\blie support in regshell
|
||||
- finish rpc_server
|
||||
|
||||
reg_backend_dir:
|
||||
- value support
|
||||
@ -15,9 +11,15 @@ reg_backend_nt4:
|
||||
reg_backend_rpc:
|
||||
- value enum support
|
||||
- write support
|
||||
- rewrite
|
||||
|
||||
reg_backend_ldb:
|
||||
- implement
|
||||
- finish
|
||||
|
||||
reg_backend_wine.c:
|
||||
- implement
|
||||
- finish
|
||||
|
||||
gregedit.c:
|
||||
- support for editing values / adding values / deleting values
|
||||
- support for adding/deleting keys
|
||||
- support for security descriptors
|
||||
|
@ -32,7 +32,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name);
|
||||
/* Register new backend */
|
||||
NTSTATUS registry_register(void *_function)
|
||||
{
|
||||
REG_OPS *functions = _function;
|
||||
struct registry_ops *functions = _function;
|
||||
struct reg_init_function_entry *entry = backends;
|
||||
|
||||
if (!functions || !functions->name) {
|
||||
@ -69,17 +69,19 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name)
|
||||
}
|
||||
|
||||
/* Open a registry file/host/etc */
|
||||
REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_load)
|
||||
WERROR reg_open(const char *backend, const char *location, const char *credentials, REG_HANDLE **h)
|
||||
{
|
||||
struct reg_init_function_entry *entry;
|
||||
static BOOL reg_first_init = True;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
REG_HANDLE *ret;
|
||||
NTSTATUS status;
|
||||
WERROR werr;
|
||||
|
||||
if(reg_first_init) {
|
||||
if (!NT_STATUS_IS_OK(register_subsystem("registry", registry_register))) {
|
||||
return False;
|
||||
}
|
||||
status = register_subsystem("registry", registry_register);
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
return WERR_GENERAL_FAILURE;
|
||||
|
||||
static_init_reg;
|
||||
reg_first_init = False;
|
||||
@ -89,7 +91,7 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
|
||||
|
||||
if (!entry) {
|
||||
DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
|
||||
return NULL;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_init(backend);
|
||||
@ -99,31 +101,35 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
|
||||
ret->functions = entry->functions;
|
||||
ret->backend_data = NULL;
|
||||
ret->mem_ctx = mem_ctx;
|
||||
*h = ret;
|
||||
|
||||
if(!entry->functions->open_registry) {
|
||||
return ret;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
if(entry->functions->open_registry(ret, location, try_full_load))
|
||||
return ret;
|
||||
werr = entry->functions->open_registry(ret, location, credentials);
|
||||
|
||||
if(W_ERROR_IS_OK(werr))
|
||||
return WERR_OK;
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
return NULL;
|
||||
return werr;
|
||||
}
|
||||
|
||||
/* Open a key
|
||||
* First tries to use the open_key function from the backend
|
||||
* then falls back to get_subkey_by_name and later get_subkey_by_index
|
||||
*/
|
||||
REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
|
||||
WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result)
|
||||
{
|
||||
char *fullname;
|
||||
WERROR status;
|
||||
REG_KEY *ret = NULL;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
if(!parent) {
|
||||
DEBUG(0, ("Invalid parent key specified"));
|
||||
return NULL;
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if(!parent->handle->functions->open_key &&
|
||||
@ -136,10 +142,10 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
|
||||
|
||||
while(curbegin && *curbegin) {
|
||||
if(curend)*curend = '\0';
|
||||
curkey = reg_key_get_subkey_by_name(curkey, curbegin);
|
||||
if(!curkey) {
|
||||
status = reg_key_get_subkey_by_name(curkey, curbegin, result);
|
||||
if(!NT_STATUS_IS_OK(status)) {
|
||||
SAFE_FREE(orig);
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
if(!curend) break;
|
||||
curbegin = curend + 1;
|
||||
@ -147,255 +153,287 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
|
||||
}
|
||||
SAFE_FREE(orig);
|
||||
|
||||
return curkey;
|
||||
*result = curkey;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_init("mem_ctx");
|
||||
|
||||
fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name);
|
||||
|
||||
\
|
||||
|
||||
if(!parent->handle->functions->open_key) {
|
||||
DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n"));
|
||||
return NULL;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = parent->handle->functions->open_key(parent->handle, fullname);
|
||||
status = parent->handle->functions->open_key(parent->handle, fullname, result);
|
||||
|
||||
if(ret) {
|
||||
ret->handle = parent->handle;
|
||||
ret->path = fullname;
|
||||
talloc_steal(mem_ctx, ret->mem_ctx, fullname);
|
||||
if(!NT_STATUS_IS_OK(status)) {
|
||||
talloc_destroy(mem_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
ret->handle = parent->handle;
|
||||
ret->path = fullname;
|
||||
talloc_steal(mem_ctx, ret->mem_ctx, fullname);
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
return ret;
|
||||
*result = ret;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
REG_VAL *reg_key_get_value_by_index(REG_KEY *key, int idx)
|
||||
WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val)
|
||||
{
|
||||
REG_VAL *ret;
|
||||
|
||||
if(!key) return NULL;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(!key->handle->functions->get_value_by_index) {
|
||||
if(!key->cache_values)
|
||||
key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values);
|
||||
|
||||
if(idx < key->cache_values_count && idx >= 0) {
|
||||
ret = reg_val_dup(key->cache_values[idx]);
|
||||
*val = reg_val_dup(key->cache_values[idx]);
|
||||
} else {
|
||||
return NULL;
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
} else {
|
||||
ret = key->handle->functions->get_value_by_index(key, idx);
|
||||
WERROR status = key->handle->functions->get_value_by_index(key, idx, val);
|
||||
if(!W_ERROR_IS_OK(status))
|
||||
return status;
|
||||
}
|
||||
|
||||
if(ret) {
|
||||
ret->parent = key;
|
||||
ret->handle = key->handle;
|
||||
}
|
||||
|
||||
return ret;
|
||||
(*val)->parent = key;
|
||||
(*val)->handle = key->handle;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
int reg_key_num_subkeys(REG_KEY *key)
|
||||
WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
|
||||
{
|
||||
if(!key) return 0;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(!key->handle->functions->num_subkeys) {
|
||||
if(!key->cache_subkeys)
|
||||
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
|
||||
|
||||
return key->cache_subkeys_count;
|
||||
*count = key->cache_subkeys_count;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
return key->handle->functions->num_subkeys(key);
|
||||
return key->handle->functions->num_subkeys(key, count);
|
||||
}
|
||||
|
||||
int reg_key_num_values(REG_KEY *key)
|
||||
WERROR reg_key_num_values(REG_KEY *key, int *count)
|
||||
{
|
||||
|
||||
if(!key) return 0;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(!key->handle->functions->num_values) {
|
||||
if(!key->handle->functions->fetch_values) {
|
||||
DEBUG(1, ("Backend '%s' doesn't support enumerating values\n", key->handle->functions->name));
|
||||
return 0;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if(!key->cache_values)
|
||||
key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values);
|
||||
|
||||
return key->cache_values_count;
|
||||
*count = key->cache_values_count;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
|
||||
return key->handle->functions->num_values(key);
|
||||
return key->handle->functions->num_values(key, count);
|
||||
}
|
||||
|
||||
REG_KEY *reg_key_get_subkey_by_index(REG_KEY *key, int idx)
|
||||
WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey)
|
||||
{
|
||||
REG_KEY *ret = NULL;
|
||||
|
||||
if(!key) return NULL;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(!key->handle->functions->get_subkey_by_index) {
|
||||
if(!key->cache_subkeys)
|
||||
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
|
||||
|
||||
if(idx < key->cache_subkeys_count) {
|
||||
ret = reg_key_dup(key->cache_subkeys[idx]);
|
||||
*subkey = reg_key_dup(key->cache_subkeys[idx]);
|
||||
} else {
|
||||
/* No such key ! */
|
||||
return NULL;
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
} else {
|
||||
ret = key->handle->functions->get_subkey_by_index(key, idx);
|
||||
WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey);
|
||||
if(!NT_STATUS_IS_OK(status)) return status;
|
||||
}
|
||||
|
||||
if(ret && !ret->path) {
|
||||
ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
|
||||
ret->handle = key->handle;
|
||||
}
|
||||
(*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name);
|
||||
(*subkey)->handle = key->handle;
|
||||
|
||||
return ret;
|
||||
|
||||
return WERR_OK;;
|
||||
}
|
||||
|
||||
REG_KEY *reg_key_get_subkey_by_name(REG_KEY *key, const char *name)
|
||||
WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subkey)
|
||||
{
|
||||
int i, max;
|
||||
int i;
|
||||
REG_KEY *ret = NULL;
|
||||
WERROR error = WERR_OK;
|
||||
|
||||
if(!key) return NULL;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(key->handle->functions->get_subkey_by_name) {
|
||||
ret = key->handle->functions->get_subkey_by_name(key,name);
|
||||
error = key->handle->functions->get_subkey_by_name(key,name,subkey);
|
||||
} else {
|
||||
max = reg_key_num_subkeys(key);
|
||||
for(i = 0; i < max; i++) {
|
||||
REG_KEY *v = reg_key_get_subkey_by_index(key, i);
|
||||
if(v && !strcmp(v->name, name)) {
|
||||
ret = v;
|
||||
for(i = 0; W_ERROR_IS_OK(error); i++) {
|
||||
error = reg_key_get_subkey_by_index(key, i, subkey);
|
||||
if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) {
|
||||
break;
|
||||
}
|
||||
reg_key_free(v);
|
||||
reg_key_free(*subkey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(ret && !ret->path) {
|
||||
ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
|
||||
ret->handle = key->handle;
|
||||
}
|
||||
if(!W_ERROR_IS_OK(error) && W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
|
||||
return error;
|
||||
|
||||
ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
|
||||
ret->handle = key->handle;
|
||||
|
||||
*subkey = ret;
|
||||
|
||||
return ret;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
REG_VAL *reg_key_get_value_by_name(REG_KEY *key, const char *name)
|
||||
WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
|
||||
{
|
||||
int i, max;
|
||||
REG_VAL *ret = NULL;
|
||||
WERROR error = WERR_OK;
|
||||
|
||||
if(!key) return NULL;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(key->handle->functions->get_value_by_name) {
|
||||
ret = key->handle->functions->get_value_by_name(key,name);
|
||||
error = key->handle->functions->get_value_by_name(key,name, val);
|
||||
} else {
|
||||
max = reg_key_num_values(key);
|
||||
for(i = 0; i < max; i++) {
|
||||
REG_VAL *v = reg_key_get_value_by_index(key, i);
|
||||
if(v && StrCaseCmp(v->name, name)) {
|
||||
ret = v;
|
||||
for(i = 0; W_ERROR_IS_OK(error); i++) {
|
||||
error = reg_key_get_value_by_index(key, i, val);
|
||||
if(W_ERROR_IS_OK(error) && StrCaseCmp((*val)->name, name)) {
|
||||
break;
|
||||
}
|
||||
reg_val_free(v);
|
||||
}
|
||||
}
|
||||
|
||||
if(ret) {
|
||||
ret->parent = key;
|
||||
ret->handle = key->handle;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL reg_key_del(REG_KEY *key)
|
||||
{
|
||||
if(key->handle->functions->del_key) {
|
||||
if(key->handle->functions->del_key(key)) {
|
||||
/* Invalidate cache */
|
||||
key->cache_subkeys = NULL;
|
||||
key->cache_subkeys_count = 0;
|
||||
return True;
|
||||
reg_val_free(*val);
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
|
||||
return error;
|
||||
|
||||
(*val)->parent = key;
|
||||
(*val)->handle = key->handle;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
BOOL reg_sync(REG_HANDLE *h, const char *location)
|
||||
WERROR reg_key_del(REG_KEY *key)
|
||||
{
|
||||
if(!h->functions->sync)
|
||||
return True;
|
||||
WERROR error;
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
|
||||
if(!key->handle->functions->del_key)
|
||||
return WERR_NOT_SUPPORTED;
|
||||
|
||||
error = key->handle->functions->del_key(key);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
return h->functions->sync(h, location);
|
||||
/* Invalidate cache */
|
||||
key->cache_subkeys = NULL;
|
||||
key->cache_subkeys_count = 0;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
BOOL reg_key_del_recursive(REG_KEY *key)
|
||||
WERROR reg_sync(REG_KEY *h, const char *location)
|
||||
{
|
||||
if(!h->handle->functions->sync_key)
|
||||
return WERR_OK;
|
||||
|
||||
return h->handle->functions->sync_key(h, location);
|
||||
}
|
||||
|
||||
WERROR reg_key_del_recursive(REG_KEY *key)
|
||||
{
|
||||
BOOL succeed = True;
|
||||
WERROR error = WERR_OK;
|
||||
int i;
|
||||
|
||||
/* Delete all values for specified key */
|
||||
for(i = 0; i < reg_key_num_values(key); i++) {
|
||||
if(!reg_val_del(reg_key_get_value_by_index(key, i)))
|
||||
succeed = False;
|
||||
for(i = 0; W_ERROR_IS_OK(error); i++) {
|
||||
REG_VAL *val;
|
||||
error = reg_key_get_value_by_index(key, i, &val);
|
||||
if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
|
||||
return error;
|
||||
|
||||
if(W_ERROR_IS_OK(error)) {
|
||||
error = reg_val_del(val);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
}
|
||||
}
|
||||
|
||||
error = WERR_OK;
|
||||
|
||||
/* Delete all keys below this one */
|
||||
for(i = 0; i < reg_key_num_subkeys(key); i++) {
|
||||
if(!reg_key_del_recursive(reg_key_get_subkey_by_index(key, i)))
|
||||
succeed = False;
|
||||
for(i = 0; W_ERROR_IS_OK(error); i++) {
|
||||
REG_KEY *subkey;
|
||||
|
||||
error = reg_key_get_subkey_by_index(key, i, &subkey);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
error = reg_key_del_recursive(subkey);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
}
|
||||
|
||||
if(succeed)reg_key_del(key);
|
||||
|
||||
return succeed;
|
||||
return reg_key_del(key);
|
||||
}
|
||||
|
||||
BOOL reg_val_del(REG_VAL *val)
|
||||
WERROR reg_val_del(REG_VAL *val)
|
||||
{
|
||||
WERROR error;
|
||||
if (!val) return WERR_INVALID_PARAM;
|
||||
|
||||
if (!val->handle->functions->del_value) {
|
||||
DEBUG(1, ("Backend '%s' doesn't support method del_value\n", val->handle->functions->name));
|
||||
return False;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if(val->handle->functions->del_value(val)) {
|
||||
val->parent->cache_values = NULL;
|
||||
val->parent->cache_values_count = 0;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
error = val->handle->functions->del_value(val);
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
val->parent->cache_values = NULL;
|
||||
val->parent->cache_values_count = 0;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path)
|
||||
WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path)
|
||||
{
|
||||
REG_KEY *cur, *prevcur = parent;
|
||||
WERROR error;
|
||||
char *begin = (char *)path, *end;
|
||||
|
||||
while(1) {
|
||||
end = strchr(begin, '\\');
|
||||
if(end) *end = '\0';
|
||||
cur = reg_key_get_subkey_by_name(prevcur, begin);
|
||||
if(!cur) {
|
||||
if(!reg_key_add_name(prevcur, begin)) { printf("foo\n"); return False; }
|
||||
cur = reg_key_get_subkey_by_name(prevcur, begin);
|
||||
if(!cur) {
|
||||
DEBUG(0, ("Can't find key after adding it : %s\n", begin));
|
||||
return False;
|
||||
}
|
||||
|
||||
error = reg_key_get_subkey_by_name(prevcur, begin, &cur);
|
||||
|
||||
/* Key is not there, add it */
|
||||
if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) {
|
||||
error = reg_key_add_name(prevcur, begin, 0, NULL, &cur);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
if(end) *end = '\\';
|
||||
return error;
|
||||
}
|
||||
|
||||
if(!end) break;
|
||||
@ -403,28 +441,36 @@ BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path)
|
||||
begin = end+1;
|
||||
prevcur = cur;
|
||||
}
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
BOOL reg_key_add_name(REG_KEY *parent, const char *name)
|
||||
WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **newkey)
|
||||
{
|
||||
if (!parent) return False;
|
||||
WERROR error;
|
||||
|
||||
if (!parent) return WERR_INVALID_PARAM;
|
||||
|
||||
if (!parent->handle->functions->add_key) {
|
||||
DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->handle->functions->name));
|
||||
return False;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if(parent->handle->functions->add_key(parent, name)) {
|
||||
parent->cache_subkeys = NULL;
|
||||
parent->cache_subkeys_count = 0;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
error = parent->handle->functions->add_key(parent, name, access_mask, desc, newkey);
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
(*newkey)->handle = parent->handle;
|
||||
(*newkey)->backend_data = talloc_asprintf((*newkey)->mem_ctx, "%s\\%s", reg_key_get_path(parent), name);
|
||||
|
||||
parent->cache_subkeys = NULL;
|
||||
parent->cache_subkeys_count = 0;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
BOOL reg_val_update(REG_VAL *val, int type, void *data, int len)
|
||||
WERROR reg_val_update(REG_VAL *val, int type, void *data, int len)
|
||||
{
|
||||
WERROR error;
|
||||
|
||||
/* A 'real' update function has preference */
|
||||
if (val->handle->functions->update_value)
|
||||
return val->handle->functions->update_value(val, type, data, len);
|
||||
@ -433,18 +479,19 @@ BOOL reg_val_update(REG_VAL *val, int type, void *data, int len)
|
||||
if (val->handle->functions->add_value &&
|
||||
val->handle->functions->del_value) {
|
||||
REG_VAL *new;
|
||||
if(!val->handle->functions->del_value(val))
|
||||
return False;
|
||||
if(!W_ERROR_IS_OK(error = val->handle->functions->del_value(val)))
|
||||
return error;
|
||||
|
||||
new = val->handle->functions->add_value(val->parent, val->name, type, data, len);
|
||||
error = val->handle->functions->add_value(val->parent, val->name, type, data, len);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
memcpy(val, new, sizeof(REG_VAL));
|
||||
val->parent->cache_values = NULL;
|
||||
val->parent->cache_values_count = 0;
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
DEBUG(1, ("Backend '%s' doesn't support method update_value\n", val->handle->functions->name));
|
||||
return False;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void reg_free(REG_HANDLE *h)
|
||||
@ -454,37 +501,44 @@ void reg_free(REG_HANDLE *h)
|
||||
h->functions->close_registry(h);
|
||||
}
|
||||
|
||||
REG_KEY *reg_get_root(REG_HANDLE *h)
|
||||
WERROR reg_get_root(REG_HANDLE *h, REG_KEY **key)
|
||||
{
|
||||
REG_KEY *ret = NULL;
|
||||
WERROR ret;
|
||||
if(h->functions->open_root_key) {
|
||||
ret = h->functions->open_root_key(h);
|
||||
ret = h->functions->open_root_key(h, key);
|
||||
} else if(h->functions->open_key) {
|
||||
ret = h->functions->open_key(h, "\\");
|
||||
ret = h->functions->open_key(h, "\\", key);
|
||||
} else {
|
||||
DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key method implemented\n", h->functions->name));
|
||||
ret = WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if(ret) {
|
||||
ret->handle = h;
|
||||
ret->path = talloc_strdup(ret->mem_ctx, "\\");
|
||||
if(W_ERROR_IS_OK(ret)) {
|
||||
(*key)->handle = h;
|
||||
(*key)->path = talloc_strdup((*key)->mem_ctx, "\\");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
REG_VAL *reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen)
|
||||
WERROR reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen)
|
||||
{
|
||||
REG_VAL *ret;
|
||||
WERROR ret = WERR_OK;
|
||||
if(!key->handle->functions->add_value)
|
||||
return NULL;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
|
||||
ret = key->handle->functions->add_value(key, name, type, value, vallen);
|
||||
ret->parent = key;
|
||||
ret->handle = key->handle;
|
||||
|
||||
if(!W_ERROR_IS_OK(ret)) return ret;
|
||||
|
||||
/* Invalidate the cache */
|
||||
key->cache_values = NULL;
|
||||
key->cache_values_count = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
WERROR reg_save(REG_HANDLE *h, const char *location)
|
||||
{
|
||||
/* FIXME */
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -96,22 +96,26 @@ BOOL reg_val_set_string(REG_VAL *val, char *str)
|
||||
return False;
|
||||
}
|
||||
|
||||
REG_VAL *reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname)
|
||||
WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname, REG_VAL **val)
|
||||
{
|
||||
REG_KEY *k = reg_key_get_subkey_by_name(key, subname);
|
||||
if(!k) return NULL;
|
||||
REG_KEY *k;
|
||||
WERROR error = reg_key_get_subkey_by_name(key, subname, &k);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
return reg_key_get_value_by_name(k, valname);
|
||||
return reg_key_get_value_by_name(k, valname, val);
|
||||
}
|
||||
|
||||
BOOL reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len)
|
||||
WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len)
|
||||
{
|
||||
REG_KEY *k = reg_key_get_subkey_by_name(key, subname);
|
||||
REG_KEY *k;
|
||||
REG_VAL *v;
|
||||
if(!k) return False;
|
||||
WERROR error;
|
||||
|
||||
v = reg_key_get_value_by_name(k, valname);
|
||||
if(!v) return False;
|
||||
error = reg_key_get_subkey_by_name(key, subname, &k);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
error = reg_key_get_value_by_name(k, valname, &v);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
return reg_val_update(v, type, data, real_len);
|
||||
}
|
||||
|
@ -57,42 +57,55 @@ struct reg_val_s {
|
||||
int ref;
|
||||
};
|
||||
|
||||
/* FIXME */
|
||||
typedef void (*key_notification_function) ();
|
||||
typedef void (*value_notification_function) ();
|
||||
|
||||
|
||||
/*
|
||||
* Container for function pointers to enumeration routines
|
||||
* for virtual registry view
|
||||
*/
|
||||
|
||||
struct reg_ops_s {
|
||||
struct registry_ops {
|
||||
const char *name;
|
||||
BOOL (*open_registry) (REG_HANDLE *, const char *location, BOOL try_complete_load);
|
||||
BOOL (*sync)(REG_HANDLE *, const char *location);
|
||||
BOOL (*close_registry) (REG_HANDLE *);
|
||||
WERROR (*open_registry) (REG_HANDLE *, const char *location, const char *credentials);
|
||||
WERROR (*sync_key)(REG_KEY *, const char *location);
|
||||
WERROR (*close_registry) (REG_HANDLE *);
|
||||
|
||||
/* Either implement these */
|
||||
REG_KEY *(*open_root_key) (REG_HANDLE *);
|
||||
int (*num_subkeys) (REG_KEY *);
|
||||
int (*num_values) (REG_KEY *);
|
||||
REG_KEY *(*get_subkey_by_index) (REG_KEY *, int idx);
|
||||
REG_KEY *(*get_subkey_by_name) (REG_KEY *, const char *name);
|
||||
REG_VAL *(*get_value_by_index) (REG_KEY *, int idx);
|
||||
REG_VAL *(*get_value_by_name) (REG_KEY *, const char *name);
|
||||
WERROR (*open_root_key) (REG_HANDLE *, REG_KEY **);
|
||||
WERROR (*num_subkeys) (REG_KEY *, int *count);
|
||||
WERROR (*num_values) (REG_KEY *, int *count);
|
||||
WERROR (*get_subkey_by_index) (REG_KEY *, int idx, REG_KEY **);
|
||||
WERROR (*get_subkey_by_name) (REG_KEY *, const char *name, REG_KEY **);
|
||||
WERROR (*get_value_by_index) (REG_KEY *, int idx, REG_VAL **);
|
||||
WERROR (*get_value_by_name) (REG_KEY *, const char *name, REG_VAL **);
|
||||
|
||||
/* Or these */
|
||||
REG_KEY *(*open_key) (REG_HANDLE *, const char *name);
|
||||
BOOL (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***);
|
||||
BOOL (*fetch_values) (REG_KEY *, int *count, REG_VAL ***);
|
||||
WERROR (*open_key) (REG_HANDLE *, const char *name, REG_KEY **);
|
||||
WERROR (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***);
|
||||
WERROR (*fetch_values) (REG_KEY *, int *count, REG_VAL ***);
|
||||
|
||||
/* Security control */
|
||||
WERROR (*key_get_sec_desc) (REG_KEY *, SEC_DESC **);
|
||||
WERROR (*key_set_sec_desc) (REG_KEY *, SEC_DESC *);
|
||||
|
||||
/* Notification */
|
||||
WERROR (*request_key_change_notify) (REG_KEY *, key_notification_function);
|
||||
WERROR (*request_value_change_notify) (REG_VAL *, value_notification_function);
|
||||
|
||||
/* Key management */
|
||||
BOOL (*add_key)(REG_KEY *, const char *name);
|
||||
BOOL (*del_key)(REG_KEY *);
|
||||
WERROR (*add_key)(REG_KEY *, const char *name, uint32 access_mask, SEC_DESC *, REG_KEY **);
|
||||
WERROR (*del_key)(REG_KEY *);
|
||||
|
||||
/* Value management */
|
||||
REG_VAL *(*add_value)(REG_KEY *, const char *name, int type, void *data, int len);
|
||||
BOOL (*del_value)(REG_VAL *);
|
||||
WERROR (*add_value)(REG_KEY *, const char *name, int type, void *data, int len);
|
||||
WERROR (*del_value)(REG_VAL *);
|
||||
|
||||
/* If update is not available, value will first be deleted and then added
|
||||
* again */
|
||||
BOOL (*update_value)(REG_VAL *, int type, void *data, int len);
|
||||
WERROR (*update_value)(REG_VAL *, int type, void *data, int len);
|
||||
|
||||
void (*free_key_backend_data) (REG_KEY *);
|
||||
void (*free_val_backend_data) (REG_VAL *);
|
||||
@ -105,7 +118,7 @@ typedef struct reg_sub_tree_s {
|
||||
} REG_SUBTREE;
|
||||
|
||||
struct reg_handle_s {
|
||||
REG_OPS *functions;
|
||||
struct registry_ops *functions;
|
||||
REG_SUBTREE *subtrees;
|
||||
char *location;
|
||||
void *backend_data;
|
||||
@ -114,7 +127,7 @@ struct reg_handle_s {
|
||||
|
||||
struct reg_init_function_entry {
|
||||
/* Function to create a member of the pdb_methods list */
|
||||
REG_OPS *functions;
|
||||
struct registry_ops *functions;
|
||||
struct reg_init_function_entry *prev, *next;
|
||||
};
|
||||
|
||||
|
@ -8,9 +8,12 @@ LIBWINREG=libwinregistry
|
||||
PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC)
|
||||
CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building reg_gconf])])
|
||||
|
||||
PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])])
|
||||
|
||||
SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o)
|
||||
SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o)
|
||||
SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o)
|
||||
SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS])
|
||||
SMB_MODULE(reg_ldb, REG, STATIC, lib/registry/reg_backend_ldb/reg_backend_ldb.o)
|
||||
SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[])
|
||||
AC_CONFIG_FILES(lib/registry/winregistry.pc)
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "includes.h"
|
||||
#include "lib/registry/common/registry.h"
|
||||
|
||||
static BOOL reg_dir_add_key(REG_KEY *parent, const char *name)
|
||||
static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc)
|
||||
{
|
||||
char *path;
|
||||
int ret;
|
||||
@ -29,15 +29,16 @@ static BOOL reg_dir_add_key(REG_KEY *parent, const char *name)
|
||||
path = reg_path_win2unix(path);
|
||||
ret = mkdir(path, 0700);
|
||||
SAFE_FREE(path);
|
||||
return (ret == 0);
|
||||
if(ret == 0)return WERR_OK;
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
static BOOL reg_dir_del_key(REG_KEY *k)
|
||||
static WERROR reg_dir_del_key(REG_KEY *k)
|
||||
{
|
||||
return (rmdir((char *)k->backend_data) == 0);
|
||||
return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
|
||||
static WERROR reg_dir_open_key(REG_HANDLE *h, const char *name, REG_KEY **subkey)
|
||||
{
|
||||
DIR *d;
|
||||
char *fullpath;
|
||||
@ -45,7 +46,7 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
|
||||
TALLOC_CTX *mem_ctx = talloc_init("tmp");
|
||||
if(!name) {
|
||||
DEBUG(0, ("NULL pointer passed as directory name!"));
|
||||
return NULL;
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name);
|
||||
fullpath = reg_path_win2unix(fullpath);
|
||||
@ -54,16 +55,17 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
|
||||
if(!d) {
|
||||
DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno)));
|
||||
talloc_destroy(mem_ctx);
|
||||
return NULL;
|
||||
return WERR_BADFILE;
|
||||
}
|
||||
closedir(d);
|
||||
ret = reg_key_new_abs(name, h, fullpath);
|
||||
talloc_steal(mem_ctx, ret->mem_ctx, fullpath);
|
||||
talloc_destroy(mem_ctx);
|
||||
return ret;
|
||||
*subkey = ret;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
|
||||
static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
|
||||
{
|
||||
struct dirent *e;
|
||||
int max = 200;
|
||||
@ -75,7 +77,7 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
|
||||
|
||||
d = opendir(fullpath);
|
||||
|
||||
if(!d) return False;
|
||||
if(!d) return WERR_INVALID_PARAM;
|
||||
|
||||
while((e = readdir(d))) {
|
||||
if(e->d_type == DT_DIR &&
|
||||
@ -96,35 +98,35 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
|
||||
closedir(d);
|
||||
|
||||
*r = ar;
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) {
|
||||
if(!loc) return False;
|
||||
return True;
|
||||
static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentials) {
|
||||
if(!loc) return WERR_INVALID_PARAM;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
|
||||
static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value)
|
||||
{
|
||||
REG_VAL *ret = reg_val_new(p, NULL);
|
||||
char *fullpath;
|
||||
FILE *fd;
|
||||
ret->name = name?talloc_strdup(ret->mem_ctx, name):NULL;
|
||||
fullpath = reg_path_win2unix(strdup(reg_val_get_path(ret)));
|
||||
*value = reg_val_new(p, NULL);
|
||||
(*value)->name = name?talloc_strdup((*value)->mem_ctx, name):NULL;
|
||||
fullpath = reg_path_win2unix(strdup(reg_val_get_path(*value)));
|
||||
|
||||
fd = fopen(fullpath, "w+");
|
||||
|
||||
/* FIXME */
|
||||
return NULL;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static BOOL reg_dir_del_value(REG_VAL *v)
|
||||
static WERROR reg_dir_del_value(REG_VAL *v)
|
||||
{
|
||||
/* FIXME*/
|
||||
return False;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static REG_OPS reg_backend_dir = {
|
||||
static struct registry_ops reg_backend_dir = {
|
||||
.name = "dir",
|
||||
.open_registry = reg_dir_open,
|
||||
.open_key = reg_dir_open_key,
|
||||
|
@ -22,18 +22,26 @@
|
||||
#include "lib/registry/common/registry.h"
|
||||
#include <gconf/gconf-client.h>
|
||||
|
||||
static BOOL reg_open_gconf(REG_HANDLE *h, const char *location, BOOL try_complete_load)
|
||||
static WERROR gerror_to_werror(GError *error)
|
||||
{
|
||||
if(error == NULL) return WERR_OK;
|
||||
/* FIXME */
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
static WERROR reg_open_gconf(REG_HANDLE *h, const char *location, const char *credentials)
|
||||
{
|
||||
h->backend_data = (void *)gconf_client_get_default();
|
||||
return True;
|
||||
if(!h->backend_data) return WERR_FOOBAR;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL reg_close_gconf(REG_HANDLE *h)
|
||||
static WERROR reg_close_gconf(REG_HANDLE *h)
|
||||
{
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name)
|
||||
static WERROR gconf_open_key (REG_HANDLE *h, const char *name, REG_KEY **key)
|
||||
{
|
||||
REG_KEY *ret;
|
||||
char *fullpath = reg_path_win2unix(strdup(name));
|
||||
@ -41,16 +49,17 @@ static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name)
|
||||
/* Check if key exists */
|
||||
if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) {
|
||||
SAFE_FREE(fullpath);
|
||||
return NULL;
|
||||
return WERR_DEST_NOT_FOUND;
|
||||
}
|
||||
ret = reg_key_new_abs(name, h, NULL);
|
||||
ret->backend_data = talloc_strdup(ret->mem_ctx, fullpath);
|
||||
SAFE_FREE(fullpath);
|
||||
|
||||
return ret;
|
||||
*key = ret;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
|
||||
static WERROR gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
|
||||
{
|
||||
GSList *entries;
|
||||
GSList *cur;
|
||||
@ -113,22 +122,24 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
|
||||
|
||||
g_slist_free(entries);
|
||||
*vals = ar;
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
|
||||
static WERROR gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
|
||||
{
|
||||
GSList *dirs;
|
||||
GSList *cur;
|
||||
REG_KEY **ar = malloc(sizeof(REG_KEY *));
|
||||
REG_KEY **ar = talloc_array_p(p->mem_ctx, REG_KEY *, 1);
|
||||
char *fullpath = p->backend_data;
|
||||
cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL);
|
||||
|
||||
(*count) = 0;
|
||||
while(cur) {
|
||||
ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle,NULL);
|
||||
ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, cur->data);
|
||||
ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+2));
|
||||
char *winpath = reg_path_unix2win(strdup((char *)cur->data));
|
||||
ar[(*count)] = reg_key_new_abs(winpath, p->handle,NULL);
|
||||
free(winpath);
|
||||
ar[(*count)]->backend_data = reg_path_win2unix(talloc_strdup(ar[*count]->mem_ctx, cur->data));
|
||||
ar = talloc_realloc_p(p->mem_ctx, ar, REG_KEY *, (*count)+2);
|
||||
(*count)++;
|
||||
g_free(cur->data);
|
||||
cur = cur->next;
|
||||
@ -136,10 +147,10 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
|
||||
|
||||
g_slist_free(dirs);
|
||||
*subs = ar;
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len)
|
||||
static WERROR gconf_update_value(REG_VAL *val, int type, void *data, int len)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *keypath = val->backend_data;
|
||||
@ -152,22 +163,23 @@ static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len)
|
||||
case REG_EXPAND_SZ:
|
||||
gconf_client_set_string((GConfClient *)val->handle->backend_data, valpath, data, &error);
|
||||
free(valpath);
|
||||
return (error == NULL);
|
||||
return gerror_to_werror(error);
|
||||
|
||||
case REG_DWORD:
|
||||
gconf_client_set_int((GConfClient *)val->handle->backend_data, valpath,
|
||||
*((int *)data), &error);
|
||||
free(valpath);
|
||||
return (error == NULL);
|
||||
return gerror_to_werror(error);
|
||||
default:
|
||||
DEBUG(0, ("Unsupported type: %d\n", type));
|
||||
free(valpath);
|
||||
return False;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
return False;
|
||||
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static REG_OPS reg_backend_gconf = {
|
||||
static struct registry_ops reg_backend_gconf = {
|
||||
.name = "gconf",
|
||||
.open_registry = reg_open_gconf,
|
||||
.close_registry = reg_close_gconf,
|
||||
|
@ -20,51 +20,96 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/registry/common/registry.h"
|
||||
#include "lib/ldb/include/ldb.h"
|
||||
|
||||
char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path)
|
||||
{
|
||||
char *ret = talloc_strdup(mem_ctx, "(dn=");
|
||||
char *begin = (char *)path;
|
||||
char *end = NULL;
|
||||
|
||||
while(begin) {
|
||||
end = strchr(begin, '\\');
|
||||
if(end)end = '\0';
|
||||
if(end - begin != 0) ret = talloc_asprintf_append(mem_ctx, ret, "key=%s,", begin);
|
||||
|
||||
if(end) {
|
||||
*end = '\\';
|
||||
begin = end+1;
|
||||
} else begin = NULL;
|
||||
}
|
||||
|
||||
ret[strlen(ret)-1] = ')';
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves the dn as private_data for every key/val
|
||||
*/
|
||||
|
||||
static BOOL ldb_open_registry(REG_HANDLE *handle, const char *location, BOOL try_full_load)
|
||||
static WERROR ldb_open_registry(REG_HANDLE *handle, const char *location, const char *credentials)
|
||||
{
|
||||
struct ldb_context *c;
|
||||
c = ldb_connect(location, 0, NULL);
|
||||
|
||||
if(!c) return False;
|
||||
if(!c) return WERR_FOOBAR;
|
||||
|
||||
handle->backend_data = c;
|
||||
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL ldb_close_registry(REG_HANDLE *h)
|
||||
static WERROR ldb_close_registry(REG_HANDLE *h)
|
||||
{
|
||||
ldb_close(h);
|
||||
return True;
|
||||
ldb_close((struct ldb_context *)h->backend_data);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
|
||||
static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
|
||||
{
|
||||
ldb_search();
|
||||
struct ldb_context *c = k->handle->backend_data;
|
||||
char *path;
|
||||
struct ldb_message **msg;
|
||||
char *ldap_path;
|
||||
TALLOC_CTX *mem_ctx = talloc_init("ldb_path");
|
||||
REG_KEY *key = NULL;
|
||||
ldap_path = reg_path_to_ldb(mem_ctx, reg_key_get_path(k));
|
||||
|
||||
if(ldb_search(c, NULL, LDB_SCOPE_ONELEVEL, ldap_path, NULL,&msg) > 0) {
|
||||
key = reg_key_new_abs(reg_key_get_path(k), k->handle, ldap_path);
|
||||
talloc_steal(mem_ctx, key->mem_ctx, ldap_path);
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
ldap_search_free(c, msg);
|
||||
talloc_destroy(mem_ctx);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static REG_KEY *ldb_open_key(REG_HANDLE *h, const char *name)
|
||||
|
||||
|
||||
static WERROR ldb_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
|
||||
{
|
||||
struct ldb_context *c = h->backend_data;
|
||||
char *path;
|
||||
struct ldb_message **msg;
|
||||
REG_KEY *key = NULL;
|
||||
(dn=key=Systems,
|
||||
if(ldb_search(c, NULL, LDP_SCOPE_BASE, "", NULL,&msg) > 0) {
|
||||
key = reg_key_new_abs(name, h, base);
|
||||
char *ldap_path;
|
||||
TALLOC_CTX *mem_ctx = talloc_init("ldb_path");
|
||||
ldap_path = reg_path_to_ldb(mem_ctx, name);
|
||||
|
||||
if(ldb_search(c, NULL, LDB_SCOPE_BASE, ldap_path, NULL,&msg) > 0) {
|
||||
*key = reg_key_new_abs(name, h, ldap_path);
|
||||
talloc_steal(mem_ctx, (*key)->mem_ctx, ldap_path);
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
ldap_search_free(c, msg);
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
return key;
|
||||
return WERR_OK;;
|
||||
}
|
||||
|
||||
static REG_OPS reg_backend_ldb = {
|
||||
static struct registry_ops reg_backend_ldb = {
|
||||
.name = "ldb",
|
||||
.open_registry = ldb_open_registry,
|
||||
.close_registry = ldb_close_registry,
|
||||
|
@ -881,7 +881,7 @@ static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, in
|
||||
/*
|
||||
* Process a VK header and return a value
|
||||
*/
|
||||
static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size)
|
||||
static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **value)
|
||||
{
|
||||
char val_name[1024];
|
||||
REGF *regf = parent->handle->backend_data;
|
||||
@ -889,12 +889,12 @@ static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size)
|
||||
const char *val_type;
|
||||
REG_VAL *tmp = NULL;
|
||||
|
||||
if (!vk_hdr) return NULL;
|
||||
if (!vk_hdr) return WERR_INVALID_PARAM;
|
||||
|
||||
if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) {
|
||||
DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n",
|
||||
vk_id, (int)vk_hdr, parent->handle->location));
|
||||
return NULL;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
nam_len = SVAL(&vk_hdr->nam_len,0);
|
||||
@ -943,7 +943,8 @@ static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size)
|
||||
tmp->data_len = dat_len;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
*value = tmp;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL vl_verify(VL_TYPE vl, int count, int size)
|
||||
@ -956,63 +957,67 @@ static BOOL vl_verify(VL_TYPE vl, int count, int size)
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size)
|
||||
static WERROR lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size)
|
||||
{
|
||||
int lf_id;
|
||||
if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) {
|
||||
DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n",
|
||||
lf_id, (int)lf_hdr, h->location));
|
||||
return False;
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static int lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size)
|
||||
static WERROR lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size, int *count)
|
||||
{
|
||||
int count;
|
||||
WERROR error;
|
||||
|
||||
if(!lf_verify(h, lf_hdr, size)) return 0;
|
||||
error = lf_verify(h, lf_hdr, size);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
SMB_REG_ASSERT(size < 0);
|
||||
|
||||
count = SVAL(&lf_hdr->key_count,0);
|
||||
DEBUG(2, ("Key Count: %u\n", count));
|
||||
if (count <= 0) return 0;
|
||||
*count = SVAL(&lf_hdr->key_count,0);
|
||||
DEBUG(2, ("Key Count: %u\n", *count));
|
||||
if (*count <= 0) return WERR_INVALID_PARAM;
|
||||
|
||||
return count;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
|
||||
static REG_KEY *nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent);
|
||||
static WERROR nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Process an LF Header and return a list of sub-keys
|
||||
*/
|
||||
static REG_KEY *lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n)
|
||||
static WERROR lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n, REG_KEY **key)
|
||||
{
|
||||
REGF *regf = parent->handle->backend_data;
|
||||
int count, nk_off;
|
||||
NK_HDR *nk_hdr;
|
||||
WERROR error;
|
||||
|
||||
if (!lf_hdr) return NULL;
|
||||
if (!lf_hdr) return WERR_INVALID_PARAM;
|
||||
|
||||
if(!lf_verify(parent->handle, lf_hdr, size)) return NULL;
|
||||
error = lf_verify(parent->handle, lf_hdr, size);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
SMB_REG_ASSERT(size < 0);
|
||||
|
||||
count = SVAL(&lf_hdr->key_count,0);
|
||||
DEBUG(2, ("Key Count: %u\n", count));
|
||||
if (count <= 0 || n > count) return NULL;
|
||||
if (count <= 0) return WERR_GENERAL_FAILURE;
|
||||
if (n >= count) return WERR_NO_MORE_ITEMS;
|
||||
|
||||
nk_off = IVAL(&lf_hdr->hr[n].nk_off,0);
|
||||
DEBUG(2, ("NK Offset: %0X\n", nk_off));
|
||||
nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off);
|
||||
return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent);
|
||||
return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent, key);
|
||||
}
|
||||
|
||||
static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent)
|
||||
static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **key)
|
||||
{
|
||||
REGF *regf = h->backend_data;
|
||||
REG_KEY *tmp = NULL, *own;
|
||||
@ -1022,12 +1027,12 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
|
||||
int type;
|
||||
char key_name[1024], cls_name[1024];
|
||||
|
||||
if (!nk_hdr) return NULL;
|
||||
if (!nk_hdr) return WERR_INVALID_PARAM;
|
||||
|
||||
if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) {
|
||||
DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n",
|
||||
nk_id, (int)nk_hdr, parent->handle->location));
|
||||
return NULL;
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
SMB_REG_ASSERT(size < 0);
|
||||
@ -1047,7 +1052,7 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
|
||||
DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr));
|
||||
DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n",
|
||||
sizeof(NK_HDR), name_len, clsname_len));
|
||||
/*return NULL;*/
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len));
|
||||
@ -1062,7 +1067,7 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
|
||||
type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
|
||||
if(type == REG_ROOT_KEY && parent) {
|
||||
DEBUG(0,("Root key encountered below root level!\n"));
|
||||
return NULL;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
if(type == REG_ROOT_KEY) tmp = reg_key_new_abs(key_name, h, nk_hdr);
|
||||
@ -1121,7 +1126,8 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
|
||||
|
||||
}
|
||||
|
||||
return tmp;
|
||||
*key = tmp;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1559,7 +1565,7 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL nt_close_registry (REG_HANDLE *h)
|
||||
static WERROR nt_close_registry (REG_HANDLE *h)
|
||||
{
|
||||
REGF *regf = h->backend_data;
|
||||
if (regf->base) munmap(regf->base, regf->sbuf.st_size);
|
||||
@ -1570,10 +1576,10 @@ static BOOL nt_close_registry (REG_HANDLE *h)
|
||||
regf->sk_count = regf->sk_map_size = 0;
|
||||
|
||||
free(regf);
|
||||
return False;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load)
|
||||
static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials)
|
||||
{
|
||||
REGF *regf = (REGF *)malloc(sizeof(REGF));
|
||||
REGF_HDR *regf_hdr;
|
||||
@ -1582,7 +1588,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
|
||||
|
||||
memset(regf, 0, sizeof(REGF));
|
||||
regf->mem_ctx = talloc_init("regf");
|
||||
regf->owner_sid_str = def_owner_sid_str;
|
||||
regf->owner_sid_str = credentials;
|
||||
h->backend_data = regf;
|
||||
|
||||
DEBUG(5, ("Attempting to load registry file\n"));
|
||||
@ -1591,7 +1597,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
|
||||
|
||||
if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) {
|
||||
DEBUG(0, ("Unable to get header\n"));
|
||||
return False;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
/* Now process that header and start to read the rest in */
|
||||
@ -1599,7 +1605,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
|
||||
if ((regf_id = IVAL(®f_hdr->REGF_ID,0)) != str_to_dword("regf")) {
|
||||
DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n",
|
||||
regf_id, h->location));
|
||||
return False;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1608,7 +1614,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
|
||||
if (!valid_regf_hdr(regf_hdr)) {
|
||||
DEBUG(0, ("Registry file header does not validate: %s\n",
|
||||
h->location));
|
||||
return False;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
/* Update the last mod date, and then go get the first NK record and on */
|
||||
@ -1625,7 +1631,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
|
||||
if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) {
|
||||
DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n",
|
||||
hbin_id, h->location));
|
||||
return False;
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1655,15 +1661,15 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
|
||||
|
||||
h->backend_data = regf;
|
||||
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static REG_KEY *nt_get_root_key(REG_HANDLE *h)
|
||||
static WERROR nt_get_root_key(REG_HANDLE *h, REG_KEY **key)
|
||||
{
|
||||
return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL);
|
||||
return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key);
|
||||
}
|
||||
|
||||
static int nt_num_subkeys(REG_KEY *k)
|
||||
static WERROR nt_num_subkeys(REG_KEY *k, int *num)
|
||||
{
|
||||
REGF *regf = k->handle->backend_data;
|
||||
LF_HDR *lf_hdr;
|
||||
@ -1671,19 +1677,23 @@ static int nt_num_subkeys(REG_KEY *k)
|
||||
NK_HDR *nk_hdr = k->backend_data;
|
||||
lf_off = IVAL(&nk_hdr->lf_off,0);
|
||||
DEBUG(2, ("SubKey list offset: %0X\n", lf_off));
|
||||
if(lf_off == -1) return 0;
|
||||
if(lf_off == -1) {
|
||||
*num = 0;
|
||||
return WERR_OK;
|
||||
}
|
||||
lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off);
|
||||
|
||||
return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr));
|
||||
return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr), num);
|
||||
}
|
||||
|
||||
static int nt_num_values(REG_KEY *k)
|
||||
static WERROR nt_num_values(REG_KEY *k, int *count)
|
||||
{
|
||||
NK_HDR *nk_hdr = k->backend_data;
|
||||
return IVAL(&nk_hdr->val_cnt,0);
|
||||
*count = IVAL(&nk_hdr->val_cnt,0);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static REG_VAL *nt_value_by_index(REG_KEY *k, int n)
|
||||
static WERROR nt_value_by_index(REG_KEY *k, int n, REG_VAL **value)
|
||||
{
|
||||
VL_TYPE *vl;
|
||||
int val_off, vk_off;
|
||||
@ -1696,10 +1706,10 @@ static REG_VAL *nt_value_by_index(REG_KEY *k, int n)
|
||||
|
||||
vk_off = IVAL(&vl[n],0);
|
||||
vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off);
|
||||
return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr));
|
||||
return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr), value);
|
||||
}
|
||||
|
||||
static REG_KEY *nt_key_by_index(REG_KEY *k, int n)
|
||||
static WERROR nt_key_by_index(REG_KEY *k, int n, REG_KEY **subkey)
|
||||
{
|
||||
REGF *regf = k->handle->backend_data;
|
||||
int lf_off;
|
||||
@ -1714,13 +1724,13 @@ static REG_KEY *nt_key_by_index(REG_KEY *k, int n)
|
||||
|
||||
if (lf_off != -1) {
|
||||
lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off);
|
||||
return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n);
|
||||
return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
static REG_OPS reg_backend_nt4 = {
|
||||
static struct registry_ops reg_backend_nt4 = {
|
||||
.name = "nt4",
|
||||
.open_registry = nt_open_registry,
|
||||
.close_registry = nt_close_registry,
|
||||
|
@ -77,12 +77,18 @@ struct {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full)
|
||||
static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials)
|
||||
{
|
||||
BOOL res = True;
|
||||
struct rpc_data *mydata = talloc(h->mem_ctx, sizeof(struct rpc_data));
|
||||
char *binding = strdup(location);
|
||||
NTSTATUS status;
|
||||
char *user, *pass;
|
||||
|
||||
if(!credentials || !location) return WERR_INVALID_PARAM;
|
||||
|
||||
user = talloc_strdup(h->mem_ctx, credentials);
|
||||
pass = strchr(user, '%');
|
||||
*pass = '\0'; pass++;
|
||||
|
||||
ZERO_STRUCTP(mydata);
|
||||
|
||||
@ -90,26 +96,26 @@ static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full
|
||||
DCERPC_WINREG_UUID,
|
||||
DCERPC_WINREG_VERSION,
|
||||
lp_workgroup(),
|
||||
"tridge", "samba");
|
||||
user, pass);
|
||||
|
||||
if(!NT_STATUS_IS_OK(status)) return False;
|
||||
|
||||
h->backend_data = mydata;
|
||||
|
||||
return True;
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
|
||||
static REG_KEY *rpc_open_root(REG_HANDLE *h)
|
||||
static WERROR rpc_open_root(REG_HANDLE *h, REG_KEY **k)
|
||||
{
|
||||
/* There's not really a 'root' key here */
|
||||
return reg_key_new_abs("\\", h, h->backend_data);
|
||||
*k = reg_key_new_abs("\\", h, h->backend_data);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL rpc_close_registry(REG_HANDLE *h)
|
||||
static WERROR rpc_close_registry(REG_HANDLE *h)
|
||||
{
|
||||
dcerpc_pipe_close(((struct rpc_data *)h->backend_data)->pipe);
|
||||
free(h->backend_data);
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
|
||||
@ -161,12 +167,15 @@ static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
|
||||
return key_handle;
|
||||
}
|
||||
|
||||
static REG_KEY *rpc_open_key(REG_HANDLE *h, const char *name)
|
||||
static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
|
||||
{
|
||||
return reg_key_new_abs(name, h, rpc_get_key_handle(h, name));
|
||||
struct policy_handle *pol = rpc_get_key_handle(h, name);
|
||||
if(!pol) return WERR_DEST_NOT_FOUND;
|
||||
*key = reg_key_new_abs(name, h, pol);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
{
|
||||
struct winreg_EnumKey r;
|
||||
struct winreg_EnumKeyNameRequest keyname;
|
||||
@ -188,12 +197,12 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
|
||||
*subkeys = ar;
|
||||
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent));
|
||||
|
||||
if(!parent->backend_data) return False;
|
||||
if(!parent->backend_data) return WERR_GENERAL_FAILURE;
|
||||
|
||||
(*count) = 0;
|
||||
r.in.handle = parent->backend_data;
|
||||
@ -219,10 +228,10 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
}
|
||||
|
||||
*subkeys = ar;
|
||||
return True;
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
|
||||
static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
|
||||
{
|
||||
struct winreg_EnumValue r;
|
||||
struct winreg_Uint8buf value;
|
||||
@ -238,12 +247,12 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
|
||||
/* Root */
|
||||
if(parent->backend_data == parent->handle->backend_data) {
|
||||
*values = ar;
|
||||
return True;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent));
|
||||
|
||||
if(!parent->backend_data) return False;
|
||||
if(!parent->backend_data) return WERR_GENERAL_FAILURE;
|
||||
|
||||
r.in.handle = parent->backend_data;
|
||||
r.in.enum_index = 0;
|
||||
@ -283,22 +292,48 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
|
||||
|
||||
*values = ar;
|
||||
|
||||
return True;
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static BOOL rpc_add_key(REG_KEY *parent, const char *name)
|
||||
static WERROR rpc_add_key(REG_KEY *parent, const char *name)
|
||||
{
|
||||
/* FIXME */
|
||||
return False;
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static BOOL rpc_del_key(REG_KEY *k)
|
||||
static struct policy_handle*get_hive(REG_KEY *k)
|
||||
{
|
||||
/* FIXME */
|
||||
return False;
|
||||
int i;
|
||||
struct rpc_data *mydata = k->handle->backend_data;
|
||||
for(i = 0; known_hives[i].name; i++) {
|
||||
if(!strncmp(known_hives[i].name, reg_key_get_path(k)+1, strlen(known_hives[i].name)))
|
||||
return mydata->hives[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static REG_OPS reg_backend_rpc = {
|
||||
static WERROR rpc_del_key(REG_KEY *k)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct rpc_data *mydata = k->handle->backend_data;
|
||||
struct winreg_DeleteKey r;
|
||||
char *hivepath;
|
||||
struct policy_handle *hive = get_hive(k);
|
||||
|
||||
printf("first: %s\n", reg_key_get_path(k));
|
||||
hivepath = strchr(reg_key_get_path(k), '\\');
|
||||
hivepath = strchr(hivepath+1, '\\');
|
||||
printf("asfter: %s\n", hivepath+1);
|
||||
|
||||
r.in.handle = hive;
|
||||
init_winreg_String(&r.in.key, hivepath+1);
|
||||
|
||||
status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r);
|
||||
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static struct registry_ops reg_backend_rpc = {
|
||||
.name = "rpc",
|
||||
.open_registry = rpc_open_registry,
|
||||
.close_registry = rpc_close_registry,
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/registry/common/registry.h"
|
||||
#include "windows/registry.h"
|
||||
|
||||
static REG_OPS reg_backend_wine = {
|
||||
.name = "wine",
|
||||
|
758
source4/lib/registry/tools/gregedit.c
Normal file
758
source4/lib/registry/tools/gregedit.c
Normal file
@ -0,0 +1,758 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Gtk registry frontend
|
||||
|
||||
Copyright (C) Jelmer Vernooij 2004
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "includes.h"
|
||||
|
||||
GtkWidget *openfilewin;
|
||||
GtkWidget *savefilewin;
|
||||
GtkTreeStore *store_keys;
|
||||
GtkListStore *store_vals;
|
||||
GtkWidget *tree_keys;
|
||||
GtkWidget *aboutwin;
|
||||
GtkWidget *mainwin;
|
||||
|
||||
GtkWidget *rpcwin;
|
||||
GtkWidget *rpcwin_host;
|
||||
GtkWidget *rpcwin_user;
|
||||
GtkWidget *rpcwin_password;
|
||||
GtkWidget *save;
|
||||
GtkWidget *save_as;
|
||||
GtkWidget* create_openfilewin (void);
|
||||
GtkWidget* create_savefilewin (void);
|
||||
static GtkWidget* create_aboutwin (void);
|
||||
REG_HANDLE *registry = NULL;
|
||||
|
||||
static void gtk_show_werror(WERROR err)
|
||||
{
|
||||
GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(mainwin),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"Registry error: %s\n", win_errstr(err));
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void treeview_add_val(REG_VAL *val)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gtk_list_store_append(store_vals, &iter);
|
||||
gtk_list_store_set (store_vals,
|
||||
&iter,
|
||||
0,
|
||||
reg_val_name(val),
|
||||
1,
|
||||
str_regtype(reg_val_type(val)),
|
||||
2,
|
||||
reg_val_data_string(val),
|
||||
3,
|
||||
val,
|
||||
-1);
|
||||
}
|
||||
|
||||
static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2)
|
||||
{
|
||||
GtkTreeIter iter, tmpiter;
|
||||
REG_KEY *k, *sub;
|
||||
char *name;
|
||||
GValue value;
|
||||
WERROR error;
|
||||
int i;
|
||||
|
||||
/* See if this row has ever had a name gtk_tree_store_set()'ed to it.
|
||||
If not, read the directory contents */
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent,
|
||||
0, &name, -1);
|
||||
|
||||
if(!name) return;
|
||||
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, 1, &k, -1);
|
||||
|
||||
g_assert(k);
|
||||
|
||||
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
|
||||
/* Replace the blank child with the first directory entry
|
||||
You may be tempted to remove the blank child node and then
|
||||
append a new one. Don't. If you remove the blank child
|
||||
node GTK gets confused and won't expand the parent row. */
|
||||
|
||||
if(i == 0) {
|
||||
gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys),
|
||||
&iter, parent);
|
||||
} else {
|
||||
gtk_tree_store_append(store_keys, &iter, parent);
|
||||
}
|
||||
gtk_tree_store_set (store_keys,
|
||||
&iter,
|
||||
0,
|
||||
reg_key_name(sub),
|
||||
1,
|
||||
sub,
|
||||
-1);
|
||||
|
||||
gtk_tree_store_append(store_keys, &tmpiter, &iter);
|
||||
}
|
||||
|
||||
/* Remove placeholder child */
|
||||
if(i == 0) {
|
||||
gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys),
|
||||
&iter, parent);
|
||||
gtk_tree_store_remove(store_keys, &iter);
|
||||
}
|
||||
|
||||
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
|
||||
}
|
||||
|
||||
static void registry_load_root()
|
||||
{
|
||||
REG_KEY *root;
|
||||
GtkTreeIter iter, tmpiter;
|
||||
WERROR error;
|
||||
if(!registry) return;
|
||||
|
||||
error = reg_get_root(registry, &root);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_tree_store_clear(store_keys);
|
||||
|
||||
/* Add the root */
|
||||
gtk_tree_store_append(store_keys, &iter, NULL);
|
||||
gtk_tree_store_set (store_keys,
|
||||
&iter,
|
||||
0,
|
||||
reg_key_name(root),
|
||||
1,
|
||||
root,
|
||||
-1);
|
||||
|
||||
gtk_tree_store_append(store_keys, &tmpiter, &iter);
|
||||
|
||||
gtk_widget_set_sensitive( save, True );
|
||||
gtk_widget_set_sensitive( save_as, True );
|
||||
}
|
||||
|
||||
GtkWidget* create_rpcwin (void)
|
||||
{
|
||||
GtkWidget *dialog_vbox1;
|
||||
GtkWidget *table1;
|
||||
GtkWidget *label1;
|
||||
GtkWidget *label2;
|
||||
GtkWidget *label3;
|
||||
GtkWidget *dialog_action_area1;
|
||||
GtkWidget *cancelbutton1;
|
||||
GtkWidget *okbutton1;
|
||||
|
||||
rpcwin = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (rpcwin), "Connect to remote server");
|
||||
|
||||
dialog_vbox1 = GTK_DIALOG (rpcwin)->vbox;
|
||||
gtk_widget_show (dialog_vbox1);
|
||||
|
||||
table1 = gtk_table_new (3, 2, FALSE);
|
||||
gtk_widget_show (table1);
|
||||
gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0);
|
||||
|
||||
label1 = gtk_label_new ("Host:");
|
||||
gtk_widget_show (label1);
|
||||
gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);
|
||||
|
||||
label2 = gtk_label_new ("User:");
|
||||
gtk_widget_show (label2);
|
||||
gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 1, 2,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
|
||||
|
||||
label3 = gtk_label_new ("Password:");
|
||||
gtk_widget_show (label3);
|
||||
gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
|
||||
|
||||
rpcwin_host = gtk_entry_new ();
|
||||
gtk_widget_show (rpcwin_host);
|
||||
gtk_table_attach (GTK_TABLE (table1), rpcwin_host, 1, 2, 0, 1,
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
|
||||
rpcwin_user = gtk_entry_new ();
|
||||
gtk_widget_show (rpcwin_user);
|
||||
gtk_table_attach (GTK_TABLE (table1), rpcwin_user, 1, 2, 1, 2,
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
|
||||
rpcwin_password = gtk_entry_new ();
|
||||
gtk_widget_show (rpcwin_password);
|
||||
gtk_table_attach (GTK_TABLE (table1), rpcwin_password, 1, 2, 2, 3,
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_entry_set_visibility (GTK_ENTRY (rpcwin_password), FALSE);
|
||||
|
||||
dialog_action_area1 = GTK_DIALOG (rpcwin)->action_area;
|
||||
gtk_widget_show (dialog_action_area1);
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
|
||||
|
||||
cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
|
||||
gtk_widget_show (cancelbutton1);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), cancelbutton1, GTK_RESPONSE_CANCEL);
|
||||
GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);
|
||||
|
||||
okbutton1 = gtk_button_new_from_stock ("gtk-ok");
|
||||
gtk_widget_show (okbutton1);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), okbutton1, GTK_RESPONSE_OK);
|
||||
GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);
|
||||
|
||||
return rpcwin;
|
||||
}
|
||||
|
||||
|
||||
static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin()));
|
||||
char *filename;
|
||||
WERROR error;
|
||||
switch(result) {
|
||||
case GTK_RESPONSE_OK:
|
||||
filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin)));
|
||||
error = reg_open("nt4", filename, NULL, ®istry);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
return;
|
||||
}
|
||||
registry_load_root();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(openfilewin);
|
||||
}
|
||||
|
||||
void on_open_gconf_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
WERROR error = reg_open("gconf", NULL, NULL, ®istry);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
return;
|
||||
}
|
||||
|
||||
registry_load_root();
|
||||
}
|
||||
|
||||
void
|
||||
on_open_remote_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
char *location, *credentials;
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(create_rpcwin()));
|
||||
WERROR error;
|
||||
switch(result) {
|
||||
case GTK_RESPONSE_OK:
|
||||
asprintf(&location, "ncacn_np:%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_host)));
|
||||
asprintf(&credentials, "%s%%%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_user)), gtk_entry_get_text(GTK_ENTRY(rpcwin_password)));
|
||||
error = reg_open("rpc", location, credentials, ®istry);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
return;
|
||||
}
|
||||
free(location); free(credentials);
|
||||
registry_load_root();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(rpcwin);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_save_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
WERROR error = reg_save(registry, NULL);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_save_as_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
gint result;
|
||||
WERROR error;
|
||||
create_savefilewin();
|
||||
result = gtk_dialog_run(GTK_DIALOG(savefilewin));
|
||||
switch(result) {
|
||||
case GTK_RESPONSE_OK:
|
||||
error = reg_save(registry, gtk_file_selection_get_filename(GTK_FILE_SELECTION(savefilewin)));
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
gtk_widget_destroy(savefilewin);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_quit_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_cut_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_copy_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_paste_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_delete_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_about_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_dialog_run(GTK_DIALOG(create_aboutwin()));
|
||||
gtk_widget_destroy(aboutwin);
|
||||
}
|
||||
|
||||
void on_key_activate (GtkTreeView *treeview,
|
||||
GtkTreePath *path,
|
||||
gpointer user_data)
|
||||
{
|
||||
int i;
|
||||
REG_KEY *k;
|
||||
REG_VAL *val;
|
||||
WERROR error;
|
||||
|
||||
//FIXME gtk_tree_model_get(GTK_TREE_MODEL(store_keys), iter, 1, &k, -1);
|
||||
|
||||
gtk_list_store_clear(store_vals);
|
||||
|
||||
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) {
|
||||
treeview_add_val(val);
|
||||
}
|
||||
|
||||
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GtkWidget* create_mainwin (void)
|
||||
{
|
||||
GtkWidget *vbox1;
|
||||
GtkWidget *menubar;
|
||||
GtkWidget *menu_file;
|
||||
GtkWidget *menu_file_menu;
|
||||
GtkWidget *open_nt4;
|
||||
GtkWidget *open_gconf;
|
||||
GtkWidget *open_remote;
|
||||
GtkWidget *separatormenuitem1;
|
||||
GtkWidget *quit;
|
||||
GtkWidget *men_edit;
|
||||
GtkWidget *men_edit_menu;
|
||||
GtkWidget *cut;
|
||||
GtkWidget *copy;
|
||||
GtkWidget *paste;
|
||||
GtkWidget *delete;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *curcol;
|
||||
GtkWidget *help;
|
||||
GtkWidget *help_menu;
|
||||
GtkWidget *about;
|
||||
GtkWidget *hbox1;
|
||||
GtkWidget *scrolledwindow1;
|
||||
GtkWidget *scrolledwindow2;
|
||||
GtkWidget *tree_vals;
|
||||
GtkWidget *statusbar;
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkTreeIter iter, child;
|
||||
|
||||
accel_group = gtk_accel_group_new ();
|
||||
|
||||
mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (mainwin), "Registry editor");
|
||||
gtk_window_set_default_size (GTK_WINDOW (mainwin), 642, 562);
|
||||
|
||||
vbox1 = gtk_vbox_new (FALSE, 0);
|
||||
gtk_widget_show (vbox1);
|
||||
gtk_container_add (GTK_CONTAINER (mainwin), vbox1);
|
||||
|
||||
menubar = gtk_menu_bar_new ();
|
||||
gtk_widget_show (menubar);
|
||||
gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0);
|
||||
|
||||
menu_file = gtk_menu_item_new_with_mnemonic ("_File");
|
||||
gtk_widget_show (menu_file);
|
||||
gtk_container_add (GTK_CONTAINER (menubar), menu_file);
|
||||
|
||||
menu_file_menu = gtk_menu_new ();
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu);
|
||||
|
||||
open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file");
|
||||
gtk_widget_show (open_nt4);
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4);
|
||||
|
||||
open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf");
|
||||
gtk_widget_show (open_gconf);
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf);
|
||||
|
||||
open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote");
|
||||
gtk_widget_show (open_remote);
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote);
|
||||
|
||||
save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group);
|
||||
gtk_widget_show (save);
|
||||
gtk_widget_set_sensitive( save, False );
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), save);
|
||||
|
||||
save_as = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
|
||||
gtk_widget_show (save_as);
|
||||
gtk_widget_set_sensitive( save_as, False );
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), save_as);
|
||||
|
||||
separatormenuitem1 = gtk_menu_item_new ();
|
||||
gtk_widget_show (separatormenuitem1);
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), separatormenuitem1);
|
||||
gtk_widget_set_sensitive (separatormenuitem1, FALSE);
|
||||
|
||||
quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
|
||||
gtk_widget_show (quit);
|
||||
gtk_container_add (GTK_CONTAINER (menu_file_menu), quit);
|
||||
|
||||
men_edit = gtk_menu_item_new_with_mnemonic ("_Edit");
|
||||
gtk_widget_show (men_edit);
|
||||
gtk_container_add (GTK_CONTAINER (menubar), men_edit);
|
||||
|
||||
men_edit_menu = gtk_menu_new ();
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (men_edit), men_edit_menu);
|
||||
|
||||
cut = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group);
|
||||
gtk_widget_show (cut);
|
||||
gtk_widget_set_sensitive(cut, False);
|
||||
gtk_container_add (GTK_CONTAINER (men_edit_menu), cut);
|
||||
|
||||
copy = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group);
|
||||
gtk_widget_show (copy);
|
||||
gtk_widget_set_sensitive(copy, False);
|
||||
gtk_container_add (GTK_CONTAINER (men_edit_menu), copy);
|
||||
|
||||
paste = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group);
|
||||
gtk_widget_show (paste);
|
||||
gtk_widget_set_sensitive(paste, False);
|
||||
gtk_container_add (GTK_CONTAINER (men_edit_menu), paste);
|
||||
|
||||
delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
|
||||
gtk_widget_show (delete);
|
||||
gtk_widget_set_sensitive(delete, False);
|
||||
gtk_container_add (GTK_CONTAINER (men_edit_menu), delete);
|
||||
|
||||
help = gtk_menu_item_new_with_mnemonic ("_Help");
|
||||
gtk_widget_show (help);
|
||||
gtk_container_add (GTK_CONTAINER (menubar), help);
|
||||
|
||||
help_menu = gtk_menu_new ();
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu);
|
||||
|
||||
about = gtk_menu_item_new_with_mnemonic ("_About");
|
||||
gtk_widget_show (about);
|
||||
gtk_container_add (GTK_CONTAINER (help_menu), about);
|
||||
|
||||
hbox1 = gtk_hbox_new (FALSE, 0);
|
||||
gtk_widget_show (hbox1);
|
||||
gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
|
||||
|
||||
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_show (scrolledwindow1);
|
||||
gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
|
||||
|
||||
tree_keys = gtk_tree_view_new ();
|
||||
|
||||
/* Column names */
|
||||
curcol = gtk_tree_view_column_new ();
|
||||
gtk_tree_view_column_set_title(curcol, "Name");
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
gtk_tree_view_column_pack_start(curcol, renderer, True);
|
||||
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_keys), curcol);
|
||||
|
||||
gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0);
|
||||
gtk_widget_show (tree_keys);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow1), tree_keys);
|
||||
store_keys = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_keys), GTK_TREE_MODEL(store_keys));
|
||||
g_object_unref(store_keys);
|
||||
|
||||
g_signal_connect ((gpointer) tree_keys, "row-activated",
|
||||
G_CALLBACK (on_key_activate),
|
||||
NULL);
|
||||
|
||||
g_signal_connect ((gpointer) tree_keys, "row-expanded",
|
||||
G_CALLBACK (expand_key),
|
||||
NULL);
|
||||
|
||||
scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_show (scrolledwindow2);
|
||||
gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0);
|
||||
|
||||
tree_vals = gtk_tree_view_new ();
|
||||
/* Column names */
|
||||
curcol = gtk_tree_view_column_new_with_attributes ("Name", gtk_cell_renderer_text_new(), NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
|
||||
|
||||
|
||||
curcol = gtk_tree_view_column_new_with_attributes ("Type", gtk_cell_renderer_text_new(), NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
|
||||
|
||||
curcol = gtk_tree_view_column_new_with_attributes ("Value", gtk_cell_renderer_text_new(), NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
|
||||
gtk_widget_show (tree_vals);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow2), tree_vals);
|
||||
|
||||
store_vals = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_vals), GTK_TREE_MODEL(store_vals));
|
||||
g_object_unref(store_vals);
|
||||
|
||||
statusbar = gtk_statusbar_new ();
|
||||
gtk_widget_show (statusbar);
|
||||
gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0);
|
||||
gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE);
|
||||
|
||||
g_signal_connect ((gpointer) open_nt4, "activate",
|
||||
G_CALLBACK (on_open_nt4_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) open_gconf, "activate",
|
||||
G_CALLBACK (on_open_gconf_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) open_remote, "activate",
|
||||
G_CALLBACK (on_open_remote_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) save, "activate",
|
||||
G_CALLBACK (on_save_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) save_as, "activate",
|
||||
G_CALLBACK (on_save_as_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) quit, "activate",
|
||||
G_CALLBACK (on_quit_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) cut, "activate",
|
||||
G_CALLBACK (on_cut_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) copy, "activate",
|
||||
G_CALLBACK (on_copy_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) paste, "activate",
|
||||
G_CALLBACK (on_paste_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) delete, "activate",
|
||||
G_CALLBACK (on_delete_activate),
|
||||
NULL);
|
||||
g_signal_connect ((gpointer) about, "activate",
|
||||
G_CALLBACK (on_about_activate),
|
||||
NULL);
|
||||
|
||||
gtk_window_add_accel_group (GTK_WINDOW (mainwin), accel_group);
|
||||
|
||||
return mainwin;
|
||||
}
|
||||
|
||||
static GtkWidget* create_aboutwin (void)
|
||||
{
|
||||
GtkWidget *dialog_vbox1;
|
||||
GtkWidget *image1;
|
||||
GtkWidget *label1;
|
||||
GtkWidget *label2;
|
||||
GtkWidget *dialog_action_area1;
|
||||
GtkWidget *closebutton1;
|
||||
|
||||
aboutwin = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (aboutwin), "About GRegEdit");
|
||||
gtk_window_set_resizable (GTK_WINDOW (aboutwin), FALSE);
|
||||
|
||||
dialog_vbox1 = GTK_DIALOG (aboutwin)->vbox;
|
||||
gtk_widget_show (dialog_vbox1);
|
||||
|
||||
/* FIXME: Samba logo ?
|
||||
image1 = create_pixmap (aboutwin, "samba.png");
|
||||
gtk_widget_show (image1);
|
||||
gtk_box_pack_start (GTK_BOX (dialog_vbox1), image1, FALSE, TRUE, 0); */
|
||||
|
||||
label1 = gtk_label_new ("GRegEdit 0.1");
|
||||
gtk_widget_show (label1);
|
||||
gtk_box_pack_start (GTK_BOX (dialog_vbox1), label1, FALSE, FALSE, 0);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label1), TRUE);
|
||||
|
||||
label2 = gtk_label_new_with_mnemonic ("(C) 2004 Jelmer Vernooij <jelmer@samba.org>\nPart of Samba\nhttp://www.samba.org/\n");
|
||||
gtk_widget_show (label2);
|
||||
gtk_box_pack_start (GTK_BOX (dialog_vbox1), label2, TRUE, FALSE, 0);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label2), TRUE);
|
||||
|
||||
dialog_action_area1 = GTK_DIALOG (aboutwin)->action_area;
|
||||
gtk_widget_show (dialog_action_area1);
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
|
||||
|
||||
closebutton1 = gtk_button_new_from_stock ("gtk-close");
|
||||
gtk_widget_show (closebutton1);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (aboutwin), closebutton1, GTK_RESPONSE_CLOSE);
|
||||
GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT);
|
||||
|
||||
return aboutwin;
|
||||
}
|
||||
|
||||
|
||||
GtkWidget* create_openfilewin (void)
|
||||
{
|
||||
GtkWidget *ok_button;
|
||||
GtkWidget *cancel_button;
|
||||
|
||||
openfilewin = gtk_file_selection_new ("Select File");
|
||||
gtk_container_set_border_width (GTK_CONTAINER (openfilewin), 10);
|
||||
|
||||
ok_button = GTK_FILE_SELECTION (openfilewin)->ok_button;
|
||||
gtk_widget_show (ok_button);
|
||||
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
|
||||
|
||||
cancel_button = GTK_FILE_SELECTION (openfilewin)->cancel_button;
|
||||
gtk_widget_show (cancel_button);
|
||||
GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
|
||||
|
||||
return openfilewin;
|
||||
}
|
||||
|
||||
GtkWidget* create_savefilewin (void)
|
||||
{
|
||||
GtkWidget *ok_button;
|
||||
GtkWidget *cancel_button;
|
||||
|
||||
savefilewin = gtk_file_selection_new ("Select File");
|
||||
gtk_container_set_border_width (GTK_CONTAINER (savefilewin), 10);
|
||||
|
||||
ok_button = GTK_FILE_SELECTION (savefilewin)->ok_button;
|
||||
gtk_widget_show (ok_button);
|
||||
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
|
||||
|
||||
cancel_button = GTK_FILE_SELECTION (savefilewin)->cancel_button;
|
||||
gtk_widget_show (cancel_button);
|
||||
GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
|
||||
|
||||
return savefilewin;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
poptContext pc;
|
||||
const char *backend = NULL, *credentials = NULL, *location;
|
||||
int opt;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
|
||||
{"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%%password)", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
|
||||
|
||||
while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
}
|
||||
|
||||
location = poptGetArg(pc);
|
||||
|
||||
if(location) {
|
||||
WERROR error;
|
||||
|
||||
if(!backend) {
|
||||
if(credentials)backend = "rpc";
|
||||
else backend = "nt4";
|
||||
}
|
||||
|
||||
error = reg_open(backend, location, credentials, ®istry);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(error);
|
||||
return -1;
|
||||
}
|
||||
mainwin = create_mainwin ();
|
||||
registry_load_root();
|
||||
} else
|
||||
mainwin = create_mainwin ();
|
||||
|
||||
gtk_widget_show (mainwin);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
if(registry)reg_free(registry);
|
||||
return 0;
|
||||
}
|
@ -201,6 +201,7 @@ int main (int argc, char **argv)
|
||||
REG_HANDLE *h;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
POPT_COMMON_SAMBA
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
@ -72,11 +72,11 @@
|
||||
[in,out,ref] policy_handle *handle,
|
||||
[in] winreg_String key,
|
||||
[in] winreg_String class,
|
||||
[in,out] uint32 reserved,
|
||||
[in] uint32 reserved,
|
||||
[out] uint32 *unknown,
|
||||
[in] uint32 access_mask,
|
||||
[in] uint32 sec_info,
|
||||
[in] sec_desc_buf *sec_desc,
|
||||
[in] uint32 reserved2
|
||||
[in,ref] uint32 *sec_info,
|
||||
[in] sec_desc_buf *sec_desc
|
||||
);
|
||||
|
||||
/******************/
|
||||
@ -150,6 +150,14 @@
|
||||
/******************/
|
||||
/* Function: 0x0c */
|
||||
WERROR winreg_GetKeySecurity(
|
||||
[in,ref] policy_handle *handle,
|
||||
[in] uint32 sec_info,
|
||||
[in] uint32 *len1,
|
||||
[in] uint32 empty,
|
||||
[in] uint32 len2,
|
||||
[in] uint32 unknown1,
|
||||
[in] uint32 unknown2,
|
||||
[out] sec_desc_buf *data
|
||||
);
|
||||
|
||||
/******************/
|
||||
@ -211,11 +219,24 @@
|
||||
/******************/
|
||||
/* Function: 0x15 */
|
||||
WERROR winreg_SetKeySecurity(
|
||||
[in,ref] policy_handle *handle,
|
||||
[in] uint32 sec_info,
|
||||
[in] sec_desc_buf *sec_desc
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
uint32 max_len;
|
||||
[length_is(buf_max_len)] uint8 *buffer;
|
||||
uint32 len;
|
||||
} winreg_Value;
|
||||
|
||||
/******************/
|
||||
/* Function: 0x16 */
|
||||
WERROR winreg_SetValue(
|
||||
[in,ref] policy_handle *handle,
|
||||
[in] winreg_String name,
|
||||
[in] uint32 type,
|
||||
[in] winreg_Value value
|
||||
);
|
||||
|
||||
/******************/
|
||||
@ -226,11 +247,15 @@
|
||||
/******************/
|
||||
/* Function: 0x18 */
|
||||
WERROR winreg_InitiateSystemShutdown(
|
||||
[in] winreg_String message,
|
||||
[in] uint32 timeout,
|
||||
[in] uint16 flags
|
||||
);
|
||||
|
||||
/******************/
|
||||
/* Function: 0x19 */
|
||||
WERROR winreg_AbortSystemShutdown(
|
||||
[in,ref] uint16 *server
|
||||
);
|
||||
|
||||
/******************/
|
||||
@ -264,7 +289,7 @@
|
||||
/******************/
|
||||
/* Function: 0x1e */
|
||||
WERROR winreg_InitiateSystemShutdownEx(
|
||||
);
|
||||
);
|
||||
|
||||
/******************/
|
||||
/* Function: 0x1f */
|
||||
|
@ -22,6 +22,18 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
/**
|
||||
* General notes for the current implementation:
|
||||
*
|
||||
* - All hives are currently openened as subkeys of one single registry file
|
||||
* (e.g. HKCR from \HKEY_CURRENT_USER, etc). This might be changed in
|
||||
* the future and we might want to make it possible to configure
|
||||
* what registries are behind which hives (e.g.
|
||||
* \HKEY_CURRENT_USER -> gconf,
|
||||
* \HKEY_LOCAL_MACHINE -> tdb,
|
||||
* etc
|
||||
*/
|
||||
|
||||
enum handle_types { HTYPE_REGKEY, HTYPE_REGVAL };
|
||||
|
||||
struct _privatedata {
|
||||
@ -39,9 +51,10 @@ static void winreg_unbind(struct dcesrv_connection *dc, const struct dcesrv_inte
|
||||
static NTSTATUS winreg_bind(struct dcesrv_call_state *dc, const struct dcesrv_interface *di)
|
||||
{
|
||||
struct _privatedata *data;
|
||||
data = talloc(dc->mem_ctx, sizeof(struct _privatedata));
|
||||
data->registry = reg_open(lp_parm_string(-1,"winreg","subsystem"),lp_parm_string(-1,"winreg", "file"), False);
|
||||
if(!data->registry) return NT_STATUS_UNSUCCESSFUL;
|
||||
WERROR error;
|
||||
data = talloc(dc->conn->mem_ctx, sizeof(struct _privatedata));
|
||||
error = reg_open("dir", "/tmp/reg", "", &data->registry);
|
||||
if(!W_ERROR_IS_OK(error)) return werror_to_ntstatus(error);
|
||||
dc->conn->private = data;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -49,70 +62,34 @@ static NTSTATUS winreg_bind(struct dcesrv_call_state *dc, const struct dcesrv_in
|
||||
#define DCESRV_INTERFACE_WINREG_BIND winreg_bind
|
||||
#define DCESRV_INTERFACE_WINREG_UNBIND winreg_unbind
|
||||
|
||||
/*
|
||||
winreg_OpenHKCR
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKCR(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKCR *r)
|
||||
{
|
||||
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKCU
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKCU(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKCU *r)
|
||||
{
|
||||
struct _privatedata *data = dce_call->conn->private;
|
||||
REG_KEY *root = reg_get_root(data->registry);
|
||||
REG_KEY *k = reg_open_key(root, "\\HKEY_CURRENT_USER");
|
||||
|
||||
if(!k) {
|
||||
r->out.result = WERR_BADFILE;
|
||||
} else {
|
||||
struct dcesrv_handle *h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||
h->data = k;
|
||||
r->out.handle = &h->wire_handle;
|
||||
}
|
||||
|
||||
r->out.result = WERR_OK;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKLM
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKLM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKLM *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKPD
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKPD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKPD *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKU
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKU(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKU *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
#define func_winreg_OpenHive(k,n) static NTSTATUS winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
|
||||
{ \
|
||||
struct _privatedata *data = dce_call->conn->private; \
|
||||
REG_KEY *root/* = reg_get_root(data->registry)*/; \
|
||||
REG_KEY *k/* = reg_open_key(root, n)*/; \
|
||||
\
|
||||
if(!k) { \
|
||||
r->out.result = WERR_BADFILE; \
|
||||
} else { \
|
||||
struct dcesrv_handle *h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY); \
|
||||
h->data = k; \
|
||||
r->out.handle = &h->wire_handle; \
|
||||
} \
|
||||
\
|
||||
r->out.result = WERR_OK; \
|
||||
\
|
||||
return NT_STATUS_OK; \
|
||||
}
|
||||
|
||||
func_winreg_OpenHive(HKCR,"\\HKEY_CLASSES_ROOT")
|
||||
func_winreg_OpenHive(HKCU,"\\HKEY_CURRENT_USER")
|
||||
func_winreg_OpenHive(HKLM,"\\HKEY_LOCAL_MACHINE")
|
||||
func_winreg_OpenHive(HKPD,"\\HKEY_PERFORMANCE_DATA")
|
||||
func_winreg_OpenHive(HKU,"\\HKEY_USERS")
|
||||
func_winreg_OpenHive(HKCC,"\\HKEY_CC")
|
||||
func_winreg_OpenHive(HKDD,"\\HKEY_DD")
|
||||
func_winreg_OpenHive(HKPT,"\\HKEY_PT")
|
||||
func_winreg_OpenHive(HKPN,"\\HKEY_PN")
|
||||
|
||||
/*
|
||||
winreg_CloseKey
|
||||
@ -120,7 +97,15 @@ static NTSTATUS winreg_OpenHKU(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
|
||||
static NTSTATUS winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_CloseKey *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||
if(!h) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
reg_key_free((REG_KEY *)h->data);
|
||||
dcesrv_handle_destroy(dce_call->conn, h);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -130,7 +115,25 @@ static NTSTATUS winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *
|
||||
static NTSTATUS winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_CreateKey *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||
WERROR error;
|
||||
REG_KEY *parent;
|
||||
if(!h) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
parent = h->data;
|
||||
error = reg_key_add_name_recursive(parent, r->in.key.name);
|
||||
if(W_ERROR_IS_OK(error)) {
|
||||
struct dcesrv_handle *newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||
error = reg_open_key(parent, r->in.key.name, (REG_KEY **)&newh->data);
|
||||
if(W_ERROR_IS_OK(error)) r->out.handle = &newh->wire_handle;
|
||||
else dcesrv_handle_destroy(dce_call->conn, newh);
|
||||
}
|
||||
|
||||
r->out.result = error;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -140,7 +143,19 @@ static NTSTATUS winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
||||
static NTSTATUS winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_DeleteKey *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||
REG_KEY *parent, *key;
|
||||
WERROR error;
|
||||
if(!h) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
parent = h->data;
|
||||
r->out.result = reg_open_key(parent, r->in.key.name, &key);
|
||||
if(W_ERROR_IS_OK(r->out.result)) {
|
||||
r->out.result = reg_key_del(key);
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -160,6 +175,14 @@ static NTSTATUS winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CT
|
||||
static NTSTATUS winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_EnumKey *r)
|
||||
{
|
||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||
REG_KEY *key;
|
||||
if(!h) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
key = h->data;
|
||||
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -221,11 +244,22 @@ static NTSTATUS winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
|
||||
struct winreg_OpenKey *r)
|
||||
{
|
||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||
REG_KEY *k, *subkey;
|
||||
if(!h) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
k = h->data;
|
||||
|
||||
|
||||
r->out.result = reg_open_key(k, r->in.keyname.name, &subkey);
|
||||
if(W_ERROR_IS_OK(r->out.result)) {
|
||||
struct dcesrv_handle *newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||
h->data = subkey;
|
||||
r->out.handle = &h->wire_handle;
|
||||
}
|
||||
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -339,26 +373,6 @@ static NTSTATUS winreg_GetVersion(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKCC
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKCC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKCC *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKDD
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKDD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKDD *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_QueryMultipleValues
|
||||
*/
|
||||
@ -389,26 +403,6 @@ static NTSTATUS winreg_SaveKeyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKPT
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKPT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKPT *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_OpenHKPN
|
||||
*/
|
||||
static NTSTATUS winreg_OpenHKPN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct winreg_OpenHKPN *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
winreg_QueryMultipleValues2
|
||||
*/
|
||||
|
@ -54,27 +54,24 @@ static BOOL test_GetVersion(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
static BOOL test_CreateKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, const char *name, const char *class)
|
||||
struct policy_handle *handle, char *name, const char *class)
|
||||
{
|
||||
struct winreg_CreateKey r;
|
||||
struct policy_handle newhandle;
|
||||
NTSTATUS status;
|
||||
struct sec_desc_buf sec_desc;
|
||||
uint32 sec_info = 0;
|
||||
|
||||
printf("\ntesting CreateKey\n");
|
||||
|
||||
r.in.handle = handle;
|
||||
r.out.handle = &newhandle;
|
||||
init_winreg_String(&r.in.key, name);
|
||||
init_winreg_String(&r.in.class, class);
|
||||
init_winreg_String(&r.in.class, class);
|
||||
r.in.reserved = 0x0;
|
||||
r.in.reserved2 = 0x0;
|
||||
r.in.access_mask = 0x02000000;
|
||||
r.out.reserved = 0x0;
|
||||
r.in.sec_info = 0x0;
|
||||
sec_desc.size = 0;
|
||||
sec_desc.sd = NULL;
|
||||
r.in.sec_desc = &sec_desc;
|
||||
r.in.sec_info = &sec_info;
|
||||
r.in.sec_desc = NULL;
|
||||
|
||||
status = dcerpc_winreg_CreateKey(p, mem_ctx, &r);
|
||||
|
||||
@ -148,6 +145,11 @@ static BOOL test_OpenKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
|
||||
status = dcerpc_winreg_OpenKey(p, mem_ctx, &r);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenKey failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(r.out.result)) {
|
||||
printf("OpenKey failed - %s\n", win_errstr(r.out.result));
|
||||
return False;
|
||||
@ -195,6 +197,11 @@ static BOOL test_QueryInfoKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
|
||||
status = dcerpc_winreg_QueryInfoKey(p, mem_ctx, &r);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("QueryInfoKey failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(r.out.result)) {
|
||||
printf("QueryInfoKey failed - %s\n", win_errstr(r.out.result));
|
||||
return False;
|
||||
@ -371,6 +378,53 @@ static BOOL test_OpenHKCR(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
const char *msg, uint32 timeout)
|
||||
{
|
||||
struct winreg_InitiateSystemShutdown r;
|
||||
NTSTATUS status;
|
||||
|
||||
init_winreg_String(&r.in.message, msg);
|
||||
r.in.flags = 0;
|
||||
r.in.timeout = timeout;
|
||||
|
||||
status = dcerpc_winreg_InitiateSystemShutdown(p, mem_ctx, &r);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("InitiateSystemShutdown failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(r.out.result)) {
|
||||
printf("InitiateSystemShutdown failed - %s\n", win_errstr(r.out.result));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL test_AbortSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct winreg_AbortSystemShutdown r;
|
||||
NTSTATUS status;
|
||||
|
||||
r.in.server = 0x0;
|
||||
|
||||
status = dcerpc_winreg_AbortSystemShutdown(p, mem_ctx, &r);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("AbortSystemShutdown failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(r.out.result)) {
|
||||
printf("AbortSystemShutdown failed - %s\n", win_errstr(r.out.result));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL test_OpenHKCU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle)
|
||||
{
|
||||
@ -433,17 +487,7 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
|
||||
if (!open_fn(p, mem_ctx, &handle))
|
||||
return False;
|
||||
|
||||
if (!test_GetVersion(p, mem_ctx, &handle)) {
|
||||
printf("GetVersion failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_FlushKey(p, mem_ctx, &handle)) {
|
||||
printf("FlushKey failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", "foo")) {
|
||||
if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", NULL)) {
|
||||
printf("CreateKey failed\n");
|
||||
ret = False;
|
||||
}
|
||||
@ -463,6 +507,16 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_GetVersion(p, mem_ctx, &handle)) {
|
||||
printf("GetVersion failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_FlushKey(p, mem_ctx, &handle)) {
|
||||
printf("FlushKey failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
|
||||
/* The HKCR hive has a very large fanout */
|
||||
|
||||
@ -482,7 +536,7 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
|
||||
BOOL torture_rpc_winreg(int dummy)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct dcerpc_pipe *p;
|
||||
struct dcerpc_pipe *p;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
winreg_open_fn *open_fns[] = { test_OpenHKLM, test_OpenHKU,
|
||||
@ -500,6 +554,9 @@ BOOL torture_rpc_winreg(int dummy)
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!test_InitiateSystemShutdown(p, mem_ctx, "spottyfood", 30))
|
||||
ret = False;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
|
||||
if (!test_Open(p, mem_ctx, open_fns[i]))
|
||||
ret = False;
|
||||
|
Loading…
x
Reference in New Issue
Block a user