diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/build/pidl/TODO | 4 | ||||
-rw-r--r-- | source4/build/pidl/ndr_header.pm | 6 | ||||
-rw-r--r-- | source4/build/pidl/ndr_parser.pm | 30 | ||||
-rw-r--r-- | source4/librpc/idl/echo.idl | 4 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_string.c | 38 |
5 files changed, 66 insertions, 16 deletions
diff --git a/source4/build/pidl/TODO b/source4/build/pidl/TODO index d51bd83b04..00f875e00d 100644 --- a/source4/build/pidl/TODO +++ b/source4/build/pidl/TODO @@ -1,7 +1,3 @@ -Implement: - ndr_parser.pm: - - if [charset()] specified, use instead of the for loops (call ndr_pu{ll,sh}_charset() - - True multiple dimension array / strings in arrays support (closely related to things specified above) diff --git a/source4/build/pidl/ndr_header.pm b/source4/build/pidl/ndr_header.pm index 04cd57ad7f..6269320115 100644 --- a/source4/build/pidl/ndr_header.pm +++ b/source4/build/pidl/ndr_header.pm @@ -213,7 +213,11 @@ sub HeaderType($$$) return; } - pidl typelist::mapType($e->{TYPE}); + if (util::has_property($e, "charset")) { + pidl "char"; + } else { + pidl typelist::mapType($e->{TYPE}); + } } ##################################################################### diff --git a/source4/build/pidl/ndr_parser.pm b/source4/build/pidl/ndr_parser.pm index 4eab424c75..dc3635f6e4 100644 --- a/source4/build/pidl/ndr_parser.pm +++ b/source4/build/pidl/ndr_parser.pm @@ -550,7 +550,11 @@ sub ParseElementPushLevel my $nl = Ndr::GetNextLevel($e, $l); - pidl "NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; + if (util::has_property($e, "charset")) { + pidl "NDR_CHECK(ndr_push_charset($ndr, $ndr_flags, $var_name, $length, sizeof(" . typelist::mapType($nl->{DATA_TYPE}) . "), $e->{PROPERTIES}->{charset}));"; + } else { + pidl "NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; + } return; } } elsif ($l->{TYPE} eq "SWITCH") { @@ -688,8 +692,12 @@ sub ParseElementPrint($$$) } if (is_scalar_array($e, $l)) { - my $nl = Ndr::GetNextLevel($e, $l); - pidl "ndr_print_array_$nl->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name, $length);"; + if (util::has_property($e, "charset")) { + pidl "ndr_print_string(ndr, \"$e->{NAME}\", $var_name);"; + } else { + my $nl = Ndr::GetNextLevel($e, $l); + pidl "ndr_print_array_$nl->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name, $length);"; + } last; } @@ -844,10 +852,14 @@ sub ParseElementPullLevel } my $nl = Ndr::GetNextLevel($e, $l); - pidl "NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; - if ($l->{IS_ZERO_TERMINATED}) { - # Make sure last element is zero! - pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, ndr_get_array_length(ndr, " . get_pointer_to($var_name) . "), sizeof(*$var_name)));"; + if (util::has_property($e, "charset")) { + pidl "NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . typelist::mapType($nl->{DATA_TYPE}) . "), $e->{PROPERTIES}->{charset}));"; + } else { + pidl "NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; + if ($l->{IS_ZERO_TERMINATED}) { + # Make sure last element is zero! + pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, $length, sizeof(*$var_name)));"; + } } return; } @@ -901,7 +913,7 @@ sub ParseElementPullLevel if ($l->{IS_ZERO_TERMINATED}) { # Make sure last element is zero! - pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, ndr_get_array_length(ndr, " . get_pointer_to($var_name) . "), sizeof(*$var_name)));"; + pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, $length, sizeof(*$var_name)));"; } } @@ -1867,6 +1879,8 @@ sub AllocateArrayLevel($$$$$) { my ($e,$l,$ndr,$env,$size) = @_; + return if (util::has_property($e, "charset")); + my $var = ParseExpr($e->{NAME}, $env); check_null_pointer($size); diff --git a/source4/librpc/idl/echo.idl b/source4/librpc/idl/echo.idl index d841a0974a..a6f52d9d15 100644 --- a/source4/librpc/idl/echo.idl +++ b/source4/librpc/idl/echo.idl @@ -34,8 +34,8 @@ interface rpcecho /* test strings */ void echo_TestCall ( - [in] unistr *s1, - [out] unistr *s2 + [in,string,charset(CH_UTF16)] uint16 *s1, + [out,string,charset(CH_UTF16)] uint16 *s2 ); diff --git a/source4/librpc/ndr/ndr_string.c b/source4/librpc/ndr/ndr_string.c index af9783ed95..95e9df39f0 100644 --- a/source4/librpc/ndr/ndr_string.c +++ b/source4/librpc/ndr/ndr_string.c @@ -587,8 +587,10 @@ NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, const void *_var, uin const char *var = _var; uint32_t i; + var += element_size*(count-1); + for (i = 0; i < element_size; i++) { - if (var+element_size*(count-1)+i != 0) { + if (var[i] != 0) { return NT_STATUS_UNSUCCESSFUL; } } @@ -596,3 +598,37 @@ NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, const void *_var, uin return NT_STATUS_OK; } + +NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, char **var, uint32_t length, uint8_t byte_mul, int chset) +{ + int ret; + NDR_PULL_NEED_BYTES(ndr, length*byte_mul); + ret = convert_string_talloc(ndr, chset, CH_UNIX, + ndr->data+ndr->offset, + length*byte_mul, + (void **)var); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + NDR_CHECK(ndr_pull_advance(ndr, length*byte_mul)); + + return NT_STATUS_OK; +} + +NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var, uint32_t length, uint8_t byte_mul, int chset) +{ + int ret; + NDR_PUSH_NEED_BYTES(ndr, byte_mul*length); + ret = convert_string(CH_UNIX, chset, + var, length, + ndr->data+ndr->offset, + byte_mul*length); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += byte_mul*length; + + return NT_STATUS_OK; +} |