1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-01 04:58:35 +03:00

r168: - Cleanups in rpc backend

- Small fixess in nt4 and dir backends
- Start on w95 file backend
(This used to be commit aa739e8d3c7108f6f2089af2d8d522feacc7f698)
This commit is contained in:
Jelmer Vernooij 2004-04-11 23:16:47 +00:00 committed by Gerald (Jerry) Carter
parent c60c5ebb91
commit 639afabf40
9 changed files with 317 additions and 198 deletions

View File

@ -214,7 +214,11 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
{
if(!key) return WERR_INVALID_PARAM;
if(!key->handle->functions->num_subkeys) {
if(key->handle->functions->num_subkeys) {
return key->handle->functions->num_subkeys(key, count);
}
if(key->handle->functions->fetch_subkeys) {
if(!key->cache_subkeys)
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
@ -222,7 +226,20 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
return WERR_OK;
}
return key->handle->functions->num_subkeys(key, count);
if(key->handle->functions->get_subkey_by_index) {
int i;
WERROR error;
REG_KEY *dest;
for(i = 0; W_ERROR_IS_OK(error = key->handle->functions->get_subkey_by_index(key, i, &dest)); i++) {
reg_key_free(dest);
}
*count = i;
if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK;
return error;
}
return WERR_NOT_SUPPORTED;
}
WERROR reg_key_num_values(REG_KEY *key, int *count)
@ -306,8 +323,7 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk
WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
{
int i, max;
REG_VAL *ret = NULL;
int i;
WERROR error = WERR_OK;
if(!key) return WERR_INVALID_PARAM;
@ -361,7 +377,6 @@ WERROR reg_sync(REG_KEY *h, const char *location)
WERROR reg_key_del_recursive(REG_KEY *key)
{
BOOL succeed = True;
WERROR error = WERR_OK;
int i;
@ -543,3 +558,27 @@ WERROR reg_save(REG_HANDLE *h, const char *location)
/* FIXME */
return WERR_NOT_SUPPORTED;
}
WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent)
{
char *parent_name;
char *last;
REG_KEY *root;
WERROR error;
error = reg_get_root(key->handle, &root);
if(!W_ERROR_IS_OK(error)) return error;
parent_name = strdup(reg_key_get_path(key));
last = strrchr(parent_name, '\\');
if(!last) {
SAFE_FREE(parent_name);
return WERR_FOOBAR;
}
*last = '\0';
error = reg_open_key(root, parent_name, parent);
SAFE_FREE(parent_name);
return error;
}

View File

@ -58,8 +58,8 @@ struct reg_val_s {
};
/* FIXME */
typedef void (*key_notification_function) ();
typedef void (*value_notification_function) ();
typedef void (*key_notification_function) (void);
typedef void (*value_notification_function) (void);
/*

View File

@ -11,6 +11,7 @@ PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC)
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_w95, REG, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.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])

View File

@ -21,7 +21,7 @@
#include "includes.h"
#include "lib/registry/common/registry.h"
static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc)
static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **result)
{
char *path;
int ret;
@ -29,7 +29,7 @@ static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_m
path = reg_path_win2unix(path);
ret = mkdir(path, 0700);
SAFE_FREE(path);
if(ret == 0)return WERR_OK;
if(ret == 0)return WERR_OK; /* FIXME */
return WERR_INVALID_PARAM;
}
@ -83,7 +83,6 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
if(e->d_type == DT_DIR &&
strcmp(e->d_name, ".") &&
strcmp(e->d_name, "..")) {
char *newfullpath;
ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL);
ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name);
if(ar[(*count)])(*count)++;
@ -106,16 +105,8 @@ static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentia
return WERR_OK;
}
static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value)
static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
{
char *fullpath;
FILE *fd;
*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 WERR_NOT_SUPPORTED;
}

View File

