INIT_OBJ_FILES = lib/registry/tdr_regf.o
lib/registry/tdr_regf.c: lib/registry/regf.idl
- @echo "Compiling lib/registry/regf.idl"
@./pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl
################################################
return ret;
}
-static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, tdr_pull_fn_t pull_fn, void *p)
+static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p)
{
- DATA_BLOB data;
- struct tdr_pull *pull;
+ struct tdr_pull pull;
- data = hbin_get(regf, offset);
- if (!data.data) {
+ ZERO_STRUCT(pull);
+
+ pull.data = hbin_get(regf, offset);
+ if (!pull.data.data) {
DEBUG(1, ("Unable to get data at 0x%04x\n", offset));
return False;
}
- pull = talloc_zero(regf, struct tdr_pull);
- pull->data = data;
-
- if (NT_STATUS_IS_ERR(pull_fn(pull, p))) {
+ if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) {
DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset));
- talloc_free(pull);
return False;
}
- /* FIXME: Free pull ! */
-
return True;
}
ret = talloc_zero(ctx, struct registry_key);
nk = talloc(ret, struct nk_block);
- if (!hbin_get_tdr(regf, offset, (tdr_pull_fn_t)tdr_pull_nk_block, 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;
}
if (!vk)
return WERR_NOMEM;
- if (!hbin_get_tdr(regf, vk_offset, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) {
+ if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) {
DEBUG(0, ("Unable to get VK block at %d\n", vk_offset));
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(0);
} else if (!strncmp((char *)data.data, "lf", 2)) {
struct lf_block lf;
- struct tdr_pull *pull = talloc_zero(ctx, struct tdr_pull);
+ struct tdr_pull pull;
DEBUG(10, ("Subkeys in LF list\n"));
- pull->data = data;
+ ZERO_STRUCT(pull);
+ pull.data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, &lf))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) {
DEBUG(0, ("Error parsing LF list\n"));
return WERR_GENERAL_FAILURE;
}
}
key_off = lf.hr[idx].nk_off;
-
- talloc_free(pull);
} else if (!strncmp((char *)data.data, "ri", 2)) {
DEBUG(4, ("Subkeys in RI list\n"));
SMB_ASSERT(0);
struct regf_data *regf = key->hive->backend_data;
DATA_BLOB data;
- if (!hbin_get_tdr(regf, nk->sk_offset, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) {
+ if (!hbin_get_tdr(regf, 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;
}
lf.key_count = 0;
lf.hr = NULL;
} else {
- if (!hbin_get_tdr(regf, list_offset, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) {
+ if (!hbin_get_tdr(regf, list_offset, regf, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) {
DEBUG(0, ("Can't get subkeys list\n"));
return -1;
}
lf.key_count++;
ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf);
+
+ talloc_free(lf.hr);
return ret;
}
{
struct regf_data *regf;
struct regf_hdr *regf_hdr;
- struct tdr_pull *pull;
+ struct tdr_pull pull;
int i;
regf = (struct regf_data *)talloc_zero(h, struct regf_data);
return WERR_GENERAL_FAILURE;
}
- pull = talloc_zero(regf, struct tdr_pull);
- if (!pull)
- return WERR_NOMEM;
-
- pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, regf);
+ ZERO_STRUCT(pull);
+ pull.data.data = (uint8_t*)fd_load(regf->fd, &pull.data.length, regf);
- if (pull->data.data == NULL) {
+ if (pull.data.data == NULL) {
DEBUG(0, ("Error reading data\n"));
return WERR_GENERAL_FAILURE;
}
regf_hdr = talloc(regf, struct regf_hdr);
- if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(pull, regf_hdr))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(&pull, regf_hdr, regf_hdr))) {
return WERR_GENERAL_FAILURE;
}
/*
* Validate the header ...
*/
- if (regf_hdr_checksum(pull->data.data) != regf_hdr->chksum) {
+ if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) {
DEBUG(0, ("Registry file checksum error: %s: %d,%d\n",
- h->location, regf_hdr->chksum, regf_hdr_checksum(pull->data.data)));
+ h->location, regf_hdr->chksum, regf_hdr_checksum(pull.data.data)));
return WERR_GENERAL_FAILURE;
}
- pull->offset = 0x1000;
+ pull.offset = 0x1000;
i = 0;
/* Read in all hbin blocks */
regf->hbins = talloc_array(regf, struct hbin_block *, 1);
regf->hbins[0] = NULL;
- while (pull->offset < pull->data.length) {
+ while (pull.offset < pull.data.length) {
struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block);
- if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(pull, hbin))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) {
DEBUG(0, ("[%d] Error parsing HBIN block\n", i));
return WERR_FOOBAR;
}
- Support read/write (to fd) as well as push/pull (to DATA_BLOB)
-- Specify memory context explicitly
}
-NTSTATUS tdr_pull_uint8(struct tdr_pull *tdr, uint8_t *v)
+NTSTATUS tdr_pull_uint8(struct tdr_pull *tdr, TALLOC_CTX *ctx, uint8_t *v)
{
TDR_PULL_NEED_BYTES(tdr, 1);
*v = TDR_CVAL(tdr, tdr->offset);
return NT_STATUS_OK;
}
-NTSTATUS tdr_pull_uint16(struct tdr_pull *tdr, uint16_t *v)
+NTSTATUS tdr_pull_uint16(struct tdr_pull *tdr, TALLOC_CTX *ctx, uint16_t *v)
{
TDR_PULL_NEED_BYTES(tdr, 2);
*v = TDR_SVAL(tdr, tdr->offset);
return NT_STATUS_OK;
}
-NTSTATUS tdr_pull_uint32(struct tdr_pull *tdr, uint32_t *v)
+NTSTATUS tdr_pull_uint32(struct tdr_pull *tdr, TALLOC_CTX *ctx, uint32_t *v)
{
TDR_PULL_NEED_BYTES(tdr, 4);
*v = TDR_IVAL(tdr, tdr->offset);
return NT_STATUS_OK;
}
-NTSTATUS tdr_pull_charset(struct tdr_pull *tdr, const char **v, uint32_t length, uint32_t el_size, int chset)
+NTSTATUS tdr_pull_charset(struct tdr_pull *tdr, TALLOC_CTX *ctx, const char **v, uint32_t length, uint32_t el_size, int chset)
{
int ret;
}
if (length == 0) {
- *v = talloc_strdup(tdr, "");
+ *v = talloc_strdup(ctx, "");
return NT_STATUS_OK;
}
TDR_PULL_NEED_BYTES(tdr, el_size*length);
- ret = convert_string_talloc(tdr, chset, CH_UNIX, tdr->data.data+tdr->offset, el_size*length, discard_const_p(void *, v));
+ ret = convert_string_talloc(ctx, chset, CH_UNIX, tdr->data.data+tdr->offset, el_size*length, discard_const_p(void *, v));
if (ret == -1) {
return NT_STATUS_INVALID_PARAMETER;
/*
pull a ipv4address
*/
-NTSTATUS tdr_pull_ipv4address(struct tdr_pull *tdr, const char **address)
+NTSTATUS tdr_pull_ipv4address(struct tdr_pull *tdr, TALLOC_CTX *ctx, const char **address)
{
struct ipv4_addr in;
- TDR_CHECK(tdr_pull_uint32(tdr, &in.addr));
+ TDR_CHECK(tdr_pull_uint32(tdr, ctx, &in.addr));
in.addr = htonl(in.addr);
*address = talloc_strdup(tdr, sys_inet_ntoa(in));
NT_STATUS_HAVE_NO_MEMORY(*address);
/*
parse a hyper
*/
-NTSTATUS tdr_pull_hyper(struct tdr_pull *tdr, uint64_t *v)
+NTSTATUS tdr_pull_hyper(struct tdr_pull *tdr, TALLOC_CTX *ctx, uint64_t *v)
{
TDR_PULL_NEED_BYTES(tdr, 8);
*v = TDR_IVAL(tdr, tdr->offset);
/*
pull a NTTIME
*/
-NTSTATUS tdr_pull_NTTIME(struct tdr_pull *tdr, NTTIME *t)
+NTSTATUS tdr_pull_NTTIME(struct tdr_pull *tdr, TALLOC_CTX *ctx, NTTIME *t)
{
- TDR_CHECK(tdr_pull_hyper(tdr, t));
+ TDR_CHECK(tdr_pull_hyper(tdr, ctx, t));
return NT_STATUS_OK;
}
/*
pull a time_t
*/
-NTSTATUS tdr_pull_time_t(struct tdr_pull *tdr, time_t *t)
+NTSTATUS tdr_pull_time_t(struct tdr_pull *tdr, TALLOC_CTX *ctx, time_t *t)
{
uint32_t tt;
- TDR_CHECK(tdr_pull_uint32(tdr, &tt));
+ TDR_CHECK(tdr_pull_uint32(tdr, ctx, &tt));
*t = tt;
return NT_STATUS_OK;
}
/*
pull a DATA_BLOB from the wire.
*/
-NTSTATUS tdr_pull_DATA_BLOB(struct tdr_pull *tdr, DATA_BLOB *blob)
+NTSTATUS tdr_pull_DATA_BLOB(struct tdr_pull *tdr, TALLOC_CTX *ctx, DATA_BLOB *blob)
{
uint32_t length;
return _status; \
} while (0)
-#define TDR_ALLOC(tdr, s, n) do { \
- (s) = talloc_array_size(tdr, sizeof(*(s)), n); \
+#define TDR_ALLOC(ctx, s, n) do { \
+ (s) = talloc_array_size(ctx, sizeof(*(s)), n); \
if ((n) && !(s)) return NT_STATUS_NO_MEMORY; \
} while (0)
typedef NTSTATUS (*tdr_push_fn_t) (struct tdr_push *, const void *);
-typedef NTSTATUS (*tdr_pull_fn_t) (struct tdr_pull *, void *);
+typedef NTSTATUS (*tdr_pull_fn_t) (struct tdr_pull *, TALLOC_CTX *, void *);
sub pidl($) { $ret .= $tabs.(shift)."\n"; }
sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
sub static($) { my $p = shift; return("static ") unless ($p); return ""; }
-sub printarg($) {
+sub typearg($) {
my $t = shift;
return(", const char *name") if ($t eq "print");
+ return(", TALLOC_CTX *mem_ctx") if ($t eq "pull");
return("");
}
my $switch = "";
my $array = "";
my $name = "";
+ my $mem_ctx = "mem_ctx";
fatal($e,"Pointers not supported in TDR") if ($e->{POINTERS} > 0);
fatal($e,"size_is() not supported in TDR") if (has_property($e, "size_is"));
my $len = ParseExpr(@{$e->{ARRAY_LEN}}[0], $env);
if ($len eq "*") { $len = "-1"; }
+ $name = ", mem_ctx" if ($t eq "pull");
pidl "TDR_CHECK(tdr_$t\_charset(tdr$name, &v->$e->{NAME}, $len, sizeof($e->{TYPE}_t), CH_$e->{PROPERTIES}->{charset}));";
return;
}
-
if (has_property($e, "switch_is")) {
$switch = ", " . ParseExpr($e->{PROPERTIES}->{switch_is}, $env);
}
my $len = ParseExpr($e->{ARRAY_LEN}[0], $env);
if ($t eq "pull" and not is_constant($len)) {
- pidl "TDR_ALLOC(tdr, v->$e->{NAME}, $len);"
+ pidl "TDR_ALLOC(mem_ctx, v->$e->{NAME}, $len);";
+ $mem_ctx = "v->$e->{NAME}";
}
pidl "for (i = 0; i < $len; i++) {";
$array = "[i]";
}
+ if ($t eq "pull") {
+ $name = ", $mem_ctx";
+ }
+
if (has_property($e, "value") && $t eq "push") {
pidl "v->$e->{NAME} = ".ParseExpr($e->{PROPERTIES}->{value}, $env).";";
}
{
my ($e,$n,$t,$p) = @_;
- pidl static($p)."NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".printarg($t).", struct $n *v)";
+ pidl static($p)."NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".typearg($t).", struct $n *v)";
pidl "{"; indent;
pidl "int i;" if (ContainsArray($e));
{
my ($e,$n,$t,$p) = @_;
- pidl static($p)."NTSTATUS tdr_$t\_$n(struct tdr_$t *tdr".printarg($t).", int level, union $n *v)";
+ pidl static($p)."NTSTATUS tdr_$t\_$n(struct tdr_$t *tdr".typearg($t).", int level, union $n *v)";
pidl "{"; indent;
pidl "int i;" if (ContainsArray($e));
my ($e,$n,$t,$p) = @_;
my $bt = ($e->{PROPERTIES}->{base_type} or "uint8");
- pidl static($p)."NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".printarg($t).", enum $n *v)";
+ pidl static($p)."NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".typearg($t).", enum $n *v)";
pidl "{";
if ($t eq "pull") {
pidl "\t$bt\_t r;";
- pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, \&r));";
+ pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, mem_ctx, \&r));";
pidl "\t*v = r;";
} elsif ($t eq "push") {
pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, ($bt\_t *)v));";
# FIXME
} else {
my ($n, $d) = ($e->{NAME}, lc($e->{DATA}->{TYPE}));
- pidl "NTSTATUS tdr_pull\_$n(struct tdr_pull *tdr$switch, $d $n *v);";
+ pidl "NTSTATUS tdr_pull\_$n(struct tdr_pull *tdr, TALLOC_CTX *ctx$switch, $d $n *v);";
pidl "NTSTATUS tdr_print\_$n(struct tdr_print *tdr, const char *name$switch, $d $n *v);";
pidl "NTSTATUS tdr_push\_$n(struct tdr_push *tdr$switch, $d $n *v);";
}