Author: jelmer
Date: 2007-08-04 13:13:40 +0000 (Sat, 04 Aug 2007)
New Revision: 24179

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24179

Log:
Improvements towards write support for regf by Jelmer Vernooij and me.

Modified:
   branches/4.0-regwrite/
   branches/4.0-regwrite/source/lib/policy/parse_adm.y
   branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c
   branches/4.0-regwrite/source/lib/registry/regf.idl


Changeset:

Property changes on: branches/4.0-regwrite
___________________________________________________________________
Name: bzr:revision-info
   - timestamp: Sun 2007-01-14 14:43:18.105000019 +0100
committer: Wilco Baan Hofman <[EMAIL PROTECTED]>
properties: 
        branch-nick: 4.0-regwrite
        rebase-of: [EMAIL PROTECTED]

   + timestamp: Sun 2007-01-14 16:15:41.398000002 +0100
committer: Wilco Baan Hofman <[EMAIL PROTECTED]>
properties: 
        branch-nick: 4.0-regwrite
        rebase-of: [EMAIL PROTECTED]

Name: bzr:file-ids
   - source/script/tests/test_blackbox.sh       [EMAIL 
PROTECTED]:branches%2FSAMBA_4_0:source%2Fscript%2Ftests%2Ftest_blackbox.sh
testprogs/blackbox      [EMAIL 
PROTECTED]:branches%2FSAMBA_4_0:testprogs%2Fblackbox
testprogs/blackbox/test_smbclient.sh    [EMAIL 
PROTECTED]:branches%2FSAMBA_4_0:testprogs%2Fblackbox%2Ftest_smbclient.sh
testprogs/blackbox/test_cifsdd.sh       [EMAIL 
PROTECTED]:branches%2FSAMBA_4_0:testprogs%2Fblackbox%2Ftest_cifsdd.sh

   + 
Name: bzr:revision-id:v3-trunk0
   - 11140 [EMAIL PROTECTED]
11142 [EMAIL PROTECTED]
11143 [EMAIL PROTECTED]
11144 [EMAIL PROTECTED]
11145 [EMAIL PROTECTED]
11146 [EMAIL PROTECTED]
11147 [EMAIL PROTECTED]
11148 [EMAIL PROTECTED]
11149 [EMAIL PROTECTED]
11150 [EMAIL PROTECTED]
11151 [EMAIL PROTECTED]

   + 11140 [EMAIL PROTECTED]
11142 [EMAIL PROTECTED]
11143 [EMAIL PROTECTED]
11144 [EMAIL PROTECTED]
11145 [EMAIL PROTECTED]
11146 [EMAIL PROTECTED]
11147 [EMAIL PROTECTED]
11148 [EMAIL PROTECTED]
11149 [EMAIL PROTECTED]
11150 [EMAIL PROTECTED]
11151 [EMAIL PROTECTED]
11152 [EMAIL PROTECTED]


Modified: branches/4.0-regwrite/source/lib/policy/parse_adm.y
===================================================================
--- branches/4.0-regwrite/source/lib/policy/parse_adm.y 2007-08-04 13:13:30 UTC 
(rev 24178)
+++ branches/4.0-regwrite/source/lib/policy/parse_adm.y 2007-08-04 13:13:40 UTC 
(rev 24179)
@@ -23,8 +23,10 @@
 
 %{
 #include "config.h"
-
+void error_message (const char *format, ...);
+int yyparse (void);
 void yyerror (const char *s);
+extern int yylex (void);
 
 %}
 

Modified: branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c
===================================================================
--- branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c        
2007-08-04 13:13:30 UTC (rev 24178)
+++ branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c        
2007-08-04 13:13:40 UTC (rev 24179)
@@ -30,6 +30,7 @@
  *  - Locking
  */
 
+static WERROR regf_save_hbin(struct registry_hive *hive);
 /*
  * Read HBIN blocks into memory
  */
@@ -40,6 +41,11 @@
        struct regf_hdr *header;
 };
 
