librpc/ndr/ndr_string.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003 
00004    routines for marshalling/unmarshalling string types
00005 
00006    Copyright (C) Andrew Tridgell 2003
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 
00025 /**
00026   pull a general string from the wire
00027 */
00028 NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
00029 {
00030         char *as=NULL;
00031         uint32_t len1, ofs, len2;
00032         uint16_t len3;
00033         int ret;
00034         charset_t chset = CH_UTF16LE;
00035         unsigned byte_mul = 2;
00036         unsigned flags = ndr->flags;
00037         unsigned c_len_term = 0;
00038 
00039         if (!(ndr_flags & NDR_SCALARS)) {
00040                 return NT_STATUS_OK;
00041         }
00042 
00043         if (NDR_BE(ndr)) {
00044                 chset = CH_UTF16BE;
00045         }
00046 
00047         if (flags & LIBNDR_FLAG_STR_ASCII) {
00048                 chset = CH_DOS;
00049                 byte_mul = 1;
00050                 flags &= ~LIBNDR_FLAG_STR_ASCII;
00051         }
00052 
00053         if (flags & LIBNDR_FLAG_STR_UTF8) {
00054                 chset = CH_UTF8;
00055                 byte_mul = 1;
00056                 flags &= ~LIBNDR_FLAG_STR_UTF8;
00057         }
00058 
00059         flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
00060         if (flags & LIBNDR_FLAG_STR_CHARLEN) {
00061                 c_len_term = 1;
00062                 flags &= ~LIBNDR_FLAG_STR_CHARLEN;
00063         }
00064 
00065         switch (flags & LIBNDR_STRING_FLAGS) {
00066         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
00067         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
00068                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
00069                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));
00070                 if (ofs != 0) {
00071                         return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",
00072                                               ndr->flags & LIBNDR_STRING_FLAGS);
00073                 }
00074                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len2));
00075                 if (len2 > len1) {
00076                         return ndr_pull_error(ndr, NDR_ERR_STRING, 
00077                                               "Bad string lengths len1=%u ofs=%u len2=%u\n", 
00078                                               len1, ofs, len2);
00079                 }
00080                 NDR_PULL_NEED_BYTES(ndr, (len2 + c_len_term)*byte_mul);
00081                 if (len2 == 0) {
00082                         as = talloc_strdup(ndr->current_mem_ctx, "");
00083                 } else {
00084                         ret = convert_string_talloc(ndr->current_mem_ctx,
00085                                                     chset, CH_UNIX, 
00086                                                     ndr->data+ndr->offset, 
00087                                                     (len2 + c_len_term)*byte_mul,
00088                                                     &as, True);
00089                         if (ret == -1) {
00090                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00091                                                       "Bad character conversion");
00092                         }
00093                 }
00094                 NDR_CHECK(ndr_pull_advance(ndr, (len2 + c_len_term)*byte_mul));
00095 
00096                 if (len1 != len2) {
00097                         DEBUG(6,("len1[%u] != len2[%u] '%s'\n", len1, len2, as));
00098                 }
00099 
00100                 /* this is a way of detecting if a string is sent with the wrong
00101                    termination */
00102                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
00103                         if (strlen(as) < (len2 + c_len_term)) {
00104                                 DEBUG(6,("short string '%s'\n", as));
00105                         }
00106                 } else {
00107                         if (strlen(as) == (len2 + c_len_term)) {
00108                                 DEBUG(6,("long string '%s'\n", as));
00109                         }
00110                 }
00111                 *s = as;
00112                 break;
00113 
00114         case LIBNDR_FLAG_STR_SIZE4:
00115         case LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
00116                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
00117                 NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
00118                 if (len1 == 0) {
00119                         as = talloc_strdup(ndr->current_mem_ctx, "");
00120                 } else {
00121                         ret = convert_string_talloc(ndr->current_mem_ctx,
00122                                                     chset, CH_UNIX, 
00123                                                     ndr->data+ndr->offset, 
00124                                                     (len1 + c_len_term)*byte_mul,
00125                                                     &as, False);
00126                         if (ret == -1) {
00127                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00128                                                       "Bad character conversion");
00129                         }
00130                 }
00131                 NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
00132 
00133                 /* this is a way of detecting if a string is sent with the wrong
00134                    termination */
00135                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
00136                         if (strlen(as) < (len1 + c_len_term)) {
00137                                 DEBUG(6,("short string '%s'\n", as));
00138                         }
00139                 } else {
00140                         if (strlen(as) == (len1 + c_len_term)) {
00141                                 DEBUG(6,("long string '%s'\n", as));
00142                         }
00143                 }
00144                 *s = as;
00145                 break;
00146 
00147         case LIBNDR_FLAG_STR_LEN4:
00148         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_NOTERM:
00149                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));
00150                 if (ofs != 0) {
00151                         return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",
00152                                               ndr->flags & LIBNDR_STRING_FLAGS);
00153                 }
00154                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
00155                 NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
00156                 if (len1 == 0) {
00157                         as = talloc_strdup(ndr->current_mem_ctx, "");
00158                 } else {
00159                         ret = convert_string_talloc(ndr->current_mem_ctx,
00160                                                     chset, CH_UNIX, 
00161                                                     ndr->data+ndr->offset, 
00162                                                     (len1 + c_len_term)*byte_mul,
00163                                                     &as, False);
00164                         if (ret == -1) {
00165                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00166                                                       "Bad character conversion");
00167                         }
00168                 }
00169                 NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
00170 
00171                 /* this is a way of detecting if a string is sent with the wrong
00172                    termination */
00173                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
00174                         if (strlen(as) < (len1 + c_len_term)) {
00175                                 DEBUG(6,("short string '%s'\n", as));
00176                         }
00177                 } else {
00178                         if (strlen(as) == (len1 + c_len_term)) {
00179                                 DEBUG(6,("long string '%s'\n", as));
00180                         }
00181                 }
00182                 *s = as;
00183                 break;
00184 
00185 
00186         case LIBNDR_FLAG_STR_SIZE2:
00187         case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM:
00188                 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
00189                 NDR_PULL_NEED_BYTES(ndr, (len3 + c_len_term)*byte_mul);
00190                 if (len3 == 0) {
00191                         as = talloc_strdup(ndr->current_mem_ctx, "");
00192                 } else {
00193                         ret = convert_string_talloc(ndr->current_mem_ctx,
00194                                                     chset, CH_UNIX, 
00195                                                     ndr->data+ndr->offset, 
00196                                                     (len3 + c_len_term)*byte_mul,
00197                                                     &as, False);
00198                         if (ret == -1) {
00199                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00200                                                       "Bad character conversion");
00201                         }
00202                 }
00203                 NDR_CHECK(ndr_pull_advance(ndr, (len3 + c_len_term)*byte_mul));
00204 
00205                 /* this is a way of detecting if a string is sent with the wrong
00206                    termination */
00207                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
00208                         if (strlen(as) < (len3 + c_len_term)) {
00209                                 DEBUG(6,("short string '%s'\n", as));
00210                         }
00211                 } else {
00212                         if (strlen(as) == (len3 + c_len_term)) {
00213                                 DEBUG(6,("long string '%s'\n", as));
00214                         }
00215                 }
00216                 *s = as;
00217                 break;
00218 
00219         case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE:
00220                 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
00221                 NDR_PULL_NEED_BYTES(ndr, len3);
00222                 if (len3 == 0) {
00223                         as = talloc_strdup(ndr->current_mem_ctx, "");
00224                 } else {
00225                         ret = convert_string_talloc(ndr->current_mem_ctx,
00226                                                     chset, CH_UNIX, 
00227                                                     ndr->data+ndr->offset, 
00228                                                     len3, &as, False);
00229                         if (ret == -1) {
00230                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00231                                                       "Bad character conversion");
00232                         }
00233                 }
00234                 NDR_CHECK(ndr_pull_advance(ndr, len3));
00235                 *s = as;
00236                 break;
00237 
00238         case LIBNDR_FLAG_STR_NULLTERM:
00239                 if (byte_mul == 1) {
00240                         len1 = ascii_len_n((const char *)(ndr->data+ndr->offset), ndr->data_size - ndr->offset);
00241                 } else {
00242                         len1 = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);
00243                 }
00244                 ret = convert_string_talloc(ndr->current_mem_ctx,
00245                                             chset, CH_UNIX, 
00246                                             ndr->data+ndr->offset, 
00247                                             len1, &as, False);
00248                 if (ret == -1) {
00249                         return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00250                                               "Bad character conversion");
00251                 }
00252                 NDR_CHECK(ndr_pull_advance(ndr, len1));
00253                 *s = as;
00254                 break;
00255 
00256         case LIBNDR_FLAG_STR_FIXLEN15:
00257         case LIBNDR_FLAG_STR_FIXLEN32:
00258                 len1 = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
00259                 NDR_PULL_NEED_BYTES(ndr, len1*byte_mul);
00260                 ret = convert_string_talloc(ndr->current_mem_ctx,
00261                                             chset, CH_UNIX, 
00262                                             ndr->data+ndr->offset, 
00263                                             len1*byte_mul, &as, False);
00264                 if (ret == -1) {
00265                         return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00266                                               "Bad character conversion");
00267                 }
00268                 NDR_CHECK(ndr_pull_advance(ndr, len1*byte_mul));
00269                 *s = as;
00270                 break;
00271 
00272         default:
00273                 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
00274                                       ndr->flags & LIBNDR_STRING_FLAGS);
00275         }
00276 
00277         return NT_STATUS_OK;
00278 }
00279 
00280 
00281 /**
00282   push a general string onto the wire
00283 */
00284 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
00285 {
00286         ssize_t s_len, c_len, d_len;
00287         charset_t chset = CH_UTF16LE;
00288         unsigned flags = ndr->flags;
00289         unsigned byte_mul = 2;
00290         uint8_t *dest = NULL;
00291 
00292         if (!(ndr_flags & NDR_SCALARS)) {
00293                 return NT_STATUS_OK;
00294         }
00295 
00296         if (NDR_BE(ndr)) {
00297                 chset = CH_UTF16BE;
00298         }
00299         
00300         s_len = s?strlen(s):0;
00301 
00302         if (flags & LIBNDR_FLAG_STR_ASCII) {
00303                 chset = CH_DOS;
00304                 byte_mul = 1;
00305                 flags &= ~LIBNDR_FLAG_STR_ASCII;
00306         }
00307 
00308         if (flags & LIBNDR_FLAG_STR_UTF8) {
00309                 chset = CH_UTF8;
00310                 byte_mul = 1;
00311                 flags &= ~LIBNDR_FLAG_STR_UTF8;
00312         }
00313 
00314         flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
00315 
00316         if (!(flags & 
00317               (LIBNDR_FLAG_STR_NOTERM |
00318                LIBNDR_FLAG_STR_FIXLEN15 |
00319                LIBNDR_FLAG_STR_FIXLEN32))) {
00320                 s_len++;
00321         }
00322         d_len = convert_string_talloc(ndr, CH_UNIX, chset, s, s_len, &dest,
00323                                       False);
00324         if (d_len == -1) {
00325                 return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
00326                                       "Bad character conversion");
00327         }
00328 
00329         if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
00330                 c_len = d_len;
00331                 flags &= ~LIBNDR_FLAG_STR_BYTESIZE;
00332         } else if (flags & LIBNDR_FLAG_STR_CHARLEN) {
00333                 c_len = (d_len / byte_mul)-1;
00334                 flags &= ~LIBNDR_FLAG_STR_CHARLEN;
00335         } else {
00336                 c_len = d_len / byte_mul;
00337         }
00338 
00339         switch ((flags & LIBNDR_STRING_FLAGS) & ~LIBNDR_FLAG_STR_NOTERM) {
00340         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
00341                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
00342                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
00343                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
00344                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
00345                 break;
00346 
00347         case LIBNDR_FLAG_STR_LEN4:
00348                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
00349                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
00350                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
00351                 break;
00352 
00353         case LIBNDR_FLAG_STR_SIZE4:
00354                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
00355                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
00356                 break;
00357 
00358         case LIBNDR_FLAG_STR_SIZE2:
00359                 NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, c_len));
00360                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
00361                 break;
00362 
00363         case LIBNDR_FLAG_STR_NULLTERM:
00364                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
00365                 break;
00366 
00367         case LIBNDR_FLAG_STR_FIXLEN15:
00368         case LIBNDR_FLAG_STR_FIXLEN32: {
00369                 ssize_t fix_len = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
00370                 uint32_t pad_len = fix_len - d_len;
00371                 if (d_len > fix_len) {
00372                         return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
00373                                               "Bad character conversion");
00374                 }
00375                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
00376                 if (pad_len != 0) {
00377                         NDR_CHECK(ndr_push_zero(ndr, pad_len));
00378                 }
00379                 break;
00380         }
00381 
00382         default:
00383                 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
00384                                       ndr->flags & LIBNDR_STRING_FLAGS);
00385         }
00386 
00387         talloc_free(dest);
00388 
00389         return NT_STATUS_OK;
00390 }
00391 
00392 /**
00393   push a general string onto the wire
00394 */
00395 size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
00396 {
00397         size_t c_len;
00398         unsigned flags = ndr->flags;
00399         unsigned byte_mul = 2;
00400         unsigned c_len_term = 1;
00401 
00402         if (flags & LIBNDR_FLAG_STR_FIXLEN32) {
00403                 return 32;
00404         }
00405         if (flags & LIBNDR_FLAG_STR_FIXLEN15) {
00406                 return 15;
00407         }
00408         
00409         c_len = s?strlen(s):0;
00410 
00411         if (flags & (LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_UTF8)) {
00412                 byte_mul = 1;
00413         }
00414 
00415         if (flags & LIBNDR_FLAG_STR_NOTERM) {
00416                 c_len_term = 0;
00417         }
00418 
00419         c_len = c_len + c_len_term;
00420 
00421         if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
00422                 c_len = c_len * byte_mul;
00423         }
00424 
00425         return c_len;
00426 }
00427 
00428 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
00429 {
00430         if (s) {
00431                 ndr->print(ndr, "%-25s: '%s'", name, s);
00432         } else {
00433                 ndr->print(ndr, "%-25s: NULL", name);
00434         }
00435 }
00436 
00437 uint32_t ndr_size_string(int ret, const char * const* string, int flags) 
00438 {
00439         /* FIXME: Is this correct for all strings ? */
00440         if(!(*string)) return ret;
00441         return ret+strlen(*string)+1;
00442 }
00443 
00444 /**
00445   pull a general string array from the wire
00446 */
00447 NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, const char ***_a)
00448 {
00449         const char **a = *_a;
00450         uint32_t count;
00451 
00452         if (!(ndr_flags & NDR_SCALARS)) {
00453                 return NT_STATUS_OK;
00454         }
00455 
00456         for (count = 0;; count++) {
00457                 TALLOC_CTX *tmp_ctx;
00458                 const char *s = NULL;
00459                 a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2);
00460                 NT_STATUS_HAVE_NO_MEMORY(a);
00461                 a[count]   = NULL;
00462                 a[count+1]   = NULL;
00463 
00464                 tmp_ctx = ndr->current_mem_ctx;
00465                 ndr->current_mem_ctx = a;
00466                 NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s));
00467                 ndr->current_mem_ctx = tmp_ctx;
00468                 if (strcmp("", s)==0) {
00469                         a[count] = NULL;
00470                         break;
00471                 } else {
00472                         a[count] = s;
00473                 }
00474         }
00475 
00476         *_a =a;
00477         return NT_STATUS_OK;
00478 }
00479 
00480 /**
00481   push a general string array onto the wire
00482 */
00483 NTSTATUS ndr_push_string_array(struct ndr_push *ndr, int ndr_flags, const char **a)
00484 {
00485         uint32_t count;
00486 
00487         if (!(ndr_flags & NDR_SCALARS)) {
00488                 return NT_STATUS_OK;
00489         }
00490 
00491         for (count = 0; a && a[count]; count++) {
00492                 NDR_CHECK(ndr_push_string(ndr, ndr_flags, a[count]));
00493         }
00494 
00495         NDR_CHECK(ndr_push_string(ndr, ndr_flags, ""));
00496 
00497         return NT_STATUS_OK;
00498 }
00499 
00500 void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a)
00501 {
00502         uint32_t count;
00503         uint32_t i;
00504 
00505         for (count = 0; a && a[count]; count++) {}
00506 
00507         ndr->print(ndr, "%s: ARRAY(%d)", name, count);
00508         ndr->depth++;
00509         for (i=0;i<count;i++) {
00510                 char *idx=NULL;
00511                 asprintf(&idx, "[%d]", i);
00512                 if (idx) {
00513                         ndr_print_string(ndr, idx, a[i]);
00514                         free(idx);
00515                 }
00516         }
00517         ndr->depth--;
00518 }
00519 
00520 /**
00521  * Return number of elements in a string including the last (zeroed) element 
00522  */
00523 uint32_t ndr_string_length(const void *_var, uint32_t element_size)
00524 {
00525         uint32_t i;
00526         uint8_t zero[4] = {0,0,0,0};
00527         const char *var = (const char *)_var;
00528 
00529         for (i = 0; memcmp(var+i*element_size,zero,element_size) != 0; i++);
00530 
00531         return i+1;
00532 }
00533 
00534 NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
00535 {
00536         uint32_t i;
00537         struct ndr_pull_save save_offset;
00538 
00539         ndr_pull_save(ndr, &save_offset);
00540         ndr_pull_advance(ndr, (count - 1) * element_size);
00541         NDR_PULL_NEED_BYTES(ndr, element_size);
00542 
00543         for (i = 0; i < element_size; i++) {
00544                  if (ndr->data[ndr->offset+i] != 0) {
00545                         ndr_pull_restore(ndr, &save_offset);
00546 
00547                         return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "String terminator not present or outside string boundaries");
00548                  }
00549         }
00550 
00551         ndr_pull_restore(ndr, &save_offset);
00552 
00553         return NT_STATUS_OK;
00554 }
00555 
00556 NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, charset_t chset)
00557 {
00558         int ret;
00559         if (length == 0) {
00560                 *var = talloc_strdup(ndr->current_mem_ctx, "");
00561                 return NT_STATUS_OK;
00562         }
00563 
00564         if (NDR_BE(ndr) && chset == CH_UTF16) {
00565                 chset = CH_UTF16BE;
00566         }
00567 
00568         NDR_PULL_NEED_BYTES(ndr, length*byte_mul);
00569 
00570         ret = convert_string_talloc(ndr->current_mem_ctx,
00571                                     chset, CH_UNIX, 
00572                                     ndr->data+ndr->offset, 
00573                                     length*byte_mul,
00574                                     var, False);
00575         if (ret == -1) {
00576                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
00577                                       "Bad character conversion");
00578         }
00579         NDR_CHECK(ndr_pull_advance(ndr, length*byte_mul));
00580 
00581         return NT_STATUS_OK;
00582 }
00583 
00584 NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var,
00585                           uint32_t length, uint8_t byte_mul, charset_t chset)
00586 {
00587         ssize_t ret, required;
00588 
00589         if (NDR_BE(ndr) && chset == CH_UTF16) {
00590                 chset = CH_UTF16BE;
00591         }
00592 
00593         required = byte_mul * length;
00594         
00595         NDR_PUSH_NEED_BYTES(ndr, required);
00596         ret = convert_string(CH_UNIX, chset, 
00597                              var, strlen(var),
00598                              ndr->data+ndr->offset, required, False);
00599         if (ret == -1) {
00600                 return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
00601                                       "Bad character conversion");
00602         }
00603 
00604         /* Make sure the remaining part of the string is filled with zeroes */
00605         if (ret < required) {
00606                 memset(ndr->data+ndr->offset+ret, 0, required-ret);
00607         }
00608 
00609         ndr->offset += required;
00610 
00611         return NT_STATUS_OK;
00612 }
00613 
00614 /* Return number of elements in a string in the specified charset */
00615 uint32_t ndr_charset_length(const void *var, int chset)
00616 {
00617         /* FIXME: Treat special chars special here, taking chset into account */
00618         /* Also include 0 byte */
00619         return strlen((const char *)var)+1;
00620 }

Sambaに対してSat Aug 29 21:23:04 2009に生成されました。  doxygen 1.4.7