mirror of
https://github.com/samba-team/samba.git
synced 2025-08-24 21:49:29 +03:00
r7186: add [relative_base] property, which is allowed on typedef's
(maybe we could add them to elements latter...) with this property all relative pointers from inside the struct or union are relative to the struct/union start metze
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
87a3162190
commit
c0dd18326c
@ -961,7 +961,7 @@ sub ParseElementPullLevel
|
||||
ParseElementPullLevel($e,Ndr::GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
|
||||
|
||||
if ($l->{POINTER_TYPE} ne "ref") {
|
||||
if ($l->{POINTER_TYPE} eq "relative") {
|
||||
if ($l->{POINTER_TYPE} eq "relative") {
|
||||
pidl "ndr_pull_restore(ndr, &_relative_save);";
|
||||
}
|
||||
deindent;
|
||||
@ -1079,6 +1079,9 @@ sub ParseStructPush($$)
|
||||
|
||||
my $env = GenerateStructEnv($struct);
|
||||
|
||||
# save the old relative_base_offset
|
||||
pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined($struct->{PROPERTIES}{relative_base});
|
||||
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
DeclareArrayVariables($e);
|
||||
}
|
||||
@ -1107,6 +1110,12 @@ sub ParseStructPush($$)
|
||||
|
||||
pidl "NDR_CHECK(ndr_push_align(ndr, $struct->{ALIGN}));";
|
||||
|
||||
if (defined($struct->{PROPERTIES}{relative_base})) {
|
||||
# set the current offset as base for relative pointers
|
||||
# and store it based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));";
|
||||
}
|
||||
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
ParseElementPush($e, "ndr", "r->", $env, 1, 0);
|
||||
}
|
||||
@ -1116,6 +1125,11 @@ sub ParseStructPush($$)
|
||||
|
||||
pidl "if (ndr_flags & NDR_BUFFERS) {";
|
||||
indent;
|
||||
if (defined($struct->{PROPERTIES}{relative_base})) {
|
||||
# retrieve the current offset as base for relative pointers
|
||||
# based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));";
|
||||
}
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
ParseElementPush($e, "ndr", "r->", $env, 0, 1);
|
||||
}
|
||||
@ -1124,6 +1138,8 @@ sub ParseStructPush($$)
|
||||
pidl "}";
|
||||
|
||||
end_flags($struct);
|
||||
# restore the old relative_base_offset
|
||||
pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base});
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
@ -1396,6 +1412,9 @@ sub ParseStructPull($$)
|
||||
DeclareArrayVariables($e);
|
||||
}
|
||||
|
||||
# save the old relative_base_offset
|
||||
pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined($struct->{PROPERTIES}{relative_base});
|
||||
|
||||
start_flags($struct);
|
||||
|
||||
pidl "if (ndr_flags & NDR_SCALARS) {";
|
||||
@ -1407,6 +1426,12 @@ sub ParseStructPull($$)
|
||||
|
||||
pidl "NDR_CHECK(ndr_pull_align(ndr, $struct->{ALIGN}));";
|
||||
|
||||
if (defined($struct->{PROPERTIES}{relative_base})) {
|
||||
# set the current offset as base for relative pointers
|
||||
# and store it based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));";
|
||||
}
|
||||
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
ParseElementPull($e, "ndr", "r->", $env, 1, 0);
|
||||
}
|
||||
@ -1415,6 +1440,11 @@ sub ParseStructPull($$)
|
||||
pidl "}";
|
||||
pidl "if (ndr_flags & NDR_BUFFERS) {";
|
||||
indent;
|
||||
if (defined($struct->{PROPERTIES}{relative_base})) {
|
||||
# retrieve the current offset as base for relative pointers
|
||||
# based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));";
|
||||
}
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
ParseElementPull($e, "ndr", "r->", $env, 0, 1);
|
||||
}
|
||||
@ -1423,6 +1453,8 @@ sub ParseStructPull($$)
|
||||
pidl "}";
|
||||
|
||||
end_flags($struct);
|
||||
# restore the old relative_base_offset
|
||||
pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base});
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
@ -1495,9 +1527,10 @@ sub ParseUnionPush($$)
|
||||
my $name = shift;
|
||||
my $have_default = 0;
|
||||
|
||||
# save the old relative_base_offset
|
||||
pidl "uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);" if defined($e->{PROPERTIES}{relative_base});
|
||||
pidl "int level;";
|
||||
|
||||
|
||||
start_flags($e);
|
||||
|
||||
pidl "level = ndr_push_get_switch_value(ndr, r);";
|
||||
@ -1509,8 +1542,13 @@ sub ParseUnionPush($$)
|
||||
pidl "NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}(ndr, NDR_SCALARS, level));";
|
||||
}
|
||||
|
||||
# my $align = union_alignment($e);
|
||||
# pidl "NDR_CHECK(ndr_push_align(ndr, $align));";
|
||||
pidl "NDR_CHECK(ndr_push_align(ndr, $e->{ALIGN}));";
|
||||
|
||||
if (defined($e->{PROPERTIES}{relative_base})) {
|
||||
# set the current offset as base for relative pointers
|
||||
# and store it based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));";
|
||||
}
|
||||
|
||||
pidl "switch (level) {";
|
||||
indent;
|
||||
@ -1539,6 +1577,11 @@ sub ParseUnionPush($$)
|
||||
pidl "}";
|
||||
pidl "if (ndr_flags & NDR_BUFFERS) {";
|
||||
indent;
|
||||
if (defined($e->{PROPERTIES}{relative_base})) {
|
||||
# retrieve the current offset as base for relative pointers
|
||||
# based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));";
|
||||
}
|
||||
pidl "switch (level) {";
|
||||
indent;
|
||||
foreach my $el (@{$e->{ELEMENTS}}) {
|
||||
@ -1561,6 +1604,8 @@ sub ParseUnionPush($$)
|
||||
deindent;
|
||||
pidl "}";
|
||||
end_flags($e);
|
||||
# restore the old relative_base_offset
|
||||
pidl "ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base});
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
@ -1614,6 +1659,8 @@ sub ParseUnionPull($$)
|
||||
my $have_default = 0;
|
||||
my $switch_type = $e->{SWITCH_TYPE};
|
||||
|
||||
# save the old relative_base_offset
|
||||
pidl "uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);" if defined($e->{PROPERTIES}{relative_base});
|
||||
pidl "int level;";
|
||||
if (defined($switch_type)) {
|
||||
if (typelist::typeIs($switch_type, "ENUM")) {
|
||||
@ -1636,8 +1683,13 @@ sub ParseUnionPull($$)
|
||||
pidl "}";
|
||||
}
|
||||
|
||||
# my $align = union_alignment($e);
|
||||
# pidl "\tNDR_CHECK(ndr_pull_align(ndr, $align));\n";
|
||||
pidl "NDR_CHECK(ndr_pull_align(ndr, $e->{ALIGN}));";
|
||||
|
||||
if (defined($e->{PROPERTIES}{relative_base})) {
|
||||
# set the current offset as base for relative pointers
|
||||
# and store it based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));";
|
||||
}
|
||||
|
||||
pidl "switch (level) {";
|
||||
indent;
|
||||
@ -1667,6 +1719,11 @@ sub ParseUnionPull($$)
|
||||
pidl "}";
|
||||
pidl "if (ndr_flags & NDR_BUFFERS) {";
|
||||
indent;
|
||||
if (defined($e->{PROPERTIES}{relative_base})) {
|
||||
# retrieve the current offset as base for relative pointers
|
||||
# based on the toplevel struct/union
|
||||
pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));";
|
||||
}
|
||||
pidl "switch (level) {";
|
||||
indent;
|
||||
foreach my $el (@{$e->{ELEMENTS}}) {
|
||||
@ -1689,6 +1746,8 @@ sub ParseUnionPull($$)
|
||||
deindent;
|
||||
pidl "}";
|
||||
end_flags($e);
|
||||
# restore the old relative_base_offset
|
||||
pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base});
|
||||
}
|
||||
|
||||
sub ArgsUnionPush($)
|
||||
|
@ -90,6 +90,7 @@ my %property_list = (
|
||||
"ptr" => ["ELEMENT"],
|
||||
"unique" => ["ELEMENT"],
|
||||
"relative" => ["ELEMENT"],
|
||||
"relative_base" => ["TYPEDEF"],
|
||||
|
||||
"gensize" => ["TYPEDEF"],
|
||||
"value" => ["ELEMENT"],
|
||||
|
@ -46,6 +46,9 @@ struct ndr_pull {
|
||||
uint32_t data_size;
|
||||
uint32_t offset;
|
||||
|
||||
uint32_t relative_base_offset;
|
||||
struct ndr_token_list *relative_base_list;
|
||||
|
||||
struct ndr_token_list *relative_list;
|
||||
struct ndr_token_list *array_size_list;
|
||||
struct ndr_token_list *array_length_list;
|
||||
@ -69,6 +72,9 @@ struct ndr_push {
|
||||
uint32_t alloc_size;
|
||||
uint32_t offset;
|
||||
|
||||
uint32_t relative_base_offset;
|
||||
struct ndr_token_list *relative_base_list;
|
||||
|
||||
struct ndr_token_list *switch_list;
|
||||
struct ndr_token_list *relative_list;
|
||||
|
||||
|
@ -562,59 +562,6 @@ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *p)
|
||||
return ndr_token_peek(&ndr->switch_list, p);
|
||||
}
|
||||
|
||||
/*
|
||||
pull a relative object - stage1
|
||||
called during SCALARS processing
|
||||
*/
|
||||
NTSTATUS ndr_pull_relative_ptr1(struct ndr_pull *ndr, const void *p, uint32_t rel_offset)
|
||||
{
|
||||
return ndr_token_store(ndr, &ndr->relative_list, p, rel_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
pull a relative object - stage2
|
||||
called during BUFFERS processing
|
||||
*/
|
||||
NTSTATUS ndr_pull_relative_ptr2(struct ndr_pull *ndr, const void *p)
|
||||
{
|
||||
uint32_t rel_offset;
|
||||
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &rel_offset));
|
||||
return ndr_pull_set_offset(ndr, rel_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
push a relative object - stage1
|
||||
this is called during SCALARS processing
|
||||
*/
|
||||
NTSTATUS ndr_push_relative_ptr1(struct ndr_push *ndr, const void *p)
|
||||
{
|
||||
if (p == NULL) {
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_token_store(ndr, &ndr->relative_list, p, ndr->offset));
|
||||
return ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
push a relative object - stage2
|
||||
this is called during buffers processing
|
||||
*/
|
||||
NTSTATUS ndr_push_relative_ptr2(struct ndr_push *ndr, const void *p)
|
||||
{
|
||||
struct ndr_push_save save;
|
||||
if (p == NULL) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
ndr_push_save(ndr, &save);
|
||||
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &ndr->offset));
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, save.offset));
|
||||
ndr_push_restore(ndr, &save);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
pull a struct from a blob using NDR
|
||||
*/
|
||||
@ -765,3 +712,126 @@ size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_push_flags_f
|
||||
talloc_free(ndr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
get the current base for relative pointers for the push
|
||||
*/
|
||||
uint32_t ndr_push_get_relative_base_offset(struct ndr_push *ndr)
|
||||
{
|
||||
return ndr->relative_base_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
restore the old base for relative pointers for the push
|
||||
*/
|
||||
void ndr_push_restore_relative_base_offset(struct ndr_push *ndr, uint32_t offset)
|
||||
{
|
||||
ndr->relative_base_offset = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
setup the current base for relative pointers for the push
|
||||
called in the NDR_SCALAR stage
|
||||
*/
|
||||
NTSTATUS ndr_push_setup_relative_base_offset1(struct ndr_push *ndr, const void *p, uint32_t offset)
|
||||
{
|
||||
ndr->relative_base_offset = offset;
|
||||
return ndr_token_store(ndr, &ndr->relative_base_list, p, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
setup the current base for relative pointers for the push
|
||||
called in the NDR_BUFFERS stage
|
||||
*/
|
||||
NTSTATUS ndr_push_setup_relative_base_offset2(struct ndr_push *ndr, const void *p)
|
||||
{
|
||||
return ndr_token_retrieve(&ndr->relative_base_list, p, &ndr->relative_base_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
push a relative object - stage1
|
||||
this is called during SCALARS processing
|
||||
*/
|
||||
NTSTATUS ndr_push_relative_ptr1(struct ndr_push *ndr, const void *p)
|
||||
{
|
||||
if (p == NULL) {
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_token_store(ndr, &ndr->relative_list, p, ndr->offset));
|
||||
return ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
push a relative object - stage2
|
||||
this is called during buffers processing
|
||||
*/
|
||||
NTSTATUS ndr_push_relative_ptr2(struct ndr_push *ndr, const void *p)
|
||||
{
|
||||
struct ndr_push_save save;
|
||||
if (p == NULL) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
ndr_push_save(ndr, &save);
|
||||
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &ndr->offset));
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, save.offset));
|
||||
ndr_push_restore(ndr, &save);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
get the current base for relative pointers for the pull
|
||||
*/
|
||||
uint32_t ndr_pull_get_relative_base_offset(struct ndr_pull *ndr)
|
||||
{
|
||||
return ndr->relative_base_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
restore the old base for relative pointers for the pull
|
||||
*/
|
||||
void ndr_pull_restore_relative_base_offset(struct ndr_pull *ndr, uint32_t offset)
|
||||
{
|
||||
ndr->relative_base_offset = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
setup the current base for relative pointers for the pull
|
||||
called in the NDR_SCALAR stage
|
||||
*/
|
||||
NTSTATUS ndr_pull_setup_relative_base_offset1(struct ndr_pull *ndr, const void *p, uint32_t offset)
|
||||
{
|
||||
ndr->relative_base_offset = offset;
|
||||
return ndr_token_store(ndr, &ndr->relative_base_list, p, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
setup the current base for relative pointers for the pull
|
||||
called in the NDR_BUFFERS stage
|
||||
*/
|
||||
NTSTATUS ndr_pull_setup_relative_base_offset2(struct ndr_pull *ndr, const void *p)
|
||||
{
|
||||
return ndr_token_retrieve(&ndr->relative_base_list, p, &ndr->relative_base_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
pull a relative object - stage1
|
||||
called during SCALARS processing
|
||||
*/
|
||||
NTSTATUS ndr_pull_relative_ptr1(struct ndr_pull *ndr, const void *p, uint32_t rel_offset)
|
||||
{
|
||||
rel_offset += ndr->relative_base_offset;
|
||||
return ndr_token_store(ndr, &ndr->relative_list, p, rel_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
pull a relative object - stage2
|
||||
called during BUFFERS processing
|
||||
*/
|
||||
NTSTATUS ndr_pull_relative_ptr2(struct ndr_pull *ndr, const void *p)
|
||||
{
|
||||
uint32_t rel_offset;
|
||||
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &rel_offset));
|
||||
return ndr_pull_set_offset(ndr, rel_offset);
|
||||
}
|
||||
|
Reference in New Issue
Block a user