From 746bb14367f87204baebfcda7f3170e3d9dd6b8f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Apr 2005 15:19:27 +0000 Subject: r6194: - fix some spoolss_*Form names and types - fix GetPrinterData(), look inside the datablob - add idl for RemoteFindFirstChangeNotify(), without meaning yet, just to not return a DCERPC_FAULT when receiving this request metze (This used to be commit 92f3d5bd9c700032612ac20dc7635730c555c4da) --- source4/librpc/idl/spoolss.idl | 100 ++++++++++++++++++++++++++++++----------- source4/torture/rpc/spoolss.c | 94 +++++++++++++++++++++++++++----------- 2 files changed, 142 insertions(+), 52 deletions(-) diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index d5bfd687ac..5d909b4bed 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -316,6 +316,8 @@ typedef [nodiscriminant,public] union { [case(1)] spoolss_JobInfo1 info1; + [case(2)]; /* TODO */ + [case(3)]; /* TODO */ [default]; } spoolss_JobInfo; @@ -582,11 +584,26 @@ /******************/ /* Function: 0x1a */ + const string SPOOLSS_ARCHITECTURE_NT_X86 = "Windows NT x86"; + + typedef [v1_enum] enum { + SPOOLSS_PRINTER_DATA_TYPE_NULL = 0, + SPOOLSS_PRINTER_DATA_TYPE_STRING = 1, + SPOOLSS_PRINTER_DATA_TYPE_UINT32 = 4 + } spoolss_PrinterDataType; + + typedef [nodiscriminant,gensize] union { + [case(SPOOLSS_PRINTER_DATA_TYPE_NULL)]; + [case(SPOOLSS_PRINTER_DATA_TYPE_STRING)] nstring string; + [case(SPOOLSS_PRINTER_DATA_TYPE_UINT32)] uint32 value; + [default,flag(NDR_REMAINING)] DATA_BLOB data; + } spoolss_PrinterData; + WERROR spoolss_GetPrinterData( [in,ref] policy_handle *handle, [in] unistr value_name, - [out] uint32 type, - [out] DATA_BLOB buffer, + [out] spoolss_PrinterDataType type, + [out,subcontext(4),switch_is(type)] spoolss_PrinterData data, [in,out,ref] uint32 *buf_size ); @@ -611,23 +628,37 @@ [in,out,ref] policy_handle *handle ); + /******************/ + /* Function: 0x1e */ + typedef [v1_enum] enum { + SPOOLSS_FORM_USER = 0, + SPOOLSS_FORM_BUILTIN = 1, + SPOOLSS_FORM_PRINTER = 2 + } spoolss_FormFlags; + typedef struct { - uint32 flags; - [relative] unistr *formname; uint32 width; - uint32 length; + uint32 height; + } spoolss_FormSize; + + typedef struct { uint32 left; uint32 top; uint32 right; uint32 bottom; + } spoolss_FormArea; + + typedef struct { + spoolss_FormFlags flags; + [relative] unistr *form_name; + spoolss_FormSize size; + spoolss_FormArea area; } spoolss_AddFormInfo1; typedef union { [case(1)] spoolss_AddFormInfo1 *info1; } spoolss_AddFormInfo; - /******************/ - /* Function: 0x1e */ WERROR spoolss_AddForm( [in,ref] policy_handle *handle, [in] uint32 level, @@ -638,25 +669,21 @@ /* Function: 0x1f */ WERROR spoolss_DeleteForm( [in,ref] policy_handle *handle, - [in] unistr formname + [in] unistr form_name ); /******************/ /* Function: 0x20 */ typedef struct { - uint32 flags; - [relative] nstring *formname; - uint32 width; - uint32 length; - uint32 left; - uint32 top; - uint32 right; - uint32 bottom; + spoolss_FormFlags flags; + [relative] nstring *form_name; + spoolss_FormSize size; + spoolss_FormArea area; } spoolss_FormInfo1; WERROR spoolss_GetForm( [in,ref] policy_handle *handle, - [in] unistr formname, + [in] unistr form_name, [in] uint32 level, [in] DATA_BLOB *buffer, [out,subcontext(4),switch_is(level)] spoolss_FormInfo *info, @@ -664,25 +691,21 @@ ); typedef struct { - uint32 flags; - unistr *formname; - uint32 width; - uint32 length; - uint32 left; - uint32 top; - uint32 right; - uint32 bottom; + spoolss_FormFlags flags; + unistr *form_name; + spoolss_FormSize size; + spoolss_FormArea area; } spoolss_SetFormInfo1; typedef union { - [case(1)] spoolss_AddFormInfo1 *info1; + [case(1)] spoolss_SetFormInfo1 *info1; } spoolss_SetFormInfo; /******************/ /* Function: 0x21 */ WERROR spoolss_SetForm( [in,ref] policy_handle *handle, - [in] unistr formname, + [in] unistr form_name, [in] uint32 level, [in,switch_is(level)] spoolss_SetFormInfo info ); @@ -726,6 +749,7 @@ typedef [nodiscriminant,public] union { [case(1)] spoolss_PortInfo1 info1; [case(2)] spoolss_PortInfo2 info2; + [case(3)]; /* TODO */ [default]; } spoolss_PortInfo; @@ -926,7 +950,29 @@ /******************/ /* Function: 0x41 */ + typedef [flag(NDR_PAHEX)] struct { + uint16 u1; + uint16 u2; + uint32 u3; + uint32 u4; + uint32 count; + [size_is(count)] uint16 *array[]; + } spoolss_RemoteFindFirstPrinterChangeNotifyEx_t2; + + typedef struct { + uint32 u1; + uint32 u2; + uint32 count; + [size_is(count)] spoolss_RemoteFindFirstPrinterChangeNotifyEx_t2 *t2[]; + } spoolss_RemoteFindFirstPrinterChangeNotifyEx_t1; + WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx( + [in,ref] policy_handle *handle, + [in] uint32 u1, + [in] uint32 u2, + [in] unistr *str, + [in] uint32 u3, + [in] spoolss_RemoteFindFirstPrinterChangeNotifyEx_t1 *t1 ); /******************/ diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index c2be0b5324..e75567d55d 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -26,6 +26,9 @@ struct test_spoolss_context { struct dcerpc_pipe *p; + /* print server handle */ + struct policy_handle server_handle; + /* for EnumPorts */ uint32_t port_count[3]; union spoolss_PortInfo **ports[3]; @@ -89,6 +92,35 @@ struct test_spoolss_context { #define COMPARE_SPOOLSS_TIME(c,r,e) #define COMPARE_STRING_ARRAY(c,r,e) +static BOOL test_OpenPrinter_server(struct test_spoolss_context *ctx) +{ + NTSTATUS status; + struct spoolss_OpenPrinter op; + BOOL ret = True; + + op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p)); + op.in.datatype = NULL; + op.in.devmode_ctr.size = 0; + op.in.devmode_ctr.devmode= NULL; + op.in.access_mask = 0; + op.out.handle = &ctx->server_handle; + + printf("\nTesting OpenPrinter(%s)\n", op.in.printername); + + status = dcerpc_spoolss_OpenPrinter(ctx->p, ctx, &op); + if (!NT_STATUS_IS_OK(status)) { + printf("dcerpc_spoolss_OpenPrinter failed - %s\n", nt_errstr(status)); + ret = False; + } + if (!W_ERROR_IS_OK(op.out.result)) { + printf("OpenPrinter(%s) failed - %s\n", + op.in.printername, win_errstr(op.out.result)); + ret = False; + } + + return ret; +} + static BOOL test_EnumPorts(struct test_spoolss_context *ctx) { NTSTATUS status; @@ -700,14 +732,14 @@ static BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - const char *formname) + const char *form_name) { NTSTATUS status; struct spoolss_GetForm r; uint32_t buf_size; r.in.handle = handle; - r.in.formname = formname; + r.in.form_name = form_name; r.in.level = 1; r.in.buffer = NULL; buf_size = 0; @@ -780,7 +812,7 @@ static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, info = *r.out.info; for (j = 0; j < r.out.count; j++) { - test_GetForm(p, mem_ctx, handle, info[j].info1.formname); + test_GetForm(p, mem_ctx, handle, info[j].info1.form_name); } } @@ -799,13 +831,13 @@ static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - const char *formname) + const char *form_name) { NTSTATUS status; struct spoolss_DeleteForm r; r.in.handle = handle; - r.in.formname = formname; + r.in.form_name = form_name; status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r); @@ -826,23 +858,23 @@ static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle) { struct spoolss_AddForm r; - struct spoolss_AddFormInfo1 form; + struct spoolss_AddFormInfo1 addform; + const char *form_name = "testform3"; NTSTATUS status; - const char *formname = "testform3"; BOOL ret = True; - r.in.handle = handle; - r.in.level = 1; - form.flags = 2; /* User form */ - form.formname = formname; - form.width = 1; - form.length = 2; - form.left = 3; - form.top = 4; - form.right = 5; - form.bottom = 6; - r.in.info.info1 = &form; - + r.in.handle = handle; + r.in.level = 1; + r.in.info.info1 = &addform; + addform.flags = SPOOLSS_FORM_USER; + addform.form_name = form_name; + addform.size.width = 50; + addform.size.height = 25; + addform.area.left = 5; + addform.area.top = 10; + addform.area.right = 45; + addform.area.bottom = 15; + status = dcerpc_spoolss_AddForm(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -857,12 +889,18 @@ static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { struct spoolss_SetForm sf; + struct spoolss_SetFormInfo1 setform; + + sf.in.handle = handle; + sf.in.form_name = form_name; + sf.in.level = 1; + sf.in.info.info1= &setform; + setform.flags = addform.flags; + setform.form_name = addform.form_name; + setform.size = addform.size; + setform.area = addform.area; - sf.in.handle = handle; - sf.in.formname = formname; - sf.in.level = 1; - sf.in.info.info1 = &form; - form.width = 1234; + setform.size.width = 1234; status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf); @@ -881,7 +919,7 @@ static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } done: - if (!test_DeleteForm(p, mem_ctx, handle, formname)) { + if (!test_DeleteForm(p, mem_ctx, handle, form_name)) { printf("DeleteForm failed\n"); ret = False; } @@ -1786,6 +1824,12 @@ BOOL torture_rpc_spoolss(void) ctx = talloc_zero(mem_ctx, struct test_spoolss_context); ctx->p = p; + ret &= test_OpenPrinter_server(ctx); + + ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, SPOOLSS_ARCHITECTURE); + + ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory"); + ret &= test_EnumPorts(ctx); ret &= test_EnumPrinterDrivers(ctx); -- cgit