The Samba-Bugzilla – Attachment 5082 Details for
Bug 6883
Add Printer fails with 0x000006f7 on Windows 7
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
remaing patch for master (after much more testing)
v3-4-test.patch (text/plain), 69.19 KB, created by
Guenther Deschner
on 2009-12-11 08:08:57 UTC
(
hide
)
Description:
remaing patch for master (after much more testing)
Filename:
MIME Type:
Creator:
Guenther Deschner
Created:
2009-12-11 08:08:57 UTC
Size:
69.19 KB
patch
obsolete
>From 0d62e53390a447197a8f1249bfe2750fb77408c2 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Mon, 23 Nov 2009 13:35:32 +0100 >Subject: [PATCH 01/13] s4-smbtorture: fix spoolss_EnumPrinterKey client in RPC-SPOOLSS-WIN. > >Guenther >--- > source4/torture/rpc/spoolss_win.c | 22 ++++++++++++++++++---- > 1 files changed, 18 insertions(+), 4 deletions(-) > >diff --git a/source4/torture/rpc/spoolss_win.c b/source4/torture/rpc/spoolss_win.c >index 719d8e2..df1a47d 100644 >--- a/source4/torture/rpc/spoolss_win.c >+++ b/source4/torture/rpc/spoolss_win.c >@@ -23,6 +23,7 @@ > #include "torture/rpc/rpc.h" > #include "librpc/gen_ndr/ndr_spoolss_c.h" > #include "rpc_server/dcerpc_server.h" >+#include "librpc/gen_ndr/ndr_misc.h" > #include "ntvfs/ntvfs.h" > #include "param/param.h" > >@@ -177,7 +178,7 @@ static bool test_GetPrinterData(struct torture_context *tctx, > if (W_ERROR_IS_OK(expected_werr)) { > torture_assert_int_equal(tctx, data.value, > expected_value, >- "GetPrinterData did not return expected value."); >+ talloc_asprintf(tctx, "GetPrinterData for %s did not return expected value.", value_name)); > } > return true; > } >@@ -385,15 +386,17 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > NTSTATUS status; > struct spoolss_EnumPrinterKey epk; > uint32_t needed = 0; >- const char **key_buffer = NULL; >+ uint16_t *key_buffer; > > torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key); > >+ key_buffer = talloc_zero_array(tctx, uint16_t, 0); >+ > epk.in.handle = handle; > epk.in.key_name = talloc_strdup(tctx, key); > epk.in.offered = 0; > epk.out.needed = &needed; >- epk.out.key_buffer = &key_buffer; >+ epk.out.key_buffer = key_buffer; > > status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); > torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed"); >@@ -401,6 +404,8 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > > if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) { > epk.in.offered = needed; >+ key_buffer = talloc_zero_array(tctx, uint16_t, needed/2); >+ epk.out.key_buffer = key_buffer; > status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); > torture_assert_ntstatus_ok(tctx, status, > "EnumPrinterKey failed"); >@@ -408,7 +413,16 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > > torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed"); > >- ctx->printer_keys = key_buffer; >+ { >+ union winreg_Data data; >+ enum ndr_err_code ndr_err; >+ DATA_BLOB blob = data_blob_const(key_buffer, needed); >+ ndr_err = ndr_pull_union_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx), >+ &data, REG_MULTI_SZ, >+ (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); >+ torture_assert_ndr_success(tctx, ndr_err, "failed to pull REG_MULTI_SZ"); >+ ctx->printer_keys = data.string_array; >+ } > > return true; > } >-- >1.6.5.2 > > >From b3332a8c91177cdbb9c7957f4c517d8c93974e5a Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Fri, 20 Nov 2009 16:33:29 +0100 >Subject: [PATCH 02/13] s4-smbtorture: add tests for spoolss_EnumPrinterKey to RPC-SPOOLSS-PRINTER. > >Guenther >--- > source4/torture/rpc/spoolss.c | 73 +++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 73 insertions(+), 0 deletions(-) > >diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c >index bfe6672..895f6b9 100644 >--- a/source4/torture/rpc/spoolss.c >+++ b/source4/torture/rpc/spoolss.c >@@ -23,7 +23,9 @@ > #include "includes.h" > #include "torture/torture.h" > #include "torture/rpc/rpc.h" >+#include "librpc/gen_ndr/ndr_misc.h" > #include "librpc/gen_ndr/ndr_spoolss_c.h" >+#include "param/param.h" > > struct test_spoolss_context { > /* print server handle */ >@@ -2000,6 +2002,77 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, > return true; > } > >+bool test_printer_keys(struct torture_context *tctx, >+ struct dcerpc_pipe *p, >+ struct policy_handle *handle) >+{ >+ DATA_BLOB blob; >+ const char **key_array = NULL; >+ int i; >+ >+ { >+ struct spoolss_EnumPrinterKey r; >+ uint32_t needed; >+ uint16_t *key_buffer = talloc_zero_array(tctx, uint16_t, 0); >+ >+ r.in.handle = handle; >+ r.in.key_name = ""; >+ r.in.offered = 0; >+ r.out.key_buffer = key_buffer; >+ r.out.needed = &needed; >+ >+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), >+ "failed to call EnumPrinterKey"); >+ if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { >+ r.in.offered = needed; >+ key_buffer = talloc_zero_array(tctx, uint16_t, needed/2); >+ r.out.key_buffer = key_buffer; >+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), >+ "failed to call EnumPrinterKey"); >+ } >+ torture_assert_werr_ok(tctx, r.out.result, >+ "failed to call EnumPrinterKey"); >+ >+ blob = data_blob_const(key_buffer, needed); >+ } >+ >+ { >+ union winreg_Data data; >+ enum ndr_err_code ndr_err; >+ ndr_err = ndr_pull_union_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx), >+ &data, REG_MULTI_SZ, >+ (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); >+ torture_assert_ndr_success(tctx, ndr_err, "failed to pull REG_MULTI_SZ"); >+ key_array = data.string_array; >+ } >+ >+ for (i=0; key_array[i]; i++) { >+ struct spoolss_EnumPrinterDataEx r; >+ uint32_t count; >+ struct spoolss_PrinterEnumValues *info; >+ uint32_t needed; >+ >+ r.in.handle = handle; >+ r.in.key_name = key_array[i]; >+ r.in.offered = 0; >+ r.out.count = &count; >+ r.out.info = &info; >+ r.out.needed = &needed; >+ >+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r), >+ "failed to call EnumPrinterDataEx"); >+ if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { >+ r.in.offered = needed; >+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r), >+ "failed to call EnumPrinterDataEx"); >+ } >+ torture_assert_werr_ok(tctx, r.out.result, >+ "failed to call EnumPrinterDataEx"); >+ } >+ >+ return true; >+} >+ > bool torture_rpc_spoolss(struct torture_context *torture) > { > NTSTATUS status; >-- >1.6.5.2 > > >From 389015795e4cb66b18f7bb5d39d2e597040111e1 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Wed, 2 Dec 2009 14:22:52 +0100 >Subject: [PATCH 03/13] spoolss: add spoolss_StringArray2. > >The difference to spoolss_StringArray is that in spoolss_StringArray2 the string >array is put into a subcontext of _ndr_size. > >Guenther >--- > librpc/gen_ndr/ndr_spoolss.c | 53 ++++++++++++++++++++++++++++++++++++++++++ > librpc/gen_ndr/ndr_spoolss.h | 3 ++ > librpc/gen_ndr/spoolss.h | 5 ++++ > librpc/idl/spoolss.idl | 5 ++++ > librpc/ndr/ndr_spoolss_buf.c | 9 +++++++ > librpc/ndr/ndr_spoolss_buf.h | 1 + > 6 files changed, 76 insertions(+), 0 deletions(-) > >diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c >index d03196e..0b67e80 100644 >--- a/librpc/gen_ndr/ndr_spoolss.c >+++ b/librpc/gen_ndr/ndr_spoolss.c >@@ -7421,6 +7421,59 @@ _PUBLIC_ void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *n > ndr->depth--; > } > >+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r) >+{ >+ if (ndr_flags & NDR_SCALARS) { >+ NDR_CHECK(ndr_push_align(ndr, 4)); >+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2)); >+ { >+ uint32_t _flags_save_string_array = ndr->flags; >+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >+ { >+ struct ndr_push *_ndr_string; >+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_string, 0, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2 * 2)); >+ NDR_CHECK(ndr_push_string_array(_ndr_string, NDR_SCALARS, r->string)); >+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_string, 0, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2 * 2)); >+ } >+ ndr->flags = _flags_save_string_array; >+ } >+ } >+ if (ndr_flags & NDR_BUFFERS) { >+ } >+ return NDR_ERR_SUCCESS; >+} >+ >+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r) >+{ >+ if (ndr_flags & NDR_SCALARS) { >+ NDR_CHECK(ndr_pull_align(ndr, 4)); >+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); >+ { >+ uint32_t _flags_save_string_array = ndr->flags; >+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >+ { >+ struct ndr_pull *_ndr_string; >+ NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_string, 0, r->_ndr_size * 2)); >+ NDR_CHECK(ndr_pull_string_array(_ndr_string, NDR_SCALARS, &r->string)); >+ NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_string, 0, r->_ndr_size * 2)); >+ } >+ ndr->flags = _flags_save_string_array; >+ } >+ } >+ if (ndr_flags & NDR_BUFFERS) { >+ } >+ return NDR_ERR_SUCCESS; >+} >+ >+_PUBLIC_ void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r) >+{ >+ ndr_print_struct(ndr, name, "spoolss_StringArray2"); >+ ndr->depth++; >+ ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?(ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2:r->_ndr_size); >+ ndr_print_string_array(ndr, "string", r->string); >+ ndr->depth--; >+} >+ > static enum ndr_err_code ndr_push_spoolss_AddDriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_AddDriverInfo1 *r) > { > if (ndr_flags & NDR_SCALARS) { >diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h >index 204aad8..fbf056f 100644 >--- a/librpc/gen_ndr/ndr_spoolss.h >+++ b/librpc/gen_ndr/ndr_spoolss.h >@@ -303,6 +303,9 @@ void ndr_print_spoolss_SetPrinterInfoCtr(struct ndr_print *ndr, const char *name > enum ndr_err_code ndr_push_spoolss_StringArray(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray *r); > enum ndr_err_code ndr_pull_spoolss_StringArray(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray *r); > void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray *r); >+enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r); >+enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r); >+void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r); > void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo1 *r); > enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r); > enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r); >diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h >index 2053065..1d2cf5b 100644 >--- a/librpc/gen_ndr/spoolss.h >+++ b/librpc/gen_ndr/spoolss.h >@@ -723,6 +723,11 @@ struct spoolss_StringArray { > const char ** string;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */ > }/* [public] */; > >+struct spoolss_StringArray2 { >+ uint32_t _ndr_size;/* [value((ndr_size_spoolss_StringArray2(r,ndr->iconv_convenience,ndr->flags)-4)/2)] */ >+ const char ** string;/* [subcontext_size(_ndr_size*2),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */ >+}/* [public] */; >+ > struct spoolss_AddDriverInfo1 { > const char *driver_name;/* [unique,charset(UTF16)] */ > }; >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index e4f03e5..cb34138 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -786,6 +786,11 @@ import "misc.idl", "security.idl", "winreg.idl"; > /*[subcontext(0),subcontext_size(_ndr_size*2)]*/ nstring_array string; > } spoolss_StringArray; > >+ typedef [public] struct { >+ [value((ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags)-4)/2)] uint32 _ndr_size; >+ [subcontext(0),subcontext_size(_ndr_size*2)] nstring_array string; >+ } spoolss_StringArray2; >+ > typedef struct { > [string,charset(UTF16)] uint16 *driver_name; > } spoolss_AddDriverInfo1; >diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c >index 0acae3d..9968e90 100644 >--- a/librpc/ndr/ndr_spoolss_buf.c >+++ b/librpc/ndr/ndr_spoolss_buf.c >@@ -708,6 +708,15 @@ _PUBLIC_ size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r > return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); > } > >+_PUBLIC_ size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags) >+{ >+ if (!r) { >+ return 4; >+ } >+ >+ return ndr_size_struct((const struct spoolss_StringArray *)r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); >+} >+ > /* hand marshall as pidl cannot (yet) generate a relative pointer to a fixed array of > * structs */ > >diff --git a/librpc/ndr/ndr_spoolss_buf.h b/librpc/ndr/ndr_spoolss_buf.h >index aa6e277..9a76f82 100644 >--- a/librpc/ndr/ndr_spoolss_buf.h >+++ b/librpc/ndr/ndr_spoolss_buf.h >@@ -47,6 +47,7 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag > enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r); > uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct smb_iconv_convenience *ic, uint32_t flags); > size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags); >+size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags); > _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); > _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); > void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, const union spoolss_Field *r); >-- >1.6.5.2 > > >From 540251731a95cd5bdd534b39305d44d83a49d4c3 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Wed, 2 Dec 2009 14:53:39 +0100 >Subject: [PATCH 04/13] samba-spoolss: use spoolss_StringArray2 in spoolss_EnumPrinterKey. > >This should finally resolve the endian issues we were seeing on sparc and is >much cleaner for spoolss clients and servers. > >Guenther >--- > librpc/gen_ndr/cli_spoolss.c | 4 +- > librpc/gen_ndr/cli_spoolss.h | 2 +- > librpc/gen_ndr/ndr_spoolss.c | 41 ++++++++-------------------------- > librpc/gen_ndr/spoolss.h | 2 +- > librpc/gen_ndr/srv_spoolss.c | 4 +- > librpc/idl/spoolss.idl | 2 +- > source3/rpc_client/cli_spoolss.c | 24 +++----------------- > source3/rpc_server/srv_spoolss_nt.c | 2 +- > source4/torture/rpc/spoolss.c | 19 ++------------- > source4/torture/rpc/spoolss_win.c | 19 ++------------- > 10 files changed, 28 insertions(+), 91 deletions(-) > >diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c >index b605f58..244245d 100644 >--- a/librpc/gen_ndr/cli_spoolss.c >+++ b/librpc/gen_ndr/cli_spoolss.c >@@ -3811,7 +3811,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, > TALLOC_CTX *mem_ctx, > struct policy_handle *handle /* [in] [ref] */, > const char *key_name /* [in] [charset(UTF16)] */, >- uint16_t *key_buffer /* [out] [ref,size_is(offered/2)] */, >+ struct spoolss_StringArray2 *key_buffer /* [out] [ref] */, > uint32_t offered /* [in] */, > uint32_t *needed /* [out] [ref] */, > WERROR *werror) >@@ -3847,7 +3847,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, > } > > /* Return variables */ >- memcpy(key_buffer, r.out.key_buffer, (r.in.offered / 2) * sizeof(*key_buffer)); >+ *key_buffer = *r.out.key_buffer; > *needed = *r.out.needed; > > /* Return result */ >diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h >index 4c621f4..f97bf9a 100644 >--- a/librpc/gen_ndr/cli_spoolss.h >+++ b/librpc/gen_ndr/cli_spoolss.h >@@ -497,7 +497,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, > TALLOC_CTX *mem_ctx, > struct policy_handle *handle /* [in] [ref] */, > const char *key_name /* [in] [charset(UTF16)] */, >- uint16_t *key_buffer /* [out] [ref,size_is(offered/2)] */, >+ struct spoolss_StringArray2 *key_buffer /* [out] [ref] */, > uint32_t offered /* [in] */, > uint32_t *needed /* [out] [ref] */, > WERROR *werror); >diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c >index 0b67e80..a1d7f8f 100644 >--- a/librpc/gen_ndr/ndr_spoolss.c >+++ b/librpc/gen_ndr/ndr_spoolss.c >@@ -26672,7 +26672,6 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const c > > _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterKey *r) > { >- uint32_t cntr_key_buffer_1; > if (flags & NDR_IN) { > if (r->in.handle == NULL) { > return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); >@@ -26688,10 +26687,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, > if (r->out.key_buffer == NULL) { > return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); > } >- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered / 2)); >- for (cntr_key_buffer_1 = 0; cntr_key_buffer_1 < r->in.offered / 2; cntr_key_buffer_1++) { >- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->out.key_buffer[cntr_key_buffer_1])); >- } >+ NDR_CHECK(ndr_push_spoolss_StringArray2(ndr, NDR_SCALARS, r->out.key_buffer)); > if (r->out.needed == NULL) { > return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); > } >@@ -26703,9 +26699,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, > > _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterKey *r) > { >- uint32_t cntr_key_buffer_1; > TALLOC_CTX *_mem_save_handle_0; >- TALLOC_CTX *_mem_save_key_buffer_1; >+ TALLOC_CTX *_mem_save_key_buffer_0; > TALLOC_CTX *_mem_save_needed_0; > if (flags & NDR_IN) { > ZERO_STRUCT(r->out); >@@ -26725,22 +26720,19 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, > NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t))); > NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.key_name, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t), CH_UTF16)); > NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered)); >- NDR_PULL_ALLOC_N(ndr, r->out.key_buffer, r->in.offered / 2); >- memset(r->out.key_buffer, 0, (r->in.offered / 2) * sizeof(*r->out.key_buffer)); >+ NDR_PULL_ALLOC(ndr, r->out.key_buffer); >+ ZERO_STRUCTP(r->out.key_buffer); > NDR_PULL_ALLOC(ndr, r->out.needed); > ZERO_STRUCTP(r->out.needed); > } > if (flags & NDR_OUT) { >- NDR_CHECK(ndr_pull_array_size(ndr, &r->out.key_buffer)); > if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { >- NDR_PULL_ALLOC_N(ndr, r->out.key_buffer, ndr_get_array_size(ndr, &r->out.key_buffer)); >- } >- _mem_save_key_buffer_1 = NDR_PULL_GET_MEM_CTX(ndr); >- NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, 0); >- for (cntr_key_buffer_1 = 0; cntr_key_buffer_1 < r->in.offered / 2; cntr_key_buffer_1++) { >- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->out.key_buffer[cntr_key_buffer_1])); >+ NDR_PULL_ALLOC(ndr, r->out.key_buffer); > } >- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_1, 0); >+ _mem_save_key_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr); >+ NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, LIBNDR_FLAG_REF_ALLOC); >+ NDR_CHECK(ndr_pull_spoolss_StringArray2(ndr, NDR_SCALARS, r->out.key_buffer)); >+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_0, LIBNDR_FLAG_REF_ALLOC); > if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { > NDR_PULL_ALLOC(ndr, r->out.needed); > } >@@ -26749,16 +26741,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, > NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.needed)); > NDR_PULL_SET_MEM_CTX(ndr, _mem_save_needed_0, LIBNDR_FLAG_REF_ALLOC); > NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); >- if (r->out.key_buffer) { >- NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.key_buffer, r->in.offered / 2)); >- } > } > return NDR_ERR_SUCCESS; > } > > _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinterKey *r) > { >- uint32_t cntr_key_buffer_1; > ndr_print_struct(ndr, name, "spoolss_EnumPrinterKey"); > ndr->depth++; > if (flags & NDR_SET_VALUES) { >@@ -26780,16 +26768,7 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char > ndr->depth++; > ndr_print_ptr(ndr, "key_buffer", r->out.key_buffer); > ndr->depth++; >- ndr->print(ndr, "%s: ARRAY(%d)", "key_buffer", (int)r->in.offered / 2); >- ndr->depth++; >- for (cntr_key_buffer_1=0;cntr_key_buffer_1<r->in.offered / 2;cntr_key_buffer_1++) { >- char *idx_1=NULL; >- if (asprintf(&idx_1, "[%d]", cntr_key_buffer_1) != -1) { >- ndr_print_uint16(ndr, "key_buffer", r->out.key_buffer[cntr_key_buffer_1]); >- free(idx_1); >- } >- } >- ndr->depth--; >+ ndr_print_spoolss_StringArray2(ndr, "key_buffer", r->out.key_buffer); > ndr->depth--; > ndr_print_ptr(ndr, "needed", r->out.needed); > ndr->depth++; >diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h >index 1d2cf5b..e7c125a 100644 >--- a/librpc/gen_ndr/spoolss.h >+++ b/librpc/gen_ndr/spoolss.h >@@ -3035,7 +3035,7 @@ struct spoolss_EnumPrinterKey { > } in; > > struct { >- uint16_t *key_buffer;/* [ref,size_is(offered/2)] */ >+ struct spoolss_StringArray2 *key_buffer;/* [ref] */ > uint32_t *needed;/* [ref] */ > WERROR result; > } out; >diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c >index 3bbe401..2d12587 100644 >--- a/librpc/gen_ndr/srv_spoolss.c >+++ b/librpc/gen_ndr/srv_spoolss.c >@@ -6296,7 +6296,7 @@ static bool api_spoolss_EnumPrinterKey(pipes_struct *p) > } > > ZERO_STRUCT(r->out); >- r->out.key_buffer = talloc_zero_array(r, uint16_t, r->in.offered / 2); >+ r->out.key_buffer = talloc_zero(r, struct spoolss_StringArray2); > if (r->out.key_buffer == NULL) { > talloc_free(r); > return false; >@@ -8399,7 +8399,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, > case NDR_SPOOLSS_ENUMPRINTERKEY: { > struct spoolss_EnumPrinterKey *r = (struct spoolss_EnumPrinterKey *)_r; > ZERO_STRUCT(r->out); >- r->out.key_buffer = talloc_zero_array(mem_ctx, uint16_t, r->in.offered / 2); >+ r->out.key_buffer = talloc_zero(mem_ctx, struct spoolss_StringArray2); > if (r->out.key_buffer == NULL) { > return NT_STATUS_NO_MEMORY; > } >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index cb34138..3d82dfa 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -2307,7 +2307,7 @@ import "misc.idl", "security.idl", "winreg.idl"; > [public] WERROR spoolss_EnumPrinterKey( > [in, ref] policy_handle *handle, > [in] [string,charset(UTF16)] uint16 key_name[], >- [out,ref] [size_is(offered/2)] uint16 *key_buffer, >+ [out,ref] spoolss_StringArray2 *key_buffer, > [in] uint32 offered, > [out,ref] uint32 *needed > ); >diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c >index 5522ca7..d2e6556 100644 >--- a/source3/rpc_client/cli_spoolss.c >+++ b/source3/rpc_client/cli_spoolss.c >@@ -760,44 +760,28 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, > NTSTATUS status; > WERROR werror; > uint32_t needed; >- uint16_t *buffer = NULL; >- >- *key_buffer = NULL; >- >- if (offered) { >- buffer = talloc_array(mem_ctx, uint16_t, offered/2); >- W_ERROR_HAVE_NO_MEMORY(buffer); >- } >+ struct spoolss_StringArray2 _key_buffer; > > status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, > handle, > key_name, >- buffer, >+ &_key_buffer, > offered, > &needed, > &werror); > > if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { > offered = needed; >- buffer = talloc_realloc(mem_ctx, buffer, uint16_t, needed/2); >- W_ERROR_HAVE_NO_MEMORY(buffer); > status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, > handle, > key_name, >- buffer, >+ &_key_buffer, > offered, > &needed, > &werror); > } > >- if (W_ERROR_IS_OK(werror)) { >- const char **array; >- DATA_BLOB blob = data_blob_const((uint8_t *)buffer, offered); >- if (!pull_reg_multi_sz(mem_ctx, &blob, &array)) { >- return WERR_NOMEM; >- } >- *key_buffer = array; >- } >+ *key_buffer = _key_buffer.string; > > return werror; > } >diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c >index af0c952..1dfae32 100644 >--- a/source3/rpc_server/srv_spoolss_nt.c >+++ b/source3/rpc_server/srv_spoolss_nt.c >@@ -9317,7 +9317,7 @@ WERROR _spoolss_EnumPrinterKey(pipes_struct *p, > result = WERR_MORE_DATA; > } else { > result = WERR_OK; >- memcpy(r->out.key_buffer, blob.data, blob.length); >+ r->out.key_buffer->string = array; > } > > done: >diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c >index 895f6b9..6f9d7d2 100644 >--- a/source4/torture/rpc/spoolss.c >+++ b/source4/torture/rpc/spoolss.c >@@ -2006,44 +2006,31 @@ bool test_printer_keys(struct torture_context *tctx, > struct dcerpc_pipe *p, > struct policy_handle *handle) > { >- DATA_BLOB blob; > const char **key_array = NULL; > int i; > > { > struct spoolss_EnumPrinterKey r; > uint32_t needed; >- uint16_t *key_buffer = talloc_zero_array(tctx, uint16_t, 0); >+ struct spoolss_StringArray2 key_buffer; > > r.in.handle = handle; > r.in.key_name = ""; > r.in.offered = 0; >- r.out.key_buffer = key_buffer; >+ r.out.key_buffer = &key_buffer; > r.out.needed = &needed; > > torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), > "failed to call EnumPrinterKey"); > if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { > r.in.offered = needed; >- key_buffer = talloc_zero_array(tctx, uint16_t, needed/2); >- r.out.key_buffer = key_buffer; > torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), > "failed to call EnumPrinterKey"); > } > torture_assert_werr_ok(tctx, r.out.result, > "failed to call EnumPrinterKey"); > >- blob = data_blob_const(key_buffer, needed); >- } >- >- { >- union winreg_Data data; >- enum ndr_err_code ndr_err; >- ndr_err = ndr_pull_union_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx), >- &data, REG_MULTI_SZ, >- (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); >- torture_assert_ndr_success(tctx, ndr_err, "failed to pull REG_MULTI_SZ"); >- key_array = data.string_array; >+ key_array = key_buffer.string; > } > > for (i=0; key_array[i]; i++) { >diff --git a/source4/torture/rpc/spoolss_win.c b/source4/torture/rpc/spoolss_win.c >index df1a47d..5439d9d 100644 >--- a/source4/torture/rpc/spoolss_win.c >+++ b/source4/torture/rpc/spoolss_win.c >@@ -386,17 +386,15 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > NTSTATUS status; > struct spoolss_EnumPrinterKey epk; > uint32_t needed = 0; >- uint16_t *key_buffer; >+ struct spoolss_StringArray2 key_buffer; > > torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key); > >- key_buffer = talloc_zero_array(tctx, uint16_t, 0); >- > epk.in.handle = handle; > epk.in.key_name = talloc_strdup(tctx, key); > epk.in.offered = 0; > epk.out.needed = &needed; >- epk.out.key_buffer = key_buffer; >+ epk.out.key_buffer = &key_buffer; > > status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); > torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed"); >@@ -404,8 +402,6 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > > if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) { > epk.in.offered = needed; >- key_buffer = talloc_zero_array(tctx, uint16_t, needed/2); >- epk.out.key_buffer = key_buffer; > status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); > torture_assert_ntstatus_ok(tctx, status, > "EnumPrinterKey failed"); >@@ -413,16 +409,7 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > > torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed"); > >- { >- union winreg_Data data; >- enum ndr_err_code ndr_err; >- DATA_BLOB blob = data_blob_const(key_buffer, needed); >- ndr_err = ndr_pull_union_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx), >- &data, REG_MULTI_SZ, >- (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); >- torture_assert_ndr_success(tctx, ndr_err, "failed to pull REG_MULTI_SZ"); >- ctx->printer_keys = data.string_array; >- } >+ ctx->printer_keys = key_buffer.string; > > return true; > } >-- >1.6.5.2 > > >From 822d79a823a00840fea3d15d557906707fe25df6 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 3 Dec 2009 23:23:36 +0100 >Subject: [PATCH 05/13] s3-spoolss: handle SEC_FLAG_MAXIMUM_ALLOWED in spoolss_OpenPrinterEx. > >In case someone (smbtorture4) requests SEC_FLAG_MAXIMUM_ALLOWED, translate it >to a request of PRINTER_ACCESS_ADMINISTER. > >Guenther >(cherry picked from commit 459a968fb4d6f96ea7f310f331d3547e2e466d6a) >--- > source3/rpc_server/srv_spoolss_nt.c | 4 ++++ > 1 files changed, 4 insertions(+), 0 deletions(-) > >diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c >index 1dfae32..ecad469 100644 >--- a/source3/rpc_server/srv_spoolss_nt.c >+++ b/source3/rpc_server/srv_spoolss_nt.c >@@ -1670,6 +1670,10 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, > return WERR_BADFID; > } > >+ if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) { >+ r->in.access_mask = PRINTER_ACCESS_ADMINISTER; >+ } >+ > se_map_standard(&r->in.access_mask, &printer_std_mapping); > > /* map an empty access mask to the minimum access mask */ >-- >1.6.5.2 > > >From f31a721ad09116f7ab7a668b23fe56bf39951a9e Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Wed, 2 Dec 2009 21:26:10 +0100 >Subject: [PATCH 06/13] spoolss: hand-marshall the spoolss_StringArray2 struct for spoolss_EnumPrinterKey. > >This call is just driving me nuts :-) > >Guenther >--- > librpc/gen_ndr/ndr_spoolss.c | 44 ------------------------------ > librpc/gen_ndr/spoolss.h | 2 +- > librpc/idl/spoolss.idl | 2 +- > librpc/ndr/ndr_spoolss_buf.c | 60 +++++++++++++++++++++++++++++++++++++++-- > librpc/ndr/ndr_spoolss_buf.h | 2 + > 5 files changed, 61 insertions(+), 49 deletions(-) > >diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c >index a1d7f8f..587819c 100644 >--- a/librpc/gen_ndr/ndr_spoolss.c >+++ b/librpc/gen_ndr/ndr_spoolss.c >@@ -7421,50 +7421,6 @@ _PUBLIC_ void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *n > ndr->depth--; > } > >-_PUBLIC_ enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r) >-{ >- if (ndr_flags & NDR_SCALARS) { >- NDR_CHECK(ndr_push_align(ndr, 4)); >- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2)); >- { >- uint32_t _flags_save_string_array = ndr->flags; >- ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >- { >- struct ndr_push *_ndr_string; >- NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_string, 0, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2 * 2)); >- NDR_CHECK(ndr_push_string_array(_ndr_string, NDR_SCALARS, r->string)); >- NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_string, 0, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2 * 2)); >- } >- ndr->flags = _flags_save_string_array; >- } >- } >- if (ndr_flags & NDR_BUFFERS) { >- } >- return NDR_ERR_SUCCESS; >-} >- >-_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r) >-{ >- if (ndr_flags & NDR_SCALARS) { >- NDR_CHECK(ndr_pull_align(ndr, 4)); >- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); >- { >- uint32_t _flags_save_string_array = ndr->flags; >- ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >- { >- struct ndr_pull *_ndr_string; >- NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_string, 0, r->_ndr_size * 2)); >- NDR_CHECK(ndr_pull_string_array(_ndr_string, NDR_SCALARS, &r->string)); >- NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_string, 0, r->_ndr_size * 2)); >- } >- ndr->flags = _flags_save_string_array; >- } >- } >- if (ndr_flags & NDR_BUFFERS) { >- } >- return NDR_ERR_SUCCESS; >-} >- > _PUBLIC_ void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r) > { > ndr_print_struct(ndr, name, "spoolss_StringArray2"); >diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h >index e7c125a..f70438d 100644 >--- a/librpc/gen_ndr/spoolss.h >+++ b/librpc/gen_ndr/spoolss.h >@@ -726,7 +726,7 @@ struct spoolss_StringArray { > struct spoolss_StringArray2 { > uint32_t _ndr_size;/* [value((ndr_size_spoolss_StringArray2(r,ndr->iconv_convenience,ndr->flags)-4)/2)] */ > const char ** string;/* [subcontext_size(_ndr_size*2),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */ >-}/* [public] */; >+}/* [nopush,public,nopull] */; > > struct spoolss_AddDriverInfo1 { > const char *driver_name;/* [unique,charset(UTF16)] */ >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index 3d82dfa..2e47eb6 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -786,7 +786,7 @@ import "misc.idl", "security.idl", "winreg.idl"; > /*[subcontext(0),subcontext_size(_ndr_size*2)]*/ nstring_array string; > } spoolss_StringArray; > >- typedef [public] struct { >+ typedef [public,nopush,nopull] struct { > [value((ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags)-4)/2)] uint32 _ndr_size; > [subcontext(0),subcontext_size(_ndr_size*2)] nstring_array string; > } spoolss_StringArray2; >diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c >index 9968e90..0527197 100644 >--- a/librpc/ndr/ndr_spoolss_buf.c >+++ b/librpc/ndr/ndr_spoolss_buf.c >@@ -708,13 +708,67 @@ _PUBLIC_ size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r > return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); > } > >+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r) >+{ >+ if (ndr_flags & NDR_SCALARS) { >+ uint32_t _ndr_size; >+ _ndr_size = ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags); >+ NDR_CHECK(ndr_push_align(ndr, 4)); >+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size)); >+ if (_ndr_size > 0) { >+ uint32_t _flags_save_string_array = ndr->flags; >+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >+ { >+ struct ndr_push *_ndr_string; >+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_string, 0, _ndr_size * 2)); >+ NDR_CHECK(ndr_push_string_array(_ndr_string, NDR_SCALARS, r->string)); >+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_string, 0, _ndr_size * 2)); >+ } >+ ndr->flags = _flags_save_string_array; >+ } >+ } >+ if (ndr_flags & NDR_BUFFERS) { >+ } >+ return NDR_ERR_SUCCESS; >+} >+ > _PUBLIC_ size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags) > { >- if (!r) { >- return 4; >+ uint32_t i; >+ >+ if (!r || !r->string) { >+ return 0; > } > >- return ndr_size_struct((const struct spoolss_StringArray *)r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); >+ for (i=0; r->string[i]; i++) { >+ ;; >+ } >+ >+ return (ndr_size_string_array(r->string, i, LIBNDR_FLAG_STR_NULLTERM) + 1); >+} >+ >+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r) >+{ >+ if (ndr_flags & NDR_SCALARS) { >+ NDR_CHECK(ndr_pull_align(ndr, 4)); >+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); >+ if (r->_ndr_size) { >+ uint32_t _flags_save_string_array = ndr->flags; >+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >+ { >+ struct ndr_pull *_ndr_string; >+ NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_string, 0, r->_ndr_size * 2)); >+ NDR_CHECK(ndr_pull_string_array(_ndr_string, NDR_SCALARS, &r->string)); >+ NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_string, 0, r->_ndr_size * 2)); >+ } >+ ndr->flags = _flags_save_string_array; >+ } else { >+ r->string = NULL; >+ } >+ } >+ if (ndr_flags & NDR_BUFFERS) { >+ } >+ return NDR_ERR_SUCCESS; > } > > /* hand marshall as pidl cannot (yet) generate a relative pointer to a fixed array of >diff --git a/librpc/ndr/ndr_spoolss_buf.h b/librpc/ndr/ndr_spoolss_buf.h >index 9a76f82..74d0b52 100644 >--- a/librpc/ndr/ndr_spoolss_buf.h >+++ b/librpc/ndr/ndr_spoolss_buf.h >@@ -47,6 +47,8 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag > enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r); > uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct smb_iconv_convenience *ic, uint32_t flags); > size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags); >+enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r); >+enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r); > size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags); > _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); > _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); >-- >1.6.5.2 > > >From 8da6ef825326461b02b65b71b63fdcfc8391df64 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 10 Dec 2009 14:18:46 +0100 >Subject: [PATCH 07/13] spoolss: add spoolss_KeyNames union. > >Guenther >(cherry picked from commit cf2561473f7bd0bcef5c562c1e901d4ad17e6ee3) >--- > librpc/idl/spoolss.idl | 6 ++++++ > 1 files changed, 6 insertions(+), 0 deletions(-) > >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index 2e47eb6..ae6aaeb 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -2302,6 +2302,12 @@ import "misc.idl", "security.idl", "winreg.idl"; > [out,ref] uint32 *needed > ); > >+ typedef [nodiscriminant] union { >+ [case(0)]; >+ [case(1)]; >+ [default] nstring_array string_array; >+ } spoolss_KeyNames; >+ > /******************/ > /* Function: 0x50 */ > [public] WERROR spoolss_EnumPrinterKey( >-- >1.6.5.2 > > >From 7bcc5fdd9f4a99455418d6c70d14041cb550a5f1 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 10 Dec 2009 14:19:28 +0100 >Subject: [PATCH 08/13] spoolss: use spoolss_KeyNames in spoolss_EnumPrinterKey. > >Guenther >(cherry picked from commit 0ecb7f6ab28d7b7c1844554289f5ae8e876b1dcf) >--- > librpc/idl/spoolss.idl | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index ae6aaeb..f2abc22 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -2313,7 +2313,8 @@ import "misc.idl", "security.idl", "winreg.idl"; > [public] WERROR spoolss_EnumPrinterKey( > [in, ref] policy_handle *handle, > [in] [string,charset(UTF16)] uint16 key_name[], >- [out,ref] spoolss_StringArray2 *key_buffer, >+ [out,ref] uint32 *_ndr_size, >+ [out,ref,subcontext(0),subcontext_size(*_ndr_size*2),switch_is(*_ndr_size)] spoolss_KeyNames *key_buffer, > [in] uint32 offered, > [out,ref] uint32 *needed > ); >-- >1.6.5.2 > > >From 1e5f68fd01feaacc951a5e89db7a080ad00da190 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Fri, 11 Dec 2009 11:02:55 +0100 >Subject: [PATCH 09/13] s3: re-run make samba3-idl. > >Guenther >--- > librpc/gen_ndr/cli_spoolss.c | 4 +- > librpc/gen_ndr/cli_spoolss.h | 3 +- > librpc/gen_ndr/ndr_spoolss.c | 134 +++++++++++++++++++++++++++++++++++++++++- > librpc/gen_ndr/ndr_spoolss.h | 1 + > librpc/gen_ndr/spoolss.h | 7 ++- > librpc/gen_ndr/srv_spoolss.c | 15 ++++- > 6 files changed, 156 insertions(+), 8 deletions(-) > >diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c >index 244245d..10dd8b4 100644 >--- a/librpc/gen_ndr/cli_spoolss.c >+++ b/librpc/gen_ndr/cli_spoolss.c >@@ -3811,7 +3811,8 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, > TALLOC_CTX *mem_ctx, > struct policy_handle *handle /* [in] [ref] */, > const char *key_name /* [in] [charset(UTF16)] */, >- struct spoolss_StringArray2 *key_buffer /* [out] [ref] */, >+ uint32_t *_ndr_size /* [out] [ref] */, >+ union spoolss_KeyNames *key_buffer /* [out] [subcontext_size(*_ndr_size*2),ref,subcontext(0),switch_is(*_ndr_size)] */, > uint32_t offered /* [in] */, > uint32_t *needed /* [out] [ref] */, > WERROR *werror) >@@ -3847,6 +3848,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, > } > > /* Return variables */ >+ *_ndr_size = *r.out._ndr_size; > *key_buffer = *r.out.key_buffer; > *needed = *r.out.needed; > >diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h >index f97bf9a..eb1e8dd 100644 >--- a/librpc/gen_ndr/cli_spoolss.h >+++ b/librpc/gen_ndr/cli_spoolss.h >@@ -497,7 +497,8 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, > TALLOC_CTX *mem_ctx, > struct policy_handle *handle /* [in] [ref] */, > const char *key_name /* [in] [charset(UTF16)] */, >- struct spoolss_StringArray2 *key_buffer /* [out] [ref] */, >+ uint32_t *_ndr_size /* [out] [ref] */, >+ union spoolss_KeyNames *key_buffer /* [out] [subcontext_size(*_ndr_size*2),ref,subcontext(0),switch_is(*_ndr_size)] */, > uint32_t offered /* [in] */, > uint32_t *needed /* [out] [ref] */, > WERROR *werror); >diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c >index 587819c..2766850 100644 >--- a/librpc/gen_ndr/ndr_spoolss.c >+++ b/librpc/gen_ndr/ndr_spoolss.c >@@ -18531,6 +18531,103 @@ _PUBLIC_ size_t ndr_size_spoolss_PrinterEnumValues(const struct spoolss_PrinterE > return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterEnumValues, ic); > } > >+static enum ndr_err_code ndr_push_spoolss_KeyNames(struct ndr_push *ndr, int ndr_flags, const union spoolss_KeyNames *r) >+{ >+ if (ndr_flags & NDR_SCALARS) { >+ int level = ndr_push_get_switch_value(ndr, r); >+ switch (level) { >+ case 0: { >+ break; } >+ >+ case 1: { >+ break; } >+ >+ default: { >+ { >+ uint32_t _flags_save_string_array = ndr->flags; >+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >+ NDR_CHECK(ndr_push_string_array(ndr, NDR_SCALARS, r->string_array)); >+ ndr->flags = _flags_save_string_array; >+ } >+ break; } >+ >+ } >+ } >+ if (ndr_flags & NDR_BUFFERS) { >+ int level = ndr_push_get_switch_value(ndr, r); >+ switch (level) { >+ case 0: >+ break; >+ >+ case 1: >+ break; >+ >+ default: >+ break; >+ >+ } >+ } >+ return NDR_ERR_SUCCESS; >+} >+ >+static enum ndr_err_code ndr_pull_spoolss_KeyNames(struct ndr_pull *ndr, int ndr_flags, union spoolss_KeyNames *r) >+{ >+ int level; >+ level = ndr_pull_get_switch_value(ndr, r); >+ if (ndr_flags & NDR_SCALARS) { >+ switch (level) { >+ case 0: { >+ break; } >+ >+ case 1: { >+ break; } >+ >+ default: { >+ { >+ uint32_t _flags_save_string_array = ndr->flags; >+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >+ NDR_CHECK(ndr_pull_string_array(ndr, NDR_SCALARS, &r->string_array)); >+ ndr->flags = _flags_save_string_array; >+ } >+ break; } >+ >+ } >+ } >+ if (ndr_flags & NDR_BUFFERS) { >+ switch (level) { >+ case 0: >+ break; >+ >+ case 1: >+ break; >+ >+ default: >+ break; >+ >+ } >+ } >+ return NDR_ERR_SUCCESS; >+} >+ >+_PUBLIC_ void ndr_print_spoolss_KeyNames(struct ndr_print *ndr, const char *name, const union spoolss_KeyNames *r) >+{ >+ int level; >+ level = ndr_print_get_switch_value(ndr, r); >+ ndr_print_union(ndr, name, level, "spoolss_KeyNames"); >+ switch (level) { >+ case 0: >+ break; >+ >+ case 1: >+ break; >+ >+ default: >+ ndr_print_string_array(ndr, "string_array", r->string_array); >+ break; >+ >+ } >+} >+ > _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DeleteDriverFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r) > { > NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); >@@ -26640,10 +26737,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, > NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered)); > } > if (flags & NDR_OUT) { >+ if (r->out._ndr_size == NULL) { >+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); >+ } >+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out._ndr_size)); > if (r->out.key_buffer == NULL) { > return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); > } >- NDR_CHECK(ndr_push_spoolss_StringArray2(ndr, NDR_SCALARS, r->out.key_buffer)); >+ { >+ struct ndr_push *_ndr_key_buffer; >+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_key_buffer, 0, *r->out._ndr_size * 2)); >+ NDR_CHECK(ndr_push_set_switch_value(_ndr_key_buffer, r->out.key_buffer, *r->out._ndr_size)); >+ NDR_CHECK(ndr_push_spoolss_KeyNames(_ndr_key_buffer, NDR_SCALARS|NDR_BUFFERS, r->out.key_buffer)); >+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_key_buffer, 0, *r->out._ndr_size * 2)); >+ } > if (r->out.needed == NULL) { > return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); > } >@@ -26656,6 +26763,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, > _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterKey *r) > { > TALLOC_CTX *_mem_save_handle_0; >+ TALLOC_CTX *_mem_save__ndr_size_0; > TALLOC_CTX *_mem_save_key_buffer_0; > TALLOC_CTX *_mem_save_needed_0; > if (flags & NDR_IN) { >@@ -26676,6 +26784,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, > NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t))); > NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.key_name, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t), CH_UTF16)); > NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered)); >+ NDR_PULL_ALLOC(ndr, r->out._ndr_size); >+ ZERO_STRUCTP(r->out._ndr_size); > NDR_PULL_ALLOC(ndr, r->out.key_buffer); > ZERO_STRUCTP(r->out.key_buffer); > NDR_PULL_ALLOC(ndr, r->out.needed); >@@ -26683,11 +26793,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, > } > if (flags & NDR_OUT) { > if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { >+ NDR_PULL_ALLOC(ndr, r->out._ndr_size); >+ } >+ _mem_save__ndr_size_0 = NDR_PULL_GET_MEM_CTX(ndr); >+ NDR_PULL_SET_MEM_CTX(ndr, r->out._ndr_size, LIBNDR_FLAG_REF_ALLOC); >+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out._ndr_size)); >+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save__ndr_size_0, LIBNDR_FLAG_REF_ALLOC); >+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { > NDR_PULL_ALLOC(ndr, r->out.key_buffer); > } > _mem_save_key_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr); > NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, LIBNDR_FLAG_REF_ALLOC); >- NDR_CHECK(ndr_pull_spoolss_StringArray2(ndr, NDR_SCALARS, r->out.key_buffer)); >+ { >+ struct ndr_pull *_ndr_key_buffer; >+ NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_key_buffer, 0, *r->out._ndr_size * 2)); >+ NDR_CHECK(ndr_pull_set_switch_value(_ndr_key_buffer, r->out.key_buffer, *r->out._ndr_size)); >+ NDR_CHECK(ndr_pull_spoolss_KeyNames(_ndr_key_buffer, NDR_SCALARS|NDR_BUFFERS, r->out.key_buffer)); >+ NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_key_buffer, 0, *r->out._ndr_size * 2)); >+ } > NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_0, LIBNDR_FLAG_REF_ALLOC); > if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { > NDR_PULL_ALLOC(ndr, r->out.needed); >@@ -26722,9 +26845,14 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char > if (flags & NDR_OUT) { > ndr_print_struct(ndr, "out", "spoolss_EnumPrinterKey"); > ndr->depth++; >+ ndr_print_ptr(ndr, "_ndr_size", r->out._ndr_size); >+ ndr->depth++; >+ ndr_print_uint32(ndr, "_ndr_size", *r->out._ndr_size); >+ ndr->depth--; > ndr_print_ptr(ndr, "key_buffer", r->out.key_buffer); > ndr->depth++; >- ndr_print_spoolss_StringArray2(ndr, "key_buffer", r->out.key_buffer); >+ ndr_print_set_switch_value(ndr, r->out.key_buffer, *r->out._ndr_size); >+ ndr_print_spoolss_KeyNames(ndr, "key_buffer", r->out.key_buffer); > ndr->depth--; > ndr_print_ptr(ndr, "needed", r->out.needed); > ndr->depth++; >diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h >index fbf056f..2abaa65 100644 >--- a/librpc/gen_ndr/ndr_spoolss.h >+++ b/librpc/gen_ndr/ndr_spoolss.h >@@ -483,6 +483,7 @@ enum ndr_err_code ndr_push_spoolss_PrinterEnumValues(struct ndr_push *ndr, int n > enum ndr_err_code ndr_pull_spoolss_PrinterEnumValues(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterEnumValues *r); > void ndr_print_spoolss_PrinterEnumValues(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterEnumValues *r); > size_t ndr_size_spoolss_PrinterEnumValues(const struct spoolss_PrinterEnumValues *r, struct smb_iconv_convenience *ic, int flags); >+void ndr_print_spoolss_KeyNames(struct ndr_print *ndr, const char *name, const union spoolss_KeyNames *r); > enum ndr_err_code ndr_push_spoolss_DeleteDriverFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r); > enum ndr_err_code ndr_pull_spoolss_DeleteDriverFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r); > void ndr_print_spoolss_DeleteDriverFlags(struct ndr_print *ndr, const char *name, uint32_t r); >diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h >index f70438d..630b146 100644 >--- a/librpc/gen_ndr/spoolss.h >+++ b/librpc/gen_ndr/spoolss.h >@@ -1568,6 +1568,10 @@ struct spoolss_PrinterEnumValues { > uint32_t data_length;/* [value(ndr_size_spoolss_PrinterData(data,type,ndr->iconv_convenience,ndr->flags))] */ > }/* [relative_base,gensize,public] */; > >+union spoolss_KeyNames { >+ const char ** string_array;/* [default,flag(LIBNDR_FLAG_STR_NULLTERM)] */ >+}/* [nodiscriminant] */; >+ > /* bitmap spoolss_DeleteDriverFlags */ > #define DPD_DELETE_UNUSED_FILES ( 0x00000001 ) > #define DPD_DELETE_SPECIFIC_VERSION ( 0x00000002 ) >@@ -3035,7 +3039,8 @@ struct spoolss_EnumPrinterKey { > } in; > > struct { >- struct spoolss_StringArray2 *key_buffer;/* [ref] */ >+ uint32_t *_ndr_size;/* [ref] */ >+ union spoolss_KeyNames *key_buffer;/* [subcontext_size(*_ndr_size*2),ref,subcontext(0),switch_is(*_ndr_size)] */ > uint32_t *needed;/* [ref] */ > WERROR result; > } out; >diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c >index 2d12587..9e58eb5 100644 >--- a/librpc/gen_ndr/srv_spoolss.c >+++ b/librpc/gen_ndr/srv_spoolss.c >@@ -6296,7 +6296,13 @@ static bool api_spoolss_EnumPrinterKey(pipes_struct *p) > } > > ZERO_STRUCT(r->out); >- r->out.key_buffer = talloc_zero(r, struct spoolss_StringArray2); >+ r->out._ndr_size = talloc_zero(r, uint32_t); >+ if (r->out._ndr_size == NULL) { >+ talloc_free(r); >+ return false; >+ } >+ >+ r->out.key_buffer = talloc_zero(r, union spoolss_KeyNames); > if (r->out.key_buffer == NULL) { > talloc_free(r); > return false; >@@ -8399,7 +8405,12 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, > case NDR_SPOOLSS_ENUMPRINTERKEY: { > struct spoolss_EnumPrinterKey *r = (struct spoolss_EnumPrinterKey *)_r; > ZERO_STRUCT(r->out); >- r->out.key_buffer = talloc_zero(mem_ctx, struct spoolss_StringArray2); >+ r->out._ndr_size = talloc_zero(mem_ctx, uint32_t); >+ if (r->out._ndr_size == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ r->out.key_buffer = talloc_zero(mem_ctx, union spoolss_KeyNames); > if (r->out.key_buffer == NULL) { > return NT_STATUS_NO_MEMORY; > } >-- >1.6.5.2 > > >From 023bbdd088dd3f7559bbe2ac98d835570f44f2f2 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 10 Dec 2009 14:20:22 +0100 >Subject: [PATCH 10/13] s3-spoolss: fix enumprinter key client and server. > >Guenther >(cherry picked from commit f20effc437970d826c5bd4f047ff47e23e7a1a73) >--- > source3/rpc_client/cli_spoolss.c | 7 +++++-- > source3/rpc_server/srv_spoolss_nt.c | 13 +++++++++++-- > 2 files changed, 16 insertions(+), 4 deletions(-) > >diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c >index d2e6556..bc4a4e7 100644 >--- a/source3/rpc_client/cli_spoolss.c >+++ b/source3/rpc_client/cli_spoolss.c >@@ -760,11 +760,13 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, > NTSTATUS status; > WERROR werror; > uint32_t needed; >- struct spoolss_StringArray2 _key_buffer; >+ union spoolss_KeyNames _key_buffer; >+ uint32_t _ndr_size; > > status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, > handle, > key_name, >+ &_ndr_size, > &_key_buffer, > offered, > &needed, >@@ -775,13 +777,14 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, > status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, > handle, > key_name, >+ &_ndr_size, > &_key_buffer, > offered, > &needed, > &werror); > } > >- *key_buffer = _key_buffer.string; >+ *key_buffer = _key_buffer.string_array; > > return werror; > } >diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c >index ecad469..e88c733 100644 >--- a/source3/rpc_server/srv_spoolss_nt.c >+++ b/source3/rpc_server/srv_spoolss_nt.c >@@ -9292,12 +9292,20 @@ WERROR _spoolss_EnumPrinterKey(pipes_struct *p, > goto done; > } > >- array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 1); >+ array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 2); > if (!array) { > result = WERR_NOMEM; > goto done; > } > >+ if (!num_keys) { >+ array[0] = talloc_strdup(array, ""); >+ if (!array[0]) { >+ result = WERR_NOMEM; >+ goto done; >+ } >+ } >+ > for (i=0; i < num_keys; i++) { > > DEBUG(10,("_spoolss_EnumPrinterKey: adding keyname: %s\n", >@@ -9315,13 +9323,14 @@ WERROR _spoolss_EnumPrinterKey(pipes_struct *p, > goto done; > } > >+ *r->out._ndr_size = r->in.offered / 2; > *r->out.needed = blob.length; > > if (r->in.offered < *r->out.needed) { > result = WERR_MORE_DATA; > } else { > result = WERR_OK; >- r->out.key_buffer->string = array; >+ r->out.key_buffer->string_array = array; > } > > done: >-- >1.6.5.2 > > >From 897473f8ea1d062cf644b17b2364d303888458b4 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Wed, 9 Dec 2009 15:31:51 +0100 >Subject: [PATCH 11/13] s4-smbtorture: enhance spoolss_EnumPrinterKey torture test. > >This demonstrates that s3 still does not have that call implemented correctly. > >Guenther >--- > source4/torture/rpc/spoolss.c | 53 +++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 53 insertions(+), 0 deletions(-) > >diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c >index 6f9d7d2..3593ea7 100644 >--- a/source4/torture/rpc/spoolss.c >+++ b/source4/torture/rpc/spoolss.c >@@ -2002,6 +2002,59 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, > return true; > } > >+static bool test_EnumPrinterKey(struct torture_context *tctx, >+ struct dcerpc_pipe *p, >+ struct policy_handle *handle, >+ const char *key_name, >+ const char ***array) >+{ >+ struct spoolss_EnumPrinterKey r; >+ uint32_t needed; >+ struct spoolss_StringArray2 key_buffer; >+ uint32_t offered[] = { 0, 512, 1024, 2048 }; >+ int i; >+ >+ r.in.handle = handle; >+ r.in.key_name = key_name; >+ r.out.key_buffer = &key_buffer; >+ r.out.needed = &needed; >+ >+ for (i=0; i < ARRAY_SIZE(offered); i++) { >+ r.in.offered = offered[i]; >+ >+ torture_comment(tctx, "Testing EnumPrinterKey(%s) with %d offered\n", r.in.key_name, r.in.offered); >+ >+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), >+ "failed to call EnumPrinterKey"); >+ if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { >+ torture_assert(tctx, (key_buffer._ndr_size == 0), >+ talloc_asprintf(tctx, "EnumPrinterKey did not return 0 _ndr_size (but %d), windows clients would abort here!", key_buffer._ndr_size)); >+ r.in.offered = needed; >+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), >+ "failed to call EnumPrinterKey"); >+ } >+ torture_assert_werr_ok(tctx, r.out.result, >+ "failed to call EnumPrinterKey"); >+ >+ torture_assert(tctx, (key_buffer._ndr_size * 2 == r.in.offered), >+ talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)", >+ key_buffer._ndr_size, r.in.offered/2)); >+ >+ torture_assert(tctx, (*r.out.needed <= r.in.offered), >+ talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= offered %d", *r.out.needed, r.in.offered)); >+ >+ torture_assert(tctx, (*r.out.needed <= key_buffer._ndr_size * 2), >+ talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r.out.needed, key_buffer._ndr_size)); >+ >+ } >+ >+ if (array) { >+ *array = key_buffer.string; >+ } >+ >+ return true; >+} >+ > bool test_printer_keys(struct torture_context *tctx, > struct dcerpc_pipe *p, > struct policy_handle *handle) >-- >1.6.5.2 > > >From e0b94c9d7e74289d03288d3ac7f6aa6c87a00e56 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 10 Dec 2009 14:21:12 +0100 >Subject: [PATCH 12/13] s4-smbtorture: fix and extend enum printerkey test. > >Guenther >--- > source4/torture/rpc/spoolss.c | 58 ++++++++++++++++++++++++++++-------- > source4/torture/rpc/spoolss_win.c | 6 ++- > 2 files changed, 49 insertions(+), 15 deletions(-) > >diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c >index 3593ea7..d107616 100644 >--- a/source4/torture/rpc/spoolss.c >+++ b/source4/torture/rpc/spoolss.c >@@ -2009,47 +2009,79 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > const char ***array) > { > struct spoolss_EnumPrinterKey r; >- uint32_t needed; >- struct spoolss_StringArray2 key_buffer; >- uint32_t offered[] = { 0, 512, 1024, 2048 }; >+ uint32_t needed = 0; >+ union spoolss_KeyNames key_buffer; >+ int32_t offered[] = { 0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, 256, 512, 1024, 2048 }; >+ uint32_t _ndr_size; > int i; > > r.in.handle = handle; > r.in.key_name = key_name; > r.out.key_buffer = &key_buffer; > r.out.needed = &needed; >+ r.out._ndr_size = &_ndr_size; > > for (i=0; i < ARRAY_SIZE(offered); i++) { >- r.in.offered = offered[i]; >+ >+ if (offered[i] < 0 && needed) { >+ if (needed <= 4) { >+ continue; >+ } >+ r.in.offered = needed + offered[i]; >+ } else { >+ r.in.offered = offered[i]; >+ } >+ >+ ZERO_STRUCT(key_buffer); > > torture_comment(tctx, "Testing EnumPrinterKey(%s) with %d offered\n", r.in.key_name, r.in.offered); > > torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), > "failed to call EnumPrinterKey"); > if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { >- torture_assert(tctx, (key_buffer._ndr_size == 0), >- talloc_asprintf(tctx, "EnumPrinterKey did not return 0 _ndr_size (but %d), windows clients would abort here!", key_buffer._ndr_size)); >+ >+ torture_assert(tctx, (_ndr_size == r.in.offered/2), >+ talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)", >+ _ndr_size, r.in.offered/2)); >+ > r.in.offered = needed; > torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey(p, tctx, &r), > "failed to call EnumPrinterKey"); > } >- torture_assert_werr_ok(tctx, r.out.result, >- "failed to call EnumPrinterKey"); > >- torture_assert(tctx, (key_buffer._ndr_size * 2 == r.in.offered), >+ if (offered[i] > 0) { >+ torture_assert_werr_ok(tctx, r.out.result, >+ "failed to call EnumPrinterKey"); >+ } >+ >+ torture_assert(tctx, (_ndr_size == r.in.offered/2), > talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)", >- key_buffer._ndr_size, r.in.offered/2)); >+ _ndr_size, r.in.offered/2)); > > torture_assert(tctx, (*r.out.needed <= r.in.offered), > talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= offered %d", *r.out.needed, r.in.offered)); > >- torture_assert(tctx, (*r.out.needed <= key_buffer._ndr_size * 2), >- talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r.out.needed, key_buffer._ndr_size)); >+ torture_assert(tctx, (*r.out.needed <= _ndr_size * 2), >+ talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r.out.needed, _ndr_size)); > >+ if (key_buffer.string_array) { >+ uint32_t calc_needed = 0; >+ int s; >+ for (s=0; key_buffer.string_array[s]; s++) { >+ calc_needed += strlen_m_term(key_buffer.string_array[s])*2; >+ } >+ if (!key_buffer.string_array[0]) { >+ calc_needed += 2; >+ } >+ calc_needed += 2; >+ >+ torture_assert_int_equal(tctx, *r.out.needed, calc_needed, >+ "EnumPrinterKey unexpected size"); >+ } > } > > if (array) { >- *array = key_buffer.string; >+ *array = key_buffer.string_array; > } > > return true; >diff --git a/source4/torture/rpc/spoolss_win.c b/source4/torture/rpc/spoolss_win.c >index 5439d9d..77536e5 100644 >--- a/source4/torture/rpc/spoolss_win.c >+++ b/source4/torture/rpc/spoolss_win.c >@@ -386,7 +386,8 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > NTSTATUS status; > struct spoolss_EnumPrinterKey epk; > uint32_t needed = 0; >- struct spoolss_StringArray2 key_buffer; >+ union spoolss_KeyNames key_buffer; >+ uint32_t _ndr_size; > > torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key); > >@@ -395,6 +396,7 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > epk.in.offered = 0; > epk.out.needed = &needed; > epk.out.key_buffer = &key_buffer; >+ epk.out._ndr_size = &_ndr_size; > > status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); > torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed"); >@@ -409,7 +411,7 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, > > torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed"); > >- ctx->printer_keys = key_buffer.string; >+ ctx->printer_keys = key_buffer.string_array; > > return true; > } >-- >1.6.5.2 > > >From 593613de2b41a8187c5e2ae3e54841e2e069b865 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 10 Dec 2009 14:23:49 +0100 >Subject: [PATCH 13/13] spoolss: remove unused spoolss_StringArray2. > >Guenther >--- > librpc/gen_ndr/ndr_spoolss.c | 9 ------ > librpc/gen_ndr/ndr_spoolss.h | 3 -- > librpc/gen_ndr/spoolss.h | 5 --- > librpc/idl/spoolss.idl | 5 --- > librpc/ndr/ndr_spoolss_buf.c | 63 ------------------------------------------ > librpc/ndr/ndr_spoolss_buf.h | 3 -- > 6 files changed, 0 insertions(+), 88 deletions(-) > >diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c >index 2766850..d531cbf 100644 >--- a/librpc/gen_ndr/ndr_spoolss.c >+++ b/librpc/gen_ndr/ndr_spoolss.c >@@ -7421,15 +7421,6 @@ _PUBLIC_ void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *n > ndr->depth--; > } > >-_PUBLIC_ void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r) >-{ >- ndr_print_struct(ndr, name, "spoolss_StringArray2"); >- ndr->depth++; >- ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?(ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2:r->_ndr_size); >- ndr_print_string_array(ndr, "string", r->string); >- ndr->depth--; >-} >- > static enum ndr_err_code ndr_push_spoolss_AddDriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_AddDriverInfo1 *r) > { > if (ndr_flags & NDR_SCALARS) { >diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h >index 2abaa65..1b94124 100644 >--- a/librpc/gen_ndr/ndr_spoolss.h >+++ b/librpc/gen_ndr/ndr_spoolss.h >@@ -303,9 +303,6 @@ void ndr_print_spoolss_SetPrinterInfoCtr(struct ndr_print *ndr, const char *name > enum ndr_err_code ndr_push_spoolss_StringArray(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray *r); > enum ndr_err_code ndr_pull_spoolss_StringArray(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray *r); > void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray *r); >-enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r); >-enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r); >-void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r); > void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo1 *r); > enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r); > enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r); >diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h >index 630b146..bd63485 100644 >--- a/librpc/gen_ndr/spoolss.h >+++ b/librpc/gen_ndr/spoolss.h >@@ -723,11 +723,6 @@ struct spoolss_StringArray { > const char ** string;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */ > }/* [public] */; > >-struct spoolss_StringArray2 { >- uint32_t _ndr_size;/* [value((ndr_size_spoolss_StringArray2(r,ndr->iconv_convenience,ndr->flags)-4)/2)] */ >- const char ** string;/* [subcontext_size(_ndr_size*2),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */ >-}/* [nopush,public,nopull] */; >- > struct spoolss_AddDriverInfo1 { > const char *driver_name;/* [unique,charset(UTF16)] */ > }; >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index f2abc22..1bea82e 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -786,11 +786,6 @@ import "misc.idl", "security.idl", "winreg.idl"; > /*[subcontext(0),subcontext_size(_ndr_size*2)]*/ nstring_array string; > } spoolss_StringArray; > >- typedef [public,nopush,nopull] struct { >- [value((ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags)-4)/2)] uint32 _ndr_size; >- [subcontext(0),subcontext_size(_ndr_size*2)] nstring_array string; >- } spoolss_StringArray2; >- > typedef struct { > [string,charset(UTF16)] uint16 *driver_name; > } spoolss_AddDriverInfo1; >diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c >index 0527197..0acae3d 100644 >--- a/librpc/ndr/ndr_spoolss_buf.c >+++ b/librpc/ndr/ndr_spoolss_buf.c >@@ -708,69 +708,6 @@ _PUBLIC_ size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r > return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); > } > >-_PUBLIC_ enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r) >-{ >- if (ndr_flags & NDR_SCALARS) { >- uint32_t _ndr_size; >- _ndr_size = ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags); >- NDR_CHECK(ndr_push_align(ndr, 4)); >- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size)); >- if (_ndr_size > 0) { >- uint32_t _flags_save_string_array = ndr->flags; >- ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >- { >- struct ndr_push *_ndr_string; >- NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_string, 0, _ndr_size * 2)); >- NDR_CHECK(ndr_push_string_array(_ndr_string, NDR_SCALARS, r->string)); >- NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_string, 0, _ndr_size * 2)); >- } >- ndr->flags = _flags_save_string_array; >- } >- } >- if (ndr_flags & NDR_BUFFERS) { >- } >- return NDR_ERR_SUCCESS; >-} >- >-_PUBLIC_ size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags) >-{ >- uint32_t i; >- >- if (!r || !r->string) { >- return 0; >- } >- >- for (i=0; r->string[i]; i++) { >- ;; >- } >- >- return (ndr_size_string_array(r->string, i, LIBNDR_FLAG_STR_NULLTERM) + 1); >-} >- >-_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r) >-{ >- if (ndr_flags & NDR_SCALARS) { >- NDR_CHECK(ndr_pull_align(ndr, 4)); >- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); >- if (r->_ndr_size) { >- uint32_t _flags_save_string_array = ndr->flags; >- ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); >- { >- struct ndr_pull *_ndr_string; >- NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_string, 0, r->_ndr_size * 2)); >- NDR_CHECK(ndr_pull_string_array(_ndr_string, NDR_SCALARS, &r->string)); >- NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_string, 0, r->_ndr_size * 2)); >- } >- ndr->flags = _flags_save_string_array; >- } else { >- r->string = NULL; >- } >- } >- if (ndr_flags & NDR_BUFFERS) { >- } >- return NDR_ERR_SUCCESS; >-} >- > /* hand marshall as pidl cannot (yet) generate a relative pointer to a fixed array of > * structs */ > >diff --git a/librpc/ndr/ndr_spoolss_buf.h b/librpc/ndr/ndr_spoolss_buf.h >index 74d0b52..aa6e277 100644 >--- a/librpc/ndr/ndr_spoolss_buf.h >+++ b/librpc/ndr/ndr_spoolss_buf.h >@@ -47,9 +47,6 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag > enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r); > uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct smb_iconv_convenience *ic, uint32_t flags); > size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags); >-enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r); >-enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r); >-size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags); > _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); > _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); > void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, const union spoolss_Field *r); >-- >1.6.5.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
metze
:
review+
Actions:
View
Attachments on
bug 6883
:
4938
|
4980
|
4992
|
5003
|
5026
|
5068
| 5082