mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
r9339: treat arrays of uint8 values as a special DATA_BLOB type in the ejs
interfaces to RPC. This makes large blobs of data much saner. Tim, you will probably want to do the same for the smb_interfaces.h generated code. Next we will need ways of extracting different data types from these blobs, for example asking for the blob to be interpreted as a utf16 string, or as a little-endian integer. That will allow for registry scripting to be quite sane.
This commit is contained in:
parent
8354b01612
commit
a8bca2e8e2
@ -165,22 +165,32 @@ sub EjsPullString($$$$$)
|
||||
sub EjsPullArray($$$$$)
|
||||
{
|
||||
my ($e, $l, $var, $name, $env) = @_;
|
||||
my $nl = Parse::Pidl::NDR::GetNextLevel($e, $l);
|
||||
my $length = Parse::Pidl::Util::ParseExpr($l->{LENGTH_IS}, $env);
|
||||
my $size = Parse::Pidl::Util::ParseExpr($l->{SIZE_IS}, $env);
|
||||
my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
|
||||
if ($pl && $pl->{TYPE} eq "POINTER") {
|
||||
$var = get_pointer_to($var);
|
||||
}
|
||||
# uint8 arrays are treated as data blobs
|
||||
if ($nl->{TYPE} eq 'DATA' && $e->{TYPE} eq 'uint8') {
|
||||
if (!$l->{IS_FIXED}) {
|
||||
pidl "EJS_ALLOC_N(ejs, $var, $size);";
|
||||
}
|
||||
pidl "ejs_pull_array_uint8(ejs, v, $name, $var, $length);";
|
||||
return;
|
||||
}
|
||||
my $avar = $var . "[i]";
|
||||
pidl "{";
|
||||
indent;
|
||||
pidl "uint32_t i;";
|
||||
if (!$l->{IS_FIXED}) {
|
||||
pidl "EJS_ALLOC_N(ejs, $var, $length);";
|
||||
pidl "EJS_ALLOC_N(ejs, $var, $size);";
|
||||
}
|
||||
pidl "for (i=0;i<$length;i++) {";
|
||||
indent;
|
||||
pidl "char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);";
|
||||
EjsPullElement($e, Parse::Pidl::NDR::GetNextLevel($e, $l), $avar, "id", $env);
|
||||
EjsPullElement($e, $nl, $avar, "id", $env);
|
||||
pidl "talloc_free(id);";
|
||||
deindent;
|
||||
pidl "}";
|
||||
@ -451,11 +461,17 @@ sub EjsPushSwitch($$$$$)
|
||||
sub EjsPushArray($$$$$)
|
||||
{
|
||||
my ($e, $l, $var, $name, $env) = @_;
|
||||
my $nl = Parse::Pidl::NDR::GetNextLevel($e, $l);
|
||||
my $length = Parse::Pidl::Util::ParseExpr($l->{LENGTH_IS}, $env);
|
||||
my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
|
||||
if ($pl && $pl->{TYPE} eq "POINTER") {
|
||||
$var = get_pointer_to($var);
|
||||
}
|
||||
# uint8 arrays are treated as data blobs
|
||||
if ($nl->{TYPE} eq 'DATA' && $e->{TYPE} eq 'uint8') {
|
||||
pidl "ejs_push_array_uint8(ejs, v, $name, $var, $length);";
|
||||
return;
|
||||
}
|
||||
my $avar = $var . "[i]";
|
||||
pidl "{";
|
||||
indent;
|
||||
@ -463,7 +479,7 @@ sub EjsPushArray($$$$$)
|
||||
pidl "for (i=0;i<$length;i++) {";
|
||||
indent;
|
||||
pidl "const char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);";
|
||||
EjsPushElement($e, Parse::Pidl::NDR::GetNextLevel($e, $l), $avar, "id", $env);
|
||||
EjsPushElement($e, $nl, $avar, "id", $env);
|
||||
deindent;
|
||||
pidl "}";
|
||||
pidl "ejs_push_uint32(ejs, v, $name \".length\", &i);";
|
||||
|
@ -349,3 +349,40 @@ NTSTATUS ejs_push_BOOL(struct ejs_rpc *ejs,
|
||||
{
|
||||
return mprSetVar(v, name, mprCreateBoolVar(*r));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pull a uint8 array from a mpr variable to a C element - treating as a data blob
|
||||
*/
|
||||
NTSTATUS ejs_pull_array_uint8(struct ejs_rpc *ejs,
|
||||
struct MprVar *v, const char *name,
|
||||
uint8_t *r, uint32_t length)
|
||||
{
|
||||
NTSTATUS status;
|
||||
DATA_BLOB *blob;
|
||||
|
||||
status = mprGetVar(&v, name);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
blob = mprToDataBlob(v);
|
||||
if (blob == NULL) {
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
}
|
||||
if (blob->length != length) {
|
||||
return NT_STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
memcpy(r, blob->data, length);
|
||||
return NT_STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS ejs_push_array_uint8(struct ejs_rpc *ejs,
|
||||
struct MprVar *v, const char *name,
|
||||
const uint8_t *r, uint32_t length)
|
||||
{
|
||||
DATA_BLOB blob;
|
||||
blob.data = discard_const(r);
|
||||
blob.length = length;
|
||||
mprSetVar(v, name, mprDataBlob(blob));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -108,6 +108,13 @@ NTSTATUS ejs_pull_BOOL(struct ejs_rpc *ejs,
|
||||
NTSTATUS ejs_push_BOOL(struct ejs_rpc *ejs,
|
||||
struct MprVar *v, const char *name, const BOOL *r);
|
||||
|
||||
NTSTATUS ejs_pull_array_uint8(struct ejs_rpc *ejs,
|
||||
struct MprVar *v, const char *name,
|
||||
uint8_t *r, uint32_t length);
|
||||
NTSTATUS ejs_push_array_uint8(struct ejs_rpc *ejs,
|
||||
struct MprVar *v, const char *name,
|
||||
const uint8_t *r, uint32_t length);
|
||||
|
||||
#define EJS_ALLOC_SIZE(ejs, s, size) do { \
|
||||
(s) = talloc_size(ejs, size); \
|
||||
if (!(s)) return ejs_panic(ejs, "out of memory"); \
|
||||
|
@ -317,6 +317,31 @@ struct MprVar mprNTSTATUS(NTSTATUS status)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
create a data-blob in a mpr variable
|
||||
*/
|
||||
struct MprVar mprDataBlob(DATA_BLOB blob)
|
||||
{
|
||||
struct MprVar res;
|
||||
struct data_blob *pblob = talloc(mprMemCtx(), struct data_blob);
|
||||
*pblob = data_blob_talloc(pblob, blob.data, blob.length);
|
||||
|
||||
res = mprObject("DATA_BLOB");
|
||||
|
||||
mprSetVar(&res, "size", mprCreateIntegerVar(blob.length));
|
||||
mprSetPtrChild(&res, "blob", pblob);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
return a data blob from a mpr var created using mprDataBlob
|
||||
*/
|
||||
struct data_blob *mprToDataBlob(struct MprVar *v)
|
||||
{
|
||||
return talloc_get_type(mprGetPtr(v, "blob"), struct data_blob);
|
||||
}
|
||||
|
||||
/*
|
||||
turn a WERROR into a MprVar object with lots of funky properties
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user