1
0
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:
Stefan Metzmacher
2005-06-02 03:41:12 +00:00
committed by Gerald (Jerry) Carter
parent 87a3162190
commit c0dd18326c
4 changed files with 195 additions and 59 deletions

View File

@ -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($)

View File

@ -90,6 +90,7 @@ my %property_list = (
"ptr" => ["ELEMENT"],
"unique" => ["ELEMENT"],
"relative" => ["ELEMENT"],
"relative_base" => ["TYPEDEF"],
"gensize" => ["TYPEDEF"],
"value" => ["ELEMENT"],

View File

@ -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;

View File

@ -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);
}