root/source4/torture/rpc/spoolss_win.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_OpenPrinterEx
  2. test_OpenPrinterAsAdmin
  3. test_OpenPrinterSequence
  4. test_GetPrinterData
  5. test_EnumPrinters
  6. test_GetPrinter
  7. test_EnumJobs
  8. test_GetPrinterDriver2
  9. test_EnumForms
  10. test_EnumPrinterKey
  11. test_EnumPrinterDataEx
  12. test_ClosePrinter
  13. test_WinXP
  14. torture_rpc_spoolss_win

   1 /*
   2    Unix SMB/CIFS implementation.
   3    test suite for spoolss rpc operations as performed by various win versions
   4 
   5    Copyright (C) Kai Blin 2007
   6 
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11 
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16 
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 #include "torture/torture.h"
  23 #include "torture/rpc/rpc.h"
  24 #include "librpc/gen_ndr/ndr_spoolss_c.h"
  25 #include "rpc_server/dcerpc_server.h"
  26 #include "ntvfs/ntvfs.h"
  27 #include "param/param.h"
  28 
  29 struct test_spoolss_win_context {
  30         /* EnumPrinters */
  31         uint32_t printer_count;
  32         union spoolss_PrinterInfo *printer_info;
  33         union spoolss_PrinterInfo *current_info;
  34 
  35         /* EnumPrinterKeys */
  36         const char **printer_keys;
  37 
  38         bool printer_has_driver;
  39 };
  40 
  41 /* This is a convenience function for all OpenPrinterEx calls */
  42 static bool test_OpenPrinterEx(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
  43                                 struct dcerpc_pipe *p,
  44                                 struct policy_handle *handle,
  45                                 const char *printer_name,
  46                                 uint32_t access_mask)
  47 {
  48         NTSTATUS status;
  49         struct spoolss_OpenPrinterEx op;
  50         struct spoolss_UserLevel1 ul_1;
  51 
  52         torture_comment(tctx, "Opening printer '%s'\n", printer_name);
  53 
  54         op.in.printername               = talloc_strdup(tctx, printer_name);
  55         op.in.datatype                  = NULL;
  56         op.in.devmode_ctr.devmode       = NULL;
  57         op.in.access_mask               = access_mask;
  58         op.in.level                     = 1;
  59         op.in.userlevel.level1          = &ul_1;
  60         op.out.handle                   = handle;
  61 
  62         ul_1.size                       = 1234;
  63         ul_1.client                     = "\\clientname";
  64         ul_1.user                       = "username";
  65         ul_1.build                      = 1;
  66         ul_1.major                      = 2;
  67         ul_1.minor                      = 3;
  68         ul_1.processor                  = 4567;
  69 
  70         status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &op);
  71         torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
  72         torture_assert_werr_ok(tctx, op.out.result, "OpenPrinterEx failed");
  73 
  74         return true;
  75 }
  76 
  77 static bool test_OpenPrinterAsAdmin(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
  78                                         struct dcerpc_pipe *p,
  79                                         const char *printername)
  80 {
  81         NTSTATUS status;
  82         struct spoolss_OpenPrinterEx op;
  83         struct spoolss_ClosePrinter cp;
  84         struct spoolss_UserLevel1 ul_1;
  85         struct policy_handle handle;
  86 
  87         ul_1.size                       = 1234;
  88         ul_1.client                     = "\\clientname";
  89         ul_1.user                       = "username";
  90         ul_1.build                      = 1;
  91         ul_1.major                      = 2;
  92         ul_1.minor                      = 3;
  93         ul_1.processor                  = 4567;
  94 
  95         op.in.printername               = talloc_strdup(tctx, printername);
  96         op.in.datatype                  = NULL;
  97         op.in.devmode_ctr.devmode       = NULL;
  98         op.in.access_mask               = SERVER_ALL_ACCESS;
  99         op.in.level                     = 1;
 100         op.in.userlevel.level1          = &ul_1;
 101         op.out.handle                   = &handle;
 102 
 103         cp.in.handle                    = &handle;
 104         cp.out.handle                   = &handle;
 105 
 106         torture_comment(tctx, "Testing OpenPrinterEx(%s) with admin rights\n",
 107                         op.in.printername);
 108 
 109         status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &op);
 110 
 111         if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(op.out.result)) {
 112                 status = dcerpc_spoolss_ClosePrinter(p, tctx, &cp);
 113                 torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
 114         }
 115 
 116         return true;
 117 }
 118 
 119 
 120 static bool test_ClosePrinter(struct torture_context *tctx,
 121                                 struct dcerpc_pipe *p,
 122                                 struct policy_handle *handle);
 123 
 124 /* This replicates the opening sequence of OpenPrinterEx calls XP does */
 125 static bool test_OpenPrinterSequence(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 126                                         struct dcerpc_pipe *p,
 127                                         struct policy_handle *handle)
 128 {
 129         bool ret;
 130         char *printername = talloc_asprintf(tctx, "\\\\%s",
 131                         dcerpc_server_name(p));
 132 
 133         /* First, see if we can open the printer read_only */
 134         ret = test_OpenPrinterEx(tctx, p, handle, printername, 0);
 135         torture_assert(tctx, ret == true, "OpenPrinterEx failed.");
 136 
 137         ret = test_ClosePrinter(tctx, p, handle);
 138         torture_assert(tctx, ret, "ClosePrinter failed");
 139 
 140         /* Now let's see if we have admin rights to it. */
 141         ret = test_OpenPrinterAsAdmin(tctx, p, printername);
 142         torture_assert(tctx, ret == true,
 143                         "OpenPrinterEx as admin failed unexpectedly.");
 144 
 145         ret = test_OpenPrinterEx(tctx, p, handle, printername, SERVER_EXECUTE);
 146         torture_assert(tctx, ret == true, "OpenPrinterEx failed.");
 147 
 148         return true;
 149 }
 150 
 151 static bool test_GetPrinterData(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 152                                 struct dcerpc_pipe *p,
 153                                 struct policy_handle *handle,
 154                                 const char *value_name,
 155                                 WERROR expected_werr,
 156                                 uint32_t expected_value)
 157 {
 158         NTSTATUS status;
 159         struct spoolss_GetPrinterData gpd;
 160         uint32_t needed;
 161         enum winreg_Type type;
 162         union spoolss_PrinterData data;
 163 
 164         torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name);
 165         gpd.in.handle = handle;
 166         gpd.in.value_name = value_name;
 167         gpd.in.offered = 4;
 168         gpd.out.needed = &needed;
 169         gpd.out.type = &type;
 170         gpd.out.data = &data;
 171 
 172         status = dcerpc_spoolss_GetPrinterData(p, tctx, &gpd);
 173         torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed.");
 174         torture_assert_werr_equal(tctx, gpd.out.result, expected_werr,
 175                         "GetPrinterData did not return expected error value.");
 176 
 177         if (W_ERROR_IS_OK(expected_werr)) {
 178                 torture_assert_int_equal(tctx, data.value,
 179                         expected_value,
 180                         "GetPrinterData did not return expected value.");
 181         }
 182         return true;
 183 }
 184 
 185 static bool test_EnumPrinters(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 186                                 struct dcerpc_pipe *p,
 187                                 struct test_spoolss_win_context *ctx,
 188                                 uint32_t initial_blob_size)
 189 {
 190         NTSTATUS status;
 191         struct spoolss_EnumPrinters ep;
 192         DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
 193         uint32_t needed;
 194         uint32_t count;
 195         union spoolss_PrinterInfo *info;
 196 
 197         ep.in.flags = PRINTER_ENUM_NAME;
 198         ep.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
 199         ep.in.level = 2;
 200         ep.in.buffer = &blob;
 201         ep.in.offered = initial_blob_size;
 202         ep.out.needed = &needed;
 203         ep.out.count = &count;
 204         ep.out.info = &info;
 205 
 206         status = dcerpc_spoolss_EnumPrinters(p, ctx, &ep);
 207         torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed.");
 208 
 209         if (W_ERROR_EQUAL(ep.out.result, WERR_INSUFFICIENT_BUFFER)) {
 210                 blob = data_blob_talloc_zero(ctx, needed);
 211                 ep.in.buffer = &blob;
 212                 ep.in.offered = needed;
 213                 status = dcerpc_spoolss_EnumPrinters(p, ctx, &ep);
 214                 torture_assert_ntstatus_ok(tctx, status,"EnumPrinters failed.");
 215         }
 216 
 217         torture_assert_werr_ok(tctx, ep.out.result, "EnumPrinters failed.");
 218 
 219         ctx->printer_count = count;
 220         ctx->printer_info = info;
 221 
 222         torture_comment(tctx, "Found %d printer(s).\n", ctx->printer_count);
 223 
 224         return true;
 225 }
 226 
 227 static bool test_GetPrinter(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 228                                 struct dcerpc_pipe *p,
 229                                 struct policy_handle *handle,
 230                                 struct test_spoolss_win_context *ctx,
 231                                 uint32_t level,
 232                                 uint32_t initial_blob_size)
 233 {
 234         NTSTATUS status;
 235         struct spoolss_GetPrinter gp;
 236         DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
 237         uint32_t needed;
 238 
 239         torture_comment(tctx, "Test GetPrinter level %d\n", level);
 240 
 241         gp.in.handle = handle;
 242         gp.in.level = level;
 243         gp.in.buffer = (initial_blob_size == 0)?NULL:&blob;
 244         gp.in.offered = initial_blob_size;
 245         gp.out.needed = &needed;
 246 
 247         status = dcerpc_spoolss_GetPrinter(p, tctx, &gp);
 248         torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
 249 
 250         if (W_ERROR_EQUAL(gp.out.result, WERR_INSUFFICIENT_BUFFER)) {
 251                 blob = data_blob_talloc_zero(ctx, needed);
 252                 gp.in.buffer = &blob;
 253                 gp.in.offered = needed;
 254                 status = dcerpc_spoolss_GetPrinter(p, tctx, &gp);
 255                 torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
 256         }
 257 
 258         torture_assert_werr_ok(tctx, gp.out.result, "GetPrinter failed");
 259 
 260         ctx->current_info = gp.out.info;
 261 
 262         if (level == 2 && gp.out.info) {
 263                 ctx->printer_has_driver = gp.out.info->info2.drivername &&
 264                                           strlen(gp.out.info->info2.drivername);
 265         }
 266 
 267         return true;
 268 }
 269 
 270 static bool test_EnumJobs(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 271                                 struct dcerpc_pipe *p,
 272                                 struct policy_handle *handle)
 273 {
 274         NTSTATUS status;
 275         struct spoolss_EnumJobs ej;
 276         DATA_BLOB blob = data_blob_talloc_zero(tctx, 1024);
 277         uint32_t needed;
 278         uint32_t count;
 279         union spoolss_JobInfo *info;
 280 
 281         torture_comment(tctx, "Test EnumJobs\n");
 282 
 283         ej.in.handle = handle;
 284         ej.in.level = 2;
 285         ej.in.buffer = &blob;
 286         ej.in.offered = 1024;
 287         ej.out.needed = &needed;
 288         ej.out.count = &count;
 289         ej.out.info = &info;
 290 
 291         status = dcerpc_spoolss_EnumJobs(p, tctx, &ej);
 292         torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
 293         if (W_ERROR_EQUAL(ej.out.result, WERR_INSUFFICIENT_BUFFER)) {
 294                 blob = data_blob_talloc_zero(tctx, needed);
 295                 ej.in.offered = needed;
 296                 ej.in.buffer = &blob;
 297                 status = dcerpc_spoolss_EnumJobs(p, tctx, &ej);
 298                 torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
 299         }
 300         torture_assert_werr_ok(tctx, ej.out.result, "EnumJobs failed");
 301 
 302         return true;
 303 }
 304 
 305 static bool test_GetPrinterDriver2(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 306                                         struct dcerpc_pipe *p,
 307                                         struct test_spoolss_win_context *ctx,
 308                                         struct policy_handle *handle)
 309 {
 310         NTSTATUS status;
 311         struct spoolss_GetPrinterDriver2 gpd2;
 312         DATA_BLOB blob = data_blob_talloc_zero(tctx, 87424);
 313         uint32_t needed;
 314         uint32_t server_major_version;
 315         uint32_t server_minor_version;
 316 
 317         torture_comment(tctx, "Testing GetPrinterDriver2\n");
 318 
 319         gpd2.in.handle = handle;
 320         gpd2.in.architecture = "Windows NT x86";
 321         gpd2.in.level = 101;
 322         gpd2.in.buffer = &blob;
 323         gpd2.in.offered = 87424;
 324         gpd2.in.client_major_version = 3;
 325         gpd2.in.client_minor_version = 0;
 326         gpd2.out.needed = &needed;
 327         gpd2.out.server_major_version = &server_major_version;
 328         gpd2.out.server_minor_version = &server_minor_version;
 329 
 330         status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &gpd2);
 331         torture_assert_ntstatus_ok(tctx, status, "GetPrinterDriver2 failed");
 332 
 333         if (ctx->printer_has_driver) {
 334                 torture_assert_werr_ok(tctx, gpd2.out.result,
 335                                 "GetPrinterDriver2 failed.");
 336         }
 337 
 338         return true;
 339 }
 340 
 341 static bool test_EnumForms(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 342                                 struct dcerpc_pipe *p,
 343                                 struct policy_handle *handle,
 344                                 uint32_t initial_blob_size)
 345 {
 346         NTSTATUS status;
 347         struct spoolss_EnumForms ef;
 348         DATA_BLOB blob = data_blob_talloc_zero(tctx, initial_blob_size);
 349         uint32_t needed;
 350         uint32_t count;
 351         union spoolss_FormInfo *info;
 352 
 353         torture_comment(tctx, "Testing EnumForms\n");
 354 
 355         ef.in.handle = handle;
 356         ef.in.level = 1;
 357         ef.in.buffer = (initial_blob_size == 0)?NULL:&blob;
 358         ef.in.offered = initial_blob_size;
 359         ef.out.needed = &needed;
 360         ef.out.count = &count;
 361         ef.out.info = &info;
 362 
 363         status = dcerpc_spoolss_EnumForms(p, tctx, &ef);
 364         torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
 365 
 366         if (W_ERROR_EQUAL(ef.out.result, WERR_INSUFFICIENT_BUFFER)) {
 367                 blob = data_blob_talloc_zero(tctx, needed);
 368                 ef.in.buffer = &blob;
 369                 ef.in.offered = needed;
 370                 status = dcerpc_spoolss_EnumForms(p, tctx, &ef);
 371                 torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
 372         }
 373 
 374         torture_assert_werr_ok(tctx, ef.out.result, "EnumForms failed");
 375 
 376         return true;
 377 }
 378 
 379 static bool test_EnumPrinterKey(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 380                                 struct dcerpc_pipe *p,
 381                                 struct policy_handle *handle,
 382                                 const char* key,
 383                                 struct test_spoolss_win_context *ctx)
 384 {
 385         NTSTATUS status;
 386         struct spoolss_EnumPrinterKey epk;
 387         uint32_t needed = 0;
 388         const char **key_buffer = NULL;
 389 
 390         torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key);
 391 
 392         epk.in.handle = handle;
 393         epk.in.key_name = talloc_strdup(tctx, key);
 394         epk.in.offered = 0;
 395         epk.out.needed = &needed;
 396         epk.out.key_buffer = &key_buffer;
 397 
 398         status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk);
 399         torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed");
 400 
 401 
 402         if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) {
 403                 epk.in.offered = needed;
 404                 status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk);
 405                 torture_assert_ntstatus_ok(tctx, status,
 406                                 "EnumPrinterKey failed");
 407         }
 408 
 409         torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed");
 410 
 411         ctx->printer_keys = key_buffer;
 412 
 413         return true;
 414 }
 415 
 416 static bool test_EnumPrinterDataEx(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 417                                         struct dcerpc_pipe *p,
 418                                         struct policy_handle *handle,
 419                                         const char *key,
 420                                         uint32_t initial_blob_size,
 421                                         WERROR expected_error)
 422 {
 423         NTSTATUS status;
 424         struct spoolss_EnumPrinterDataEx epde;
 425         struct spoolss_PrinterEnumValues *info;
 426         uint32_t needed;
 427         uint32_t count;
 428 
 429         torture_comment(tctx, "Testing EnumPrinterDataEx(%s)\n", key);
 430 
 431         epde.in.handle = handle;
 432         epde.in.key_name = talloc_strdup(tctx, key);
 433         epde.in.offered = 0;
 434         epde.out.needed = &needed;
 435         epde.out.count = &count;
 436         epde.out.info = &info;
 437 
 438         status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &epde);
 439         torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed.");
 440         if (W_ERROR_EQUAL(epde.out.result, WERR_MORE_DATA)) {
 441                 epde.in.offered = needed;
 442                 status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &epde);
 443                 torture_assert_ntstatus_ok(tctx, status,
 444                                 "EnumPrinterDataEx failed.");
 445         }
 446 
 447         torture_assert_werr_equal(tctx, epde.out.result, expected_error,
 448                         "EnumPrinterDataEx failed.");
 449 
 450         return true;
 451 }
 452 
 453 static bool test_ClosePrinter(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 454                                 struct dcerpc_pipe *p,
 455                                 struct policy_handle *handle)
 456 {
 457         NTSTATUS status;
 458         struct spoolss_ClosePrinter cp;
 459 
 460         cp.in.handle  = handle;
 461         cp.out.handle = handle;
 462 
 463         status = dcerpc_spoolss_ClosePrinter(p, tctx, &cp);
 464         torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
 465 
 466         return true;
 467 }
 468 
 469 static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p)
     /* [<][>][^][v][top][bottom][index][help] */
 470 {
 471         bool ret = true;
 472         struct test_spoolss_win_context *ctx, *tmp_ctx;
 473         struct policy_handle handle01, handle02, handle03, handle04;
 474         /* Sometimes a handle stays unused. In order to make this clear in the
 475          * code, the unused_handle structures are used for that. */
 476         struct policy_handle unused_handle1, unused_handle2;
 477         char *server_name;
 478         uint32_t i;
 479 
 480         ntvfs_init(tctx->lp_ctx);
 481 
 482         ctx = talloc_zero(tctx, struct test_spoolss_win_context);
 483         tmp_ctx = talloc_zero(tctx, struct test_spoolss_win_context);
 484 
 485         ret &= test_OpenPrinterSequence(tctx, p, &handle01);
 486         ret &= test_GetPrinterData(tctx, p, &handle01,"UISingleJobStatusString",
 487                         WERR_INVALID_PARAM, 0);
 488         torture_comment(tctx, "Skip RemoteFindNextPrinterChangeNotifyEx test\n");
 489 
 490         server_name = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
 491         ret &= test_OpenPrinterEx(tctx, p, &unused_handle1, server_name, 0);
 492 
 493         ret &= test_EnumPrinters(tctx, p, ctx, 1024);
 494 
 495         ret &= test_OpenPrinterEx(tctx, p, &handle02, server_name, 0);
 496         ret &= test_GetPrinterData(tctx, p, &handle02, "MajorVersion", WERR_OK,
 497                         3);
 498         ret &= test_ClosePrinter(tctx, p, &handle02);
 499 
 500         /* If no printers were found, skip all tests that need a printer */
 501         if (ctx->printer_count == 0) {
 502                 goto end_testWinXP;
 503         }
 504 
 505         ret &= test_OpenPrinterEx(tctx, p, &handle02,
 506                         ctx->printer_info[0].info2.printername,
 507                         PRINTER_ACCESS_USE);
 508         ret &= test_GetPrinter(tctx, p, &handle02, ctx, 2, 0);
 509 
 510         torture_assert_str_equal(tctx, ctx->current_info->info2.printername,
 511                         ctx->printer_info[0].info2.printername,
 512                         "GetPrinter returned unexpected printername");
 513         /*FIXME: Test more components of the PrinterInfo2 struct */
 514 
 515         ret &= test_OpenPrinterEx(tctx, p, &handle03,
 516                         ctx->printer_info[0].info2.printername, 0);
 517         ret &= test_GetPrinter(tctx, p, &handle03, ctx, 0, 1164);
 518         ret &= test_GetPrinter(tctx, p, &handle03, ctx, 2, 0);
 519 
 520         ret &= test_OpenPrinterEx(tctx, p, &handle04,
 521                         ctx->printer_info[0].info2.printername, 0);
 522         ret &= test_GetPrinter(tctx, p, &handle04, ctx, 2, 0);
 523         ret &= test_ClosePrinter(tctx, p, &handle04);
 524 
 525         ret &= test_OpenPrinterEx(tctx, p, &handle04,
 526                         ctx->printer_info[0].info2.printername, 0);
 527         ret &= test_GetPrinter(tctx, p, &handle04, ctx, 2, 4096);
 528         ret &= test_ClosePrinter(tctx, p, &handle04);
 529 
 530         ret &= test_OpenPrinterAsAdmin(tctx, p,
 531                         ctx->printer_info[0].info2.printername);
 532 
 533         ret &= test_OpenPrinterEx(tctx, p, &handle04,
 534                         ctx->printer_info[0].info2.printername, PRINTER_READ);
 535         ret &= test_GetPrinterData(tctx, p, &handle04,"UISingleJobStatusString",
 536                         WERR_BADFILE, 0);
 537         torture_comment(tctx, "Skip RemoteFindNextPrinterChangeNotifyEx test\n");
 538 
 539         ret &= test_OpenPrinterEx(tctx, p, &unused_handle2,
 540                         ctx->printer_info[0].info2.printername, 0);
 541 
 542         ret &= test_EnumJobs(tctx, p, &handle04);
 543         ret &= test_GetPrinter(tctx, p, &handle04, ctx, 2, 4096);
 544 
 545         ret &= test_ClosePrinter(tctx, p, &unused_handle2);
 546         ret &= test_ClosePrinter(tctx, p, &handle04);
 547 
 548         ret &= test_EnumPrinters(tctx, p, ctx, 1556);
 549         ret &= test_GetPrinterDriver2(tctx, p, ctx, &handle03);
 550         ret &= test_EnumForms(tctx, p, &handle03, 0);
 551 
 552         ret &= test_EnumPrinterKey(tctx, p, &handle03, "", ctx);
 553 
 554         for (i=0; ctx->printer_keys[i] != NULL; i++) {
 555 
 556                 ret &= test_EnumPrinterKey(tctx, p, &handle03,
 557                                            ctx->printer_keys[i],
 558                                            tmp_ctx);
 559                 ret &= test_EnumPrinterDataEx(tctx, p, &handle03,
 560                                               ctx->printer_keys[i], 0,
 561                                               WERR_OK);
 562         }
 563 
 564         ret &= test_EnumPrinterDataEx(tctx, p, &handle03, "", 0,
 565                         WERR_INVALID_PARAM);
 566 
 567         ret &= test_GetPrinter(tctx, p, &handle03, tmp_ctx, 2, 0);
 568 
 569         ret &= test_OpenPrinterEx(tctx, p, &unused_handle2,
 570                         ctx->printer_info[0].info2.printername, 0);
 571         ret &= test_ClosePrinter(tctx, p, &unused_handle2);
 572 
 573         ret &= test_GetPrinter(tctx, p, &handle03, tmp_ctx, 2, 2556);
 574 
 575         ret &= test_OpenPrinterEx(tctx, p, &unused_handle2,
 576                         ctx->printer_info[0].info2.printername, 0);
 577         ret &= test_ClosePrinter(tctx, p, &unused_handle2);
 578 
 579         ret &= test_OpenPrinterEx(tctx, p, &unused_handle2,
 580                         ctx->printer_info[0].info2.printername, 0);
 581         ret &= test_ClosePrinter(tctx, p, &unused_handle2);
 582 
 583         ret &= test_GetPrinter(tctx, p, &handle03, tmp_ctx, 7, 0);
 584 
 585         ret &= test_OpenPrinterEx(tctx, p, &unused_handle2,
 586                         ctx->printer_info[0].info2.printername, 0);
 587         ret &= test_ClosePrinter(tctx, p, &unused_handle2);
 588 
 589         ret &= test_ClosePrinter(tctx, p, &handle03);
 590 
 591         ret &= test_OpenPrinterEx(tctx, p, &unused_handle2,
 592                         ctx->printer_info[0].info2.printername, 0);
 593         ret &= test_ClosePrinter(tctx, p, &unused_handle2);
 594 
 595         ret &= test_OpenPrinterEx(tctx, p, &handle03, server_name, 0);
 596         ret &= test_GetPrinterData(tctx, p, &handle03, "W3SvcInstalled",
 597                         WERR_OK, 0);
 598         ret &= test_ClosePrinter(tctx, p, &handle03);
 599 
 600         ret &= test_ClosePrinter(tctx, p, &unused_handle1);
 601         ret &= test_ClosePrinter(tctx, p, &handle02);
 602 
 603         ret &= test_OpenPrinterEx(tctx, p, &handle02,
 604                         ctx->printer_info[0].info2.sharename, 0);
 605         ret &= test_GetPrinter(tctx, p, &handle02, tmp_ctx, 2, 0);
 606         ret &= test_ClosePrinter(tctx, p, &handle02);
 607 
 608 end_testWinXP:
 609         ret &= test_ClosePrinter(tctx, p, &handle01);
 610 
 611         talloc_free(tmp_ctx);
 612         talloc_free(ctx);
 613         return ret;
 614 }
 615 
 616 struct torture_suite *torture_rpc_spoolss_win(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 617 {
 618         struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-WIN");
 619 
 620         struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite, 
 621                                                         "win", &ndr_table_spoolss);
 622 
 623         torture_rpc_tcase_add_test(tcase, "testWinXP", test_WinXP);
 624 
 625         return suite;
 626 }
 627 

/* [<][>][^][v][top][bottom][index][help] */