diff options
| -rw-r--r-- | librpc/gen_ndr/cli_spoolss.c | 16 | ||||
| -rw-r--r-- | librpc/gen_ndr/cli_spoolss.h | 7 | ||||
| -rw-r--r-- | librpc/gen_ndr/ndr_spoolss.c | 136 | ||||
| -rw-r--r-- | librpc/gen_ndr/spoolss.h | 10 | ||||
| -rw-r--r-- | librpc/gen_ndr/srv_spoolss.c | 24 | ||||
| -rw-r--r-- | librpc/idl/spoolss.idl | 9 | 
6 files changed, 201 insertions, 1 deletions
diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c index a89c4bb422..66083e6856 100644 --- a/librpc/gen_ndr/cli_spoolss.c +++ b/librpc/gen_ndr/cli_spoolss.c @@ -583,12 +583,24 @@ NTSTATUS rpccli_spoolss_EnumPrinterDrivers(struct rpc_pipe_client *cli,  NTSTATUS rpccli_spoolss_GetPrinterDriver(struct rpc_pipe_client *cli,  					 TALLOC_CTX *mem_ctx, +					 struct policy_handle *handle /* [in] [ref] */, +					 const char *architecture /* [in] [unique,charset(UTF16)] */, +					 uint32_t level /* [in]  */, +					 DATA_BLOB *buffer /* [in] [unique] */, +					 uint32_t offered /* [in]  */, +					 union spoolss_DriverInfo *info /* [out] [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */, +					 uint32_t *needed /* [out] [ref] */,  					 WERROR *werror)  {  	struct spoolss_GetPrinterDriver r;  	NTSTATUS status;  	/* In parameters */ +	r.in.handle = handle; +	r.in.architecture = architecture; +	r.in.level = level; +	r.in.buffer = buffer; +	r.in.offered = offered;  	if (DEBUGLEVEL >= 10) {  		NDR_PRINT_IN_DEBUG(spoolss_GetPrinterDriver, &r); @@ -613,6 +625,10 @@ NTSTATUS rpccli_spoolss_GetPrinterDriver(struct rpc_pipe_client *cli,  	}  	/* Return variables */ +	if (info && r.out.info) { +		*info = *r.out.info; +	} +	*needed = *r.out.needed;  	/* Return result */  	if (werror) { diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h index 14e818cc54..baf5d61e2a 100644 --- a/librpc/gen_ndr/cli_spoolss.h +++ b/librpc/gen_ndr/cli_spoolss.h @@ -96,6 +96,13 @@ NTSTATUS rpccli_spoolss_EnumPrinterDrivers(struct rpc_pipe_client *cli,  					   WERROR *werror);  NTSTATUS rpccli_spoolss_GetPrinterDriver(struct rpc_pipe_client *cli,  					 TALLOC_CTX *mem_ctx, +					 struct policy_handle *handle /* [in] [ref] */, +					 const char *architecture /* [in] [unique,charset(UTF16)] */, +					 uint32_t level /* [in]  */, +					 DATA_BLOB *buffer /* [in] [unique] */, +					 uint32_t offered /* [in]  */, +					 union spoolss_DriverInfo *info /* [out] [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */, +					 uint32_t *needed /* [out] [ref] */,  					 WERROR *werror);  NTSTATUS rpccli_spoolss_GetPrinterDriverDirectory(struct rpc_pipe_client *cli,  						  TALLOC_CTX *mem_ctx, diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index b5df8d33af..a1be2fd92c 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -20392,8 +20392,39 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterDrivers(struct ndr_print *ndr, const  static enum ndr_err_code ndr_push_spoolss_GetPrinterDriver(struct ndr_push *ndr, int flags, const struct spoolss_GetPrinterDriver *r)  {  	if (flags & NDR_IN) { +		if (r->in.handle == NULL) { +			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); +		} +		NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle)); +		NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.architecture)); +		if (r->in.architecture) { +			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.architecture, CH_UTF16))); +			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); +			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.architecture, CH_UTF16))); +			NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.architecture, ndr_charset_length(r->in.architecture, CH_UTF16), sizeof(uint16_t), CH_UTF16)); +		} +		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level)); +		NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer)); +		if (r->in.buffer) { +			NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->in.buffer)); +		} +		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered));  	}  	if (flags & NDR_OUT) { +		NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info)); +		if (r->out.info) { +			{ +				struct ndr_push *_ndr_info; +				NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); +				NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->out.info, r->in.level)); +				NDR_CHECK(ndr_push_spoolss_DriverInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); +				NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); +			} +		} +		if (r->out.needed == NULL) { +			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); +		} +		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.needed));  		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));  	}  	return NDR_ERR_SUCCESS; @@ -20401,9 +20432,85 @@ static enum ndr_err_code ndr_push_spoolss_GetPrinterDriver(struct ndr_push *ndr,  static enum ndr_err_code ndr_pull_spoolss_GetPrinterDriver(struct ndr_pull *ndr, int flags, struct spoolss_GetPrinterDriver *r)  { +	uint32_t _ptr_architecture; +	uint32_t _ptr_buffer; +	uint32_t _ptr_info; +	TALLOC_CTX *_mem_save_handle_0; +	TALLOC_CTX *_mem_save_architecture_0; +	TALLOC_CTX *_mem_save_buffer_0; +	TALLOC_CTX *_mem_save_info_0; +	TALLOC_CTX *_mem_save_needed_0;  	if (flags & NDR_IN) { +		ZERO_STRUCT(r->out); + +		if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { +			NDR_PULL_ALLOC(ndr, r->in.handle); +		} +		_mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); +		NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); +		NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); +		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); +		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_architecture)); +		if (_ptr_architecture) { +			NDR_PULL_ALLOC(ndr, r->in.architecture); +		} else { +			r->in.architecture = NULL; +		} +		if (r->in.architecture) { +			_mem_save_architecture_0 = NDR_PULL_GET_MEM_CTX(ndr); +			NDR_PULL_SET_MEM_CTX(ndr, r->in.architecture, 0); +			NDR_CHECK(ndr_pull_array_size(ndr, &r->in.architecture)); +			NDR_CHECK(ndr_pull_array_length(ndr, &r->in.architecture)); +			if (ndr_get_array_length(ndr, &r->in.architecture) > ndr_get_array_size(ndr, &r->in.architecture)) { +				return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.architecture), ndr_get_array_length(ndr, &r->in.architecture)); +			} +			NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.architecture), sizeof(uint16_t))); +			NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.architecture, ndr_get_array_length(ndr, &r->in.architecture), sizeof(uint16_t), CH_UTF16)); +			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_architecture_0, 0); +		} +		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level)); +		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_buffer)); +		if (_ptr_buffer) { +			NDR_PULL_ALLOC(ndr, r->in.buffer); +		} else { +			r->in.buffer = NULL; +		} +		if (r->in.buffer) { +			_mem_save_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr); +			NDR_PULL_SET_MEM_CTX(ndr, r->in.buffer, 0); +			NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->in.buffer)); +			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffer_0, 0); +		} +		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered)); +		NDR_PULL_ALLOC(ndr, r->out.needed); +		ZERO_STRUCTP(r->out.needed);  	}  	if (flags & NDR_OUT) { +		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); +		if (_ptr_info) { +			NDR_PULL_ALLOC(ndr, r->out.info); +		} else { +			r->out.info = NULL; +		} +		if (r->out.info) { +			_mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); +			NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0); +			{ +				struct ndr_pull *_ndr_info; +				NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); +				NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->out.info, r->in.level)); +				NDR_CHECK(ndr_pull_spoolss_DriverInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); +				NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); +			} +			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); +		} +		if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { +			NDR_PULL_ALLOC(ndr, r->out.needed); +		} +		_mem_save_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); +		NDR_PULL_SET_MEM_CTX(ndr, r->out.needed, LIBNDR_FLAG_REF_ALLOC); +		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));  	}  	return NDR_ERR_SUCCESS; @@ -20419,11 +20526,40 @@ _PUBLIC_ void ndr_print_spoolss_GetPrinterDriver(struct ndr_print *ndr, const ch  	if (flags & NDR_IN) {  		ndr_print_struct(ndr, "in", "spoolss_GetPrinterDriver");  		ndr->depth++; +		ndr_print_ptr(ndr, "handle", r->in.handle); +		ndr->depth++; +		ndr_print_policy_handle(ndr, "handle", r->in.handle); +		ndr->depth--; +		ndr_print_ptr(ndr, "architecture", r->in.architecture); +		ndr->depth++; +		if (r->in.architecture) { +			ndr_print_string(ndr, "architecture", r->in.architecture); +		} +		ndr->depth--; +		ndr_print_uint32(ndr, "level", r->in.level); +		ndr_print_ptr(ndr, "buffer", r->in.buffer); +		ndr->depth++; +		if (r->in.buffer) { +			ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer); +		} +		ndr->depth--; +		ndr_print_uint32(ndr, "offered", r->in.offered);  		ndr->depth--;  	}  	if (flags & NDR_OUT) {  		ndr_print_struct(ndr, "out", "spoolss_GetPrinterDriver");  		ndr->depth++; +		ndr_print_ptr(ndr, "info", r->out.info); +		ndr->depth++; +		if (r->out.info) { +			ndr_print_set_switch_value(ndr, r->out.info, r->in.level); +			ndr_print_spoolss_DriverInfo(ndr, "info", r->out.info); +		} +		ndr->depth--; +		ndr_print_ptr(ndr, "needed", r->out.needed); +		ndr->depth++; +		ndr_print_uint32(ndr, "needed", *r->out.needed); +		ndr->depth--;  		ndr_print_WERROR(ndr, "result", r->out.result);  		ndr->depth--;  	} diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 6bc5cd7d02..9446193863 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -1911,6 +1911,16 @@ struct spoolss_EnumPrinterDrivers {  struct spoolss_GetPrinterDriver {  	struct { +		struct policy_handle *handle;/* [ref] */ +		const char *architecture;/* [unique,charset(UTF16)] */ +		uint32_t level; +		DATA_BLOB *buffer;/* [unique] */ +		uint32_t offered; +	} in; + +	struct { +		union spoolss_DriverInfo *info;/* [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */ +		uint32_t *needed;/* [ref] */  		WERROR result;  	} out; diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c index 764c805397..41a79b4a79 100644 --- a/librpc/gen_ndr/srv_spoolss.c +++ b/librpc/gen_ndr/srv_spoolss.c @@ -944,6 +944,19 @@ static bool api_spoolss_GetPrinterDriver(pipes_struct *p)  		NDR_PRINT_IN_DEBUG(spoolss_GetPrinterDriver, r);  	} +	ZERO_STRUCT(r->out); +	r->out.info = talloc_zero(r, union spoolss_DriverInfo); +	if (r->out.info == NULL) { +		talloc_free(r); +		return false; +	} + +	r->out.needed = talloc_zero(r, uint32_t); +	if (r->out.needed == NULL) { +		talloc_free(r); +		return false; +	} +  	r->out.result = _spoolss_GetPrinterDriver(p, r);  	if (p->rng_fault_state) { @@ -7725,6 +7738,17 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,  		case NDR_SPOOLSS_GETPRINTERDRIVER: {  			struct spoolss_GetPrinterDriver *r = (struct spoolss_GetPrinterDriver *)_r; +			ZERO_STRUCT(r->out); +			r->out.info = talloc_zero(mem_ctx, union spoolss_DriverInfo); +			if (r->out.info == NULL) { +			return NT_STATUS_NO_MEMORY; +			} + +			r->out.needed = talloc_zero(mem_ctx, uint32_t); +			if (r->out.needed == NULL) { +			return NT_STATUS_NO_MEMORY; +			} +  			r->out.result = _spoolss_GetPrinterDriver(cli->pipes_struct, r);  			return NT_STATUS_OK;  		} diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index d4c6e198b8..f37424634d 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1101,7 +1101,14 @@ import "misc.idl", "security.idl", "winreg.idl";  	/******************/  	/* Function: 0x0b */ -	[todo] WERROR spoolss_GetPrinterDriver( +	WERROR spoolss_GetPrinterDriver( +		[in,ref] policy_handle *handle, +		[in,unique] [string,charset(UTF16)] uint16 *architecture, +		[in] 	 uint32 level, +		[in,unique] DATA_BLOB *buffer, +		[in] 	 uint32 offered, +		[out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_DriverInfo *info, +		[out,ref] uint32 *needed  	);  	/******************/  | 