@ -165,7 +165,7 @@ Offset Size Contents
To determine the number of values, you have to look at the owner-nk-record!
Der vk-Record
The vk-Record
=============
Offset Size Contents
0x0000 Word ID: ASCII-"vk" = 0x6B76
@ -473,7 +473,7 @@ typedef struct regf_struct_s {
int fd;
struct stat sbuf;
char *base;
int modified;
BOOL modified;
NTTIME last_mod_time;
NK_HDR *first_key;
int sk_count, sk_map_size;
@ -485,7 +485,6 @@ typedef struct regf_struct_s {
* keys when we are preparing to write them to a file
*/
HBIN_BLK *blk_head, *blk_tail, *free_space;
TALLOC_CTX *mem_ctx;
} REGF;
DWORD str_to_dword(const char *a) {
@ -886,7 +885,6 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val
char val_name[1024];
REGF *regf = parent->handle->backend_data;
int nam_len, dat_len, flag, dat_type, dat_off, vk_id;
const char *val_type;
REG_VAL *tmp = NULL;
if (!vk_hdr) return WERR_INVALID_PARAM;
@ -1021,7 +1019,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
{
REGF *regf = h->backend_data;
REG_KEY *tmp = NULL, *own;
int name_len, clsname_len, sk_off, own_off;
int namlen, clsname_len, sk_off, own_off;
unsigned int nk_id;
SK_HDR *sk_hdr;
int type;
@ -1037,32 +1035,32 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
SMB_REG_ASSERT(size < 0);
name_len = SVAL(&nk_hdr->nam_len,0);
namlen = SVAL(&nk_hdr->nam_len,0);
clsname_len = SVAL(&nk_hdr->clsnam_len,0);
/*
* The value of -size should be ge
* (sizeof(NK_HDR) - 1 + name_len)
* (sizeof(NK_HDR) - 1 + namlen)
* The -1 accounts for the fact that we included the first byte of
* the name in the structure. clsname_len is the length of the thing
* pointed to by clsnam_off
*/
if (-size < (sizeof(NK_HDR) - 1 + name_len)) {
if (-size < (sizeof(NK_HDR) - 1 + namlen)) {
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));
sizeof(NK_HDR), namlen, clsname_len));
return WERR_GENERAL_FAILURE;
}
DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len));
DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len));
/* Fish out the key name and process the LF list */
SMB_REG_ASSERT(name_len < sizeof(key_name));
SMB_REG_ASSERT(namlen < sizeof(key_name));
strncpy(key_name, nk_hdr->key_nam, name_len);
key_name[name_len] = '\0';
strncpy(key_name, nk_hdr->key_nam, namlen);
key_name[namlen] = '\0';
type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
if(type == REG_ROOT_KEY && parent) {
@ -1088,7 +1086,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off);
DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off));
tmp->class_name = talloc_strdup_w(regf->mem_ctx, clsnamep);
tmp->class_name = talloc_strdup_w(h->mem_ctx, clsnamep);
DEBUGADD(2,(" Class Name: %s\n", cls_name));
@ -1572,22 +1570,17 @@ static WERROR nt_close_registry (REG_HANDLE *h)
regf->base = NULL;
close(regf->fd); /* Ignore the error :-) */
free(regf->sk_map);
regf->sk_count = regf->sk_map_size = 0;
free(regf);
return WERR_OK;
}
static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials)
{
REGF *regf = (REGF *)malloc(sizeof(REGF));
REGF *regf = (REGF *)talloc_p(h->mem_ctx, REGF);
REGF_HDR *regf_hdr;
unsigned int regf_id, hbin_id;
HBIN_HDR *hbin_hdr;
memset(regf, 0, sizeof(REGF));
regf->mem_ctx = talloc_init("regf");
regf->owner_sid_str = credentials;
h->backend_data = regf;

View File

@ -20,6 +20,13 @@
#include "includes.h"
#include "lib/registry/common/registry.h"
/**
* This is the RPC backend for the registry library.
*
* This backend is a little special. The root key is 'virtual'. All
* of its subkeys are the hives available on the remote server.
*/
static void init_winreg_String(struct winreg_String *name, const char *s)
{
name->name = s;
@ -35,7 +42,6 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
#define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \
{ \
NTSTATUS status; \
struct winreg_Open ## u r; \
struct winreg_OpenUnknown unknown; \
struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \
@ -66,7 +72,7 @@ struct rpc_data {
};
struct {
char *name;
const char *name;
struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h);
} known_hives[] = {
{ "HKEY_LOCAL_MACHINE", open_HKLM },
@ -98,7 +104,6 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char
lp_workgroup(),
user, pass);
h->backend_data = mydata;
return ntstatus_to_werror(status);
@ -118,64 +123,66 @@ static WERROR rpc_close_registry(REG_HANDLE *h)
return WERR_OK;
}
static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
static WERROR rpc_key_put_policy_handle(REG_KEY *k)
{
char *hivename;
int i = 0;
struct rpc_data *mydata = h->backend_data;
struct policy_handle *hive = NULL;
char *end = strchr(path+1, '\\');
NTSTATUS status;
struct policy_handle *key_handle, *hive = NULL;
struct winreg_OpenKey r;
struct policy_handle *key_handle = talloc(h->mem_ctx, sizeof(struct policy_handle));
TALLOC_CTX *mem_ctx;
int i;
struct rpc_data *mydata = k->handle->backend_data;
char *realkeyname, *hivename;
if(k->backend_data) return WERR_OK;
if(end) hivename = strndup(path+1, end-path-1);
else hivename = strdup(path+1);
/* First, ensure the handle to the hive is opened */
realkeyname = strchr(k->path, '\\');
if(realkeyname) hivename = strndup(k->path+1, realkeyname-k->path-1);
else hivename = strdup(k->path+1);
for(i = 0; known_hives[i].name; i++) {
if(!strcmp(hivename, known_hives[i].name)) {
if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, h);
if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, k->handle);
hive = mydata->hives[i];
break;
}
}
if(!hive) {
DEBUG(0, ("No such hive: %s\n", hivename));
return NULL;
return WERR_FOOBAR;
}
DEBUG(2, ("Opening %s, hive: %s\n", path, hivename));
if(realkeyname[0] == '\\')realkeyname++;
if(!end || !(*end) || !(*(end+1))) return hive;
if(!realkeyname || !(*realkeyname)) {
k->backend_data = hive;
return WERR_OK;
}
key_handle = talloc(k->mem_ctx, sizeof(struct policy_handle));
/* Then, open the handle using the hive */
memset(&r, 0, sizeof(struct winreg_OpenKey));
r.in.handle = hive;
init_winreg_String(&r.in.keyname, end+1);
init_winreg_String(&r.in.keyname, realkeyname);
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = key_handle;
mem_ctx = talloc_init("openkey");
status = dcerpc_winreg_OpenKey(mydata->pipe, mem_ctx, &r);
talloc_destroy(mem_ctx);
dcerpc_winreg_OpenKey(mydata->pipe, k->mem_ctx, &r);
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
return NULL;
}
if(W_ERROR_IS_OK(r.out.result)) k->backend_data = key_handle;
return key_handle;
return r.out.result;
}
static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
{
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;
WERROR error;
*key = reg_key_new_abs(name, h, NULL);
return rpc_key_put_policy_handle(*key);
}
static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey)
{
struct winreg_EnumKey r;
struct winreg_EnumKeyNameRequest keyname;
@ -183,28 +190,22 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
struct winreg_Time tm;
struct rpc_data *mydata = parent->handle->backend_data;
int i;
REG_KEY **ar = talloc(parent->mem_ctx, sizeof(REG_KEY *));
NTSTATUS status = NT_STATUS_OK;
NTSTATUS status;
TALLOC_CTX *mem_ctx;
/* List the hives */
if(parent->backend_data == parent->handle->backend_data) {
for(i = 0; known_hives[i].name; i++) {
ar[i] = reg_key_new_rel(known_hives[i].name, parent, NULL);
(*count)++;
ar = talloc_realloc(parent->mem_ctx, ar, sizeof(REG_KEY *) * ((*count)+1));
}
/* If parent is the root key, list the hives */
if(parent->backend_data == mydata) {
if(!known_hives[n].name) return WERR_NO_MORE_ITEMS;
*subkeys = ar;
*subkey = reg_key_new_rel(known_hives[n].name, parent, known_hives[n].open(mydata->pipe, parent->handle));
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) {
rpc_key_put_policy_handle(parent);
}
if(!parent->backend_data) return WERR_GENERAL_FAILURE;
(*count) = 0;
r.in.handle = parent->backend_data;
keyname.unknown = 0x0000020a;
init_winreg_String(&keyname.key_name, NULL);
@ -215,134 +216,59 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
r.in.last_changed_time = &tm;
r.out.result.v = 0;
for(i = 0; NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result); i++) {
r.in.enum_index = i;
r.in.unknown = r.out.unknown = 0x0414;
r.in.key_name_len = r.out.key_name_len = 0;
status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
ar[(*count)] = reg_key_new_rel(r.out.out_name->name, parent, NULL);
(*count)++;
ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_KEY *));
}
r.in.enum_index = n;
r.in.unknown = r.out.unknown = 0x0414;
r.in.key_name_len = r.out.key_name_len = 0;
status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
*subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL);
}
*subkeys = ar;
return r.out.result;
}
static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
{
struct winreg_EnumValue r;
struct winreg_Uint8buf value;
struct winreg_String valuename;
struct rpc_data *mydata = parent->handle->backend_data;
TALLOC_CTX *mem_ctx;
uint32 type, requested_len, returned_len;
NTSTATUS status = NT_STATUS_OK;
REG_VAL **ar = malloc(sizeof(REG_VAL *));
(*count) = 0;
/* Root */
if(parent->backend_data == parent->handle->backend_data) {
*values = ar;
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 WERR_GENERAL_FAILURE;
r.in.handle = parent->backend_data;
r.in.enum_index = 0;
init_winreg_String(&valuename, NULL);
r.in.name = r.out.name = &valuename;
type = 0;
r.in.type = r.out.type = &type;
value.max_len = 0x7fff;
value.offset = 0;
value.len = 0;
value.buffer = NULL;
r.in.value = r.out.value = &value;
requested_len = value.max_len;
r.in.requested_len = &requested_len;
returned_len = 0;
r.in.returned_len = &returned_len;
r.out.result.v = 0;
while(1) {
status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r);
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
r.in.enum_index++;
ar[(*count)] = reg_val_new(parent, NULL);
ar[(*count)]->name = talloc_strdup(ar[*count]->mem_ctx, r.out.name->name);
ar[(*count)]->data_type = *r.out.type;
ar[(*count)]->data_len = value.len;
ar[(*count)]->data_blk = talloc(ar[*count]->mem_ctx, value.len);
memcpy(ar[(*count)]->data_blk, value.buffer, value.len);
(*count)++;
ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_VAL *));
} else break;
}
*values = ar;
return r.out.result;
}
static WERROR rpc_add_key(REG_KEY *parent, const char *name)
static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key)
{
rpc_key_put_policy_handle(parent);
/* FIXME */
return WERR_NOT_SUPPORTED;
}
static struct policy_handle*get_hive(REG_KEY *k)
{
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 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);
REG_KEY *parent;
WERROR error = reg_key_get_parent(k, &parent);
if(!W_ERROR_IS_OK(error)) return error;
rpc_key_put_policy_handle(parent);
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);
r.in.handle = parent->backend_data;
init_winreg_String(&r.in.key, k->name);
status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r);
return r.out.result;
}
static void rpc_close_key(REG_KEY *k)
{
reg_key_free(k);
}
static struct registry_ops reg_backend_rpc = {
.name = "rpc",
.open_registry = rpc_open_registry,
.close_registry = rpc_close_registry,
.open_root_key = rpc_open_root,
.open_key = rpc_open_key,
.fetch_subkeys = rpc_fetch_subkeys,
.fetch_values = rpc_fetch_values,
.get_subkey_by_index = rpc_get_subkey_by_index,
.add_key = rpc_add_key,
.del_key = rpc_del_key,
.free_key_backend_data = rpc_close_key,
};
NTSTATUS reg_rpc_init(void)

View File

@ -0,0 +1,170 @@
/*
Samba Unix/Linux SMB client utility libeditreg.c
Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
Backend for Windows '95 registry files. Explanation of file format
comes from http://www.cs.mun.ca/~michael/regutils/.
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. */
#include "includes.h"
#include "lib/registry/common/registry.h"
/**
* The registry starts with a header that contains pointers to
* the rgdb.
*
* After the main header follows the RGKN header (key index table) */
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef struct regc_block {
DWORD REGC_ID; /* REGC */
DWORD uk1;
DWORD rgdb_offset;
DWORD chksum;
WORD num_rgdb;
WORD flags;
DWORD uk2;
DWORD uk3;
DWORD uk4;
DWORD uk5;
} REGC_HDR;
typedef struct rgkn_block {
DWORD RGKN_ID; /* RGKN */
DWORD size;
DWORD root_offset;
DWORD free_offset;
DWORD flags;
DWORD chksum;
DWORD uk1;
DWORD uk2;
} RGKN_HDR;
typedef struct rgkn_key {
DWORD inuse;
DWORD hash;
DWORD next_free;
DWORD parent;
DWORD child;
DWORD next;
WORD id;
WORD rgdb;
} RGKN_KEY;
typedef struct rgdb_block {
DWORD RGDB_ID; /* RGDB */
DWORD size;
DWORD unused_size;
WORD flags;
WORD section;
DWORD free_offset; /* -1 if there is no free space */
WORD max_id;
WORD first_free_id;
DWORD uk1;
DWORD chksum;
} RGDB_HDR;
typedef struct rgdb_key {
DWORD inuse;
DWORD hash;
DWORD next_free;
DWORD parent;
DWORD child;
DWORD next;
WORD id;
WORD rgdb;
} RGDB_KEY;
typedef struct rgdb_value {
DWORD type;
DWORD uk1;
DWORD name_len;
DWORD data_len;
} RGDB_VALUE;
typedef struct regc_struct_s {
int fd;
struct stat sbuf;
BOOL modified;
char *base;
} REGC;
static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials)
{
REGC *regc = talloc_p(h->mem_ctx, REGC);
REGC_HDR *regc_hdr;
RGKN_HDR *rgkn_hdr;
DWORD regc_id, rgkn_id;
memset(regc, 0, sizeof(REGC));
h->backend_data = regc;
if((regc->fd = open(location, O_RDONLY, 0000)) < 0) {
return WERR_FOOBAR;
}
if(fstat(regc->fd, &regc->sbuf) < 0) {
return WERR_FOOBAR;
}
regc->base = mmap(0, regc->sbuf.st_size, PROT_READ, MAP_SHARED, regc->fd, 0);
regc_hdr = (REGC_HDR *)regc->base;
if ((int)regc->base == 1) {
return WERR_FOOBAR;
}
if ((regc_id = IVAL(&regc_hdr->REGC_ID,0)) != str_to_dword("REGC")) {
DEBUG(0, ("Unrecognized Windows 95 registry header id: %0X, %s\n",
regc_id, location));
return WERR_FOOBAR;
}
rgkn_hdr = (RGKN_HDR *)regc->base + sizeof(REGC_HDR);
if ((rgkn_id = IVAL(&rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) {
DEBUG(0, ("Unrecognized Windows 95 registry key index id: %0X, %s\n",
rgkn_id, location));
return WERR_FOOBAR;
}
//rgkn = (RGKN_KEY *)regc->base + sizeof(REGC_HDR) + sizeof(RGKN_HDR);
/* FIXME */
return WERR_OK;
}
static WERROR w95_close_reg(REG_HANDLE *h)
{
REGC *regc = h->backend_data;
if (regc->base) munmap(regc->base, regc->sbuf.st_size);
regc->base = NULL;
close(regc->fd);
return WERR_OK;
}
static struct registry_ops reg_backend_w95 = {
.name = "w95",
.open_registry = w95_open_reg,
.close_registry = w95_close_reg,
};
NTSTATUS reg_w95_init(void)
{
return register_backend("registry", &reg_backend_w95);
}

View File

@ -84,6 +84,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
g_assert(k);
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
int count;
/* 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
@ -103,14 +104,8 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
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_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0)
gtk_tree_store_append(store_keys, &tmpiter, &iter);
}
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);

View File

@ -493,6 +493,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False;
}
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
printf("CreateKey failed (OpenKey after Create didn't work)\n");
ret = False;
@ -503,6 +508,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False;
}
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
ret = False;
@ -513,12 +523,6 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False;
}
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
/* The HKCR hive has a very large fanout */
if (open_fn == test_OpenHKCR) {