#include "torture/torture.h"
#include "torture/rpc/rpc.h"
#include "librpc/gen_ndr/ndr_misc.h"
+#include "librpc/gen_ndr/ndr_spoolss.h"
#include "librpc/gen_ndr/ndr_spoolss_c.h"
#include "param/param.h"
} \
} while(0)
+#define CHECK_ALIGN(size, n) do {\
+ if (size % n) {\
+ torture_warning(tctx, "%d is *NOT* %d byte aligned, should be %d",\
+ size, n, size + n - (size % n));\
+ }\
+} while(0)
+
+#define DO_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1))
+
+#define CHECK_NEEDED_SIZE_ENUM_LEVEL(fn, info, level, count, ic, needed, align) do { \
+ uint32_t size = ndr_size_##fn##_info(tctx, ic, level, count, info);\
+ uint32_t round_size = DO_ROUND(size, align);\
+ if (round_size != needed) {\
+ torture_warning(tctx, __location__": "#fn" level %d (count: %d) got unexpected needed size: %d, we calculated: %d", level, count, needed, round_size);\
+ CHECK_ALIGN(size, align);\
+ }\
+} while(0)
+
+#define CHECK_NEEDED_SIZE_ENUM(fn, info, count, ic, needed, align) do { \
+ uint32_t size = ndr_size_##fn##_info(tctx, ic, count, info);\
+ uint32_t round_size = DO_ROUND(size, align);\
+ if (round_size != needed) {\
+ torture_warning(tctx, __location__": "#fn" (count: %d) got unexpected needed size: %d, we calculated: %d", count, needed, round_size);\
+ CHECK_ALIGN(size, align);\
+ }\
+} while(0)
+
+#define CHECK_NEEDED_SIZE_LEVEL(fn, info, level, ic, needed, align) do { \
+ uint32_t size = ndr_size_##fn(info, level, ic, 0);\
+ uint32_t round_size = DO_ROUND(size, align);\
+ if (round_size != needed) {\
+ torture_warning(tctx, __location__": "#fn" level %d got unexpected needed size: %d, we calculated: %d", level, needed, round_size);\
+ CHECK_ALIGN(size, align);\
+ }\
+} while(0)
+
static bool test_OpenPrinter_server(struct torture_context *tctx,
struct dcerpc_pipe *p,
struct policy_handle *server_handle)
torture_assert(tctx, info, "EnumPorts returned no info");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
ctx->port_count[level] = count;
ctx->ports[level] = info;
}
torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
torture_assert_werr_ok(tctx, r.out.result, "GetPrintProcessorDirectory failed");
+
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrintProcessorDirectoryInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 2);
}
return true;
torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed");
+
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverDirectoryInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 2);
}
return true;
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
ctx->driver_count[level] = count;
ctx->drivers[level] = info;
}
torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumMonitors, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
ctx->monitor_count[level] = count;
ctx->monitors[level] = info;
}
torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
ctx->print_processor_count[level] = count;
ctx->print_processors[level] = info;
}
torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcDataTypes failed");
+
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcDataTypes, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
}
return true;
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
ctx->printer_count[level] = count;
ctx->printers[level] = info;
}
torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
torture_assert_werr_ok(tctx, r.out.result, "GetPrinter failed");
+
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
}
return true;
torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_FormInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
return true;
}
torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
+
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumForms, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
}
return true;
torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, 2, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
return true;
}
}
torture_assert(tctx, r.out.info, "No job info returned");
torture_assert_werr_ok(tctx, r.out.result, "GetJob failed");
+
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_JobInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
}
return true;
torture_assert_werr_ok(tctx, r.out.result, "EnumJobs failed");
torture_assert(tctx, info, "No jobs returned");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumJobs, *r.out.info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
for (j = 0; j < count; j++) {
torture_assert(tctx, test_GetJob(tctx, p, handle, info[j].info1.job_id),
torture_assert_werr_ok(tctx, r.out.result,
talloc_asprintf(tctx, "GetPrinterData(%s) failed", r.in.value_name));
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, lp_iconv_convenience(tctx->lp_ctx), needed, 1);
+
if (type_p) {
*type_p = type;
}
torture_assert_werr_ok(tctx, r.out.result,
talloc_asprintf(tctx, "GetPrinterDataEx(%s - %s) failed", r.in.key_name, r.in.value_name));
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, lp_iconv_convenience(tctx->lp_ctx), needed, 1);
+
if (type_p) {
*type_p = type;
}
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDataEx failed");
+ CHECK_NEEDED_SIZE_ENUM(spoolss_EnumPrinterDataEx, info, count, lp_iconv_convenience(tctx->lp_ctx), needed, 1);
+
return true;
}
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
if (!info) {
torture_comment(tctx, "No printers returned\n");
return true;
torture_assert_werr_ok(tctx, r.out.result,
"failed to call GetPrinterDriver");
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
return true;
}
torture_assert_werr_ok(tctx, r.out.result,
"failed to call GetPrinterDriver2");
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+
return true;
}
torture_comment(tctx, "No printer drivers returned\n");
break;
}
+
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
}
return true;