+struct regf_key_data {
+       uint32_t offset;
+       struct nk_block *nk;
+};
+
 static struct hbin_block *hbin_by_offset (const struct regf_data *data, 
uint32_t offset, uint32_t *rel_offset)
 {
        int i;
@@ -48,7 +54,7 @@
                if (offset >= data->hbins[i]->offset_from_first && 
                        offset < data->hbins[i]->offset_from_first+
                                         data->hbins[i]->offset_to_next) {
-                       if (rel_offset)
+                       if (rel_offset != NULL)
                                *rel_offset = offset - 
data->hbins[i]->offset_from_first - 0x20;
                        return data->hbins[i];
                }
@@ -148,10 +154,10 @@
 
        for (i = 0; (hbin = data->hbins[i]); i++) {
                int j;
-               uint32_t my_size;
+               int32_t my_size;
                for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) {
                        uint32_t header = IVAL(hbin->data, j + 4);
-                       my_size = IVAL(hbin->data, j);
+                       my_size = IVALS(hbin->data, j);
 
                        if (my_size == 0x0) {
                                DEBUG(0, ("Invalid zero-length block! File is 
corrupt.\n"));
@@ -162,9 +168,9 @@
                                DEBUG(0, ("Encountered non-aligned block!\n"));
                        }
 
-                       if (my_size & 0x80000000) { /* Used... */
-                               my_size = (my_size ^ 0xffffffff) + 1;
-                       } else if (my_size == size) { /* exact match */
+                       if (my_size < 0) { /* Used... */
+                               my_size = -my_size;
+                       } else if (-my_size == size) { /* exact match */
                                rel_offset = j;
                                DEBUG(4, ("Found free block of exact size %d in 
middle of HBIN\n", size));
                                break;
@@ -219,7 +225,7 @@
        }
 
        /* Set size and mark as used */
-       SIVAL(hbin->data, rel_offset, size | 0x80000000);
+       SIVAL(hbin->data, rel_offset, -size);
 
        ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */
        ret.length = size - 0x4;
@@ -265,7 +271,7 @@
 /* Free existing data */
 static void hbin_free (struct regf_data *data, uint32_t offset)
 {
-       uint32_t size;
+       int32_t size;
        uint32_t rel_offset;
        struct hbin_block *hbin;
 
@@ -277,28 +283,28 @@
                return;
        
        /* Get original size */
-       size = IVAL(hbin->data, rel_offset);
+       size = IVALS(hbin->data, rel_offset);
 
-       if (!(size & 0x80000000)) {
+       if (size > 0) {
                DEBUG(1, ("Trying to free already freed block at 0x%04x\n", 
offset));
                return;
        }
 
        /* Mark block as free */
-       SIVAL(hbin->data, rel_offset, size &~ 0x80000000);
+       SIVALS(hbin->data, rel_offset, -size);
 }
 
-/* Store a data blob data was already stored, but hsa changed in size
+/* Store a data blob data was already stored, but has changed in size
  * Will try to save it at the current location if possible, otherwise 
  * does a free + store */
 static uint32_t hbin_store_resize (struct regf_data *data, uint32_t 
orig_offset, DATA_BLOB blob)
 {
        uint32_t rel_offset;
        struct hbin_block *hbin = hbin_by_offset(data, orig_offset, 
&rel_offset);
-       uint32_t my_size;
-       uint32_t orig_size;
-       uint32_t needed_size;
-       uint32_t possible_size;
+       int32_t my_size;
+       int32_t orig_size;
+       int32_t needed_size;
+       int32_t possible_size;
        int i;
 
        SMB_ASSERT(orig_offset > 0);
@@ -307,7 +313,7 @@
                return hbin_store(data, blob);
 
        /* Get original size */
-       orig_size = IVAL(hbin->data, rel_offset);
+       orig_size = IVALS(hbin->data, rel_offset);
 
        needed_size = blob.length + 4; /* Add uint32 containing length */
        needed_size = (needed_size + 7) & ~7; /* Align */
@@ -321,14 +327,12 @@
        possible_size = orig_size;
 
        /* Check if it can be combined with the next few free records */
-       for (i = rel_offset; 
-                i < hbin->offset_to_next - 0x20; 
-                i += my_size) {
+       for (i = rel_offset; i < hbin->offset_to_next - 0x20; i += my_size) {
                uint32_t header;
-               if (IVAL(hbin->data, i) & 0x80000000) /* Used */
+               if (IVALS(hbin->data, i) < 0) /* Used */
                        break;
 
-               my_size = IVAL(hbin->data, i);
+               my_size = IVALS(hbin->data, i);
                header = IVAL(hbin->data, i + 4);
                if (header == 0xffffffff) {
                        possible_size = hbin->offset_to_next - 0x20 - 
rel_offset;
@@ -340,7 +344,7 @@
                }
 
                if (possible_size >= blob.length) {
-                       SIVAL(hbin->data, rel_offset, possible_size);
+                       SIVAL(hbin->data, rel_offset, -possible_size);
                        memcpy(hbin->data + rel_offset + 0x4, blob.data, 
blob.length);
                        return orig_offset;
                }
@@ -372,18 +376,18 @@
 
 static WERROR regf_num_subkeys (const struct registry_key *key, uint32_t 
*count)
 {
-       struct nk_block *nk = key->backend_data;
+       struct regf_key_data *private_data = key->backend_data;
 
-       *count = nk->num_subkeys;
+       *count = private_data->nk->num_subkeys;
        
        return WERR_OK;
 }
 
 static WERROR regf_num_values (const struct registry_key *key, uint32_t *count)
 {
-       struct nk_block *nk = key->backend_data;
+       struct regf_key_data *private_data = key->backend_data;
 
-       *count = nk->num_values;
+       *count = private_data->nk->num_values;
 
        return WERR_OK;
 }
@@ -392,9 +396,13 @@
 {
        struct registry_key *ret;
        struct nk_block *nk;
+       struct regf_key_data *private_data;
 
        ret = talloc_zero(ctx, struct registry_key);
+       private_data = talloc_zero(ret, struct regf_key_data);
+       private_data->offset = offset;
        nk = talloc(ret, struct nk_block);
+       private_data->nk = nk;
        if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, 
nk)) {
                DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
                return NULL;
@@ -413,29 +421,29 @@
                DATA_BLOB data = hbin_get(regf, nk->clsname_offset);
                ret->class_name = talloc_strndup(ret, (char*)data.data, 
nk->clsname_length);
        }
-       ret->backend_data = nk;
+       ret->backend_data = private_data;
 
        return ret;
 }
 
 static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, 
int idx, struct registry_value **ret)
 {
-       struct nk_block *nk = key->backend_data;
+       struct regf_key_data *private_data = key->backend_data;
        struct vk_block *vk;
        struct regf_data *regf = key->hive->backend_data;
        uint32_t vk_offset;
        DATA_BLOB data;
 
-       if (idx >= nk->num_values)
+       if (idx >= private_data->nk->num_values)
                return WERR_NO_MORE_ITEMS;
 
-       data = hbin_get(regf, nk->values_offset);
+       data = hbin_get(regf, private_data->nk->values_offset);
        if (!data.data) {
                DEBUG(0, ("Unable to find value list\n"));
                return WERR_GENERAL_FAILURE;
        }
 
-       if (data.length < nk->num_values * 4) {
+       if (data.length < private_data->nk->num_values * 4) {
                DEBUG(1, ("Value counts mismatch\n"));
        }
 
@@ -474,7 +482,8 @@
 static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, const struct 
registry_key *key, int idx, struct registry_key **ret)
 {
        DATA_BLOB data;
-       struct nk_block *nk = key->backend_data;
+       struct regf_key_data *private_data = key->backend_data;
+       struct nk_block *nk = private_data->nk;
        uint32_t key_off=0;
 
        if (idx >= nk->num_subkeys)
@@ -663,7 +672,8 @@
 static WERROR regf_get_subkey_by_name (TALLOC_CTX *ctx, const struct 
registry_key *key, const char *name, struct registry_key **ret)
 {
        DATA_BLOB data;
-       struct nk_block *nk = key->backend_data;
+       struct regf_key_data *private_data = key->backend_data;
+       struct nk_block *nk = private_data->nk;
        uint32_t key_off = 0;
 
        data = hbin_get(key->hive->backend_data, nk->subkeys_offset);
@@ -871,12 +881,12 @@
 
 static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key 
*key, struct security_descriptor **sd)
 {
-       struct nk_block *nk = key->backend_data;
+       struct regf_key_data *private_data = key->backend_data;
        struct sk_block sk;
        struct regf_data *regf = key->hive->backend_data;
        DATA_BLOB data;
 
-       if (!hbin_get_tdr(regf, nk->sk_offset, ctx, (tdr_pull_fn_t) 
tdr_pull_sk_block, &sk)) {
+       if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, 
(tdr_pull_fn_t) tdr_pull_sk_block, &sk)) {
                DEBUG(0, ("Unable to find security descriptor\n"));
                return WERR_GENERAL_FAILURE;
        }
@@ -938,11 +948,11 @@
 
 static WERROR regf_del_key (const struct registry_key *parent, const char 
*name)
 {
-       struct nk_block *nk = parent->backend_data;
+       struct regf_key_data *private_data = parent->backend_data;
 
-       SMB_ASSERT(nk);
+       SMB_ASSERT(private_data);
        
-       if (nk->subkeys_offset == -1) 
+       if (private_data->nk->subkeys_offset == -1) 
                return WERR_BADFILE;
 
        /* FIXME */
@@ -950,9 +960,11 @@
        return WERR_NOT_SUPPORTED;
 }
 
-static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key 
*parent, const char *name, uint32_t access_mask, struct security_descriptor 
*sec_desc, struct registry_key **ret)
+static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key 
*parent, const char *name, 
+                            uint32_t access_mask, struct security_descriptor 
*sec_desc, struct registry_key **ret)
 {
-       struct nk_block *parent_nk = parent->backend_data, nk;
+       struct regf_key_data *private_data = parent->backend_data;
+       struct nk_block *parent_nk = private_data->nk, nk;
        struct regf_data *regf = parent->hive->backend_data;
        uint32_t offset;
 
@@ -960,13 +972,13 @@
        nk.type = REG_SUB_KEY;
        unix_to_nt_time(&nk.last_change, time(NULL));
        nk.uk1 = 0;
-       nk.parent_offset = 0; /* FIXME */
+       nk.parent_offset = private_data->offset;
        nk.num_subkeys = 0;
        nk.uk2 = 0;
        nk.subkeys_offset = -1;
        nk.unknown_offset = -1;
        nk.num_values = 0;
-       nk.sk_offset = 0;
+       nk.sk_offset = -1;
        memset(nk.unk3, 0, 5);
        nk.clsname_offset = -1;
        nk.clsname_length = 0;
@@ -974,16 +986,17 @@
        
        offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk);
 
-       parent_nk->subkeys_offset = lf_add_entry(regf, 
parent_nk->subkeys_offset, name, nk.parent_offset);
-
+       /* FIXME: Support other formats than just 'lf' */
+       parent_nk->subkeys_offset = lf_add_entry(regf, 
parent_nk->subkeys_offset, name, offset);
        parent_nk->num_subkeys++;
 
+       /* Since the subkey offset of the parent can change, store it again */
        hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, 
nk.parent_offset, parent_nk);
 
        *ret = regf_get_key(ctx, regf, offset);
 
        /* FIXME: Set sec desc ! */
-       return WERR_OK;
+       return regf_save_hbin(parent->hive);
 }
 
 static WERROR regf_set_value (const struct registry_key *key, const char 
*name, uint32_t type, const DATA_BLOB data)
@@ -993,28 +1006,35 @@
        return WERR_NOT_SUPPORTED;
 }
 
-#if 0 /* Unused */
-
-static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block 
*hbin)
+static WERROR regf_save_hbin(struct registry_hive *hive)
 {
        struct regf_data *regf = hive->backend_data;
+       int i;
 
-       /* go to right offset */
-       if (lseek(regf->fd, SEEK_SET, regf->header->data_offset + 
hbin->offset_from_first) == -1) {
+       if (lseek(regf->fd, SEEK_SET, 0) == -1) {
                DEBUG(0, ("Error lseeking in regf file\n"));
                return WERR_GENERAL_FAILURE;
        }
 
-       if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, 
(tdr_push_fn_t)tdr_push_hbin_block, hbin))) {
-               DEBUG(0, ("Error writing HBIN block\n"));       
+       if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, 
(tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) {
+               DEBUG(0, ("Error writing registry file header\n"));
                return WERR_GENERAL_FAILURE;
        }
 
+       if (lseek(regf->fd, SEEK_SET, 0x1000) == -1) {
+               DEBUG(0, ("Error lseeking to 0x1000 in regf file\n"));
+               return WERR_GENERAL_FAILURE;
+       }
+       for (i = 0; regf->hbins[i]; i++) {
+               if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, 
(tdr_push_fn_t)tdr_push_hbin_block, regf->hbins[i]))) {
+                       DEBUG(0, ("Error writing HBIN block\n"));       
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
        return WERR_OK;
 }
 
-#endif
-
 static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key)
 {
        struct regf_data *regf;

Modified: branches/4.0-regwrite/source/lib/registry/regf.idl
===================================================================
--- branches/4.0-regwrite/source/lib/registry/regf.idl  2007-08-04 13:13:30 UTC 
(rev 24178)
+++ branches/4.0-regwrite/source/lib/registry/regf.idl  2007-08-04 13:13:40 UTC 
(rev 24179)
@@ -66,7 +66,7 @@
                uint8 data[offset_to_next-0x20]; 
                /* data is filled with:
                        uint32 length;                  
-                               Negative if in used, positive otherwise
+                               Negative if in use, positive otherwise
                                Always a multiple of 8
                        uint8_t data[length];  
                                Free space marker if 0xffffffff

Reply via email to