testprogs: rename test_PrinterData to test_PrinterData_Server.
[ira/wip.git] / testprogs / win32 / spoolss / spoolss.c
index b83259dd90a934953b77efbde8702dff91e2ead0..0edb5337cf4691cc91ca252f6c3eb5e018d20489 100644 (file)
@@ -228,7 +228,7 @@ static BOOL test_EnumForms(struct torture_context *tctx,
                           HANDLE handle)
 {
        DWORD levels[]  = { 1, 2 };
-       DWORD success[] = { 1, 0 };
+       DWORD success[] = { 1, 1 };
        DWORD i;
        LPBYTE buffer = NULL;
 
@@ -241,6 +241,11 @@ static BOOL test_EnumForms(struct torture_context *tctx,
 
                torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
 
+               if (tctx->samba3 && levels[i] == 2) {
+                       torture_comment(tctx, "skipping level %d enum against samba\n", levels[i]);
+                       continue;
+               }
+
                EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
                err = GetLastError();
                if (err == ERROR_INSUFFICIENT_BUFFER) {
@@ -638,6 +643,11 @@ static BOOL test_EnumJobs(struct torture_context *tctx,
 
                torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
 
+               if (tctx->samba3 && levels[i] == 4) {
+                       torture_comment(tctx, "skipping level %d enum against samba\n", levels[i]);
+                       continue;
+               }
+
                EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
                err = GetLastError();
                if (err == ERROR_INSUFFICIENT_BUFFER) {
@@ -720,6 +730,236 @@ static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
        return TRUE;
 }
 
+/****************************************************************************
+****************************************************************************/
+
+static BOOL test_devicemode_equal(struct torture_context *tctx,
+                                 const DEVMODE *d1,
+                                 const DEVMODE *d2)
+{
+       if (d1 == d2) {
+               return TRUE;
+       }
+
+       if (!d1 || !d2) {
+               torture_comment(tctx, "%s\n", __location__);
+               return FALSE;
+       }
+
+       torture_assert_str_equal(tctx, (const char *)d1->dmDeviceName, (const char *)d2->dmDeviceName, "dmDeviceName mismatch");
+       torture_assert_int_equal(tctx, d1->dmSpecVersion, d2->dmSpecVersion, "dmSpecVersion mismatch");
+       torture_assert_int_equal(tctx, d1->dmDriverVersion, d2->dmDriverVersion, "dmDriverVersion mismatch");
+       torture_assert_int_equal(tctx, d1->dmSize, d2->dmSize, "size mismatch");
+       torture_assert_int_equal(tctx, d1->dmDriverExtra, d2->dmDriverExtra, "dmDriverExtra mismatch");
+       torture_assert_int_equal(tctx, d1->dmFields, d2->dmFields, "dmFields mismatch");
+
+       torture_assert_int_equal(tctx, d1->dmOrientation, d2->dmOrientation, "dmOrientation mismatch");
+       torture_assert_int_equal(tctx, d1->dmPaperSize, d2->dmPaperSize, "dmPaperSize mismatch");
+       torture_assert_int_equal(tctx, d1->dmPaperLength, d2->dmPaperLength, "dmPaperLength mismatch");
+       torture_assert_int_equal(tctx, d1->dmPaperWidth, d2->dmPaperWidth, "dmPaperWidth mismatch");
+       torture_assert_int_equal(tctx, d1->dmScale, d2->dmScale, "dmScale mismatch");
+       torture_assert_int_equal(tctx, d1->dmCopies, d2->dmCopies, "dmCopies mismatch");
+       torture_assert_int_equal(tctx, d1->dmDefaultSource, d2->dmDefaultSource, "dmDefaultSource mismatch");
+       torture_assert_int_equal(tctx, d1->dmPrintQuality, d2->dmPrintQuality, "dmPrintQuality mismatch");
+
+       torture_assert_int_equal(tctx, d1->dmColor, d2->dmColor, "dmColor mismatch");
+       torture_assert_int_equal(tctx, d1->dmDuplex, d2->dmDuplex, "dmDuplex mismatch");
+       torture_assert_int_equal(tctx, d1->dmYResolution, d2->dmYResolution, "dmYResolution mismatch");
+       torture_assert_int_equal(tctx, d1->dmTTOption, d2->dmTTOption, "dmTTOption mismatch");
+       torture_assert_int_equal(tctx, d1->dmCollate, d2->dmCollate, "dmCollate mismatch");
+       torture_assert_str_equal(tctx, (const char *)d1->dmFormName, (const char *)d2->dmFormName, "dmFormName mismatch");
+       torture_assert_int_equal(tctx, d1->dmLogPixels, d2->dmLogPixels, "dmLogPixels mismatch");
+       torture_assert_int_equal(tctx, d1->dmBitsPerPel, d2->dmBitsPerPel, "dmBitsPerPel mismatch");
+       torture_assert_int_equal(tctx, d1->dmPelsWidth, d2->dmPelsWidth, "dmPelsWidth mismatch");
+       torture_assert_int_equal(tctx, d1->dmPelsHeight, d2->dmPelsHeight, "dmPelsHeight mismatch");
+
+       torture_assert_int_equal(tctx, d1->dmDisplayFlags, d2->dmDisplayFlags, "dmDisplayFlags mismatch");
+       /* or dmNup ? */
+       torture_assert_int_equal(tctx, d1->dmDisplayFrequency, d2->dmDisplayFrequency, "dmDisplayFrequency mismatch");
+
+       torture_assert_int_equal(tctx, d1->dmICMMethod, d2->dmICMMethod, "dmICMMethod mismatch");
+       torture_assert_int_equal(tctx, d1->dmICMIntent, d2->dmICMIntent, "dmICMIntent mismatch");
+       torture_assert_int_equal(tctx, d1->dmMediaType, d2->dmMediaType, "dmMediaType mismatch");
+       torture_assert_int_equal(tctx, d1->dmDitherType, d2->dmDitherType, "dmDitherType mismatch");
+       torture_assert_int_equal(tctx, d1->dmReserved1, d2->dmReserved1, "dmReserved1 mismatch");
+       torture_assert_int_equal(tctx, d1->dmReserved2, d2->dmReserved2, "reserved2 mismatch");
+
+       torture_assert_int_equal(tctx, d1->dmPanningWidth, d2->dmPanningWidth, "dmPanningWidth mismatch");
+       torture_assert_int_equal(tctx, d1->dmPanningHeight, d2->dmPanningHeight, "dmPanningHeight mismatch");
+
+       /* torture_assert_mem_equal(tctx, d1 + d1->dmSize, d2 + d2->dmSize, d1->dmDriverExtra, "private extra data mismatch"); */
+
+       return TRUE;
+}
+
+static BOOL test_DeviceModes(struct torture_context *tctx,
+                            LPSTR printername,
+                            HANDLE handle)
+{
+       PPRINTER_INFO_2 info2 = NULL;
+       PPRINTER_INFO_8 info8 = NULL;
+       DWORD needed = 0;
+       DWORD err = 0;
+       char tmp[1024];
+
+       torture_comment(tctx, "Testing DeviceModes");
+
+       torture_comment(tctx, "Testing GetPrinter level %d", 2);
+
+       GetPrinter(handle, 2, NULL, 0, &needed);
+       err = GetLastError();
+       if (err == ERROR_INSUFFICIENT_BUFFER) {
+               err = 0;
+               info2 = (PPRINTER_INFO_2)malloc(needed);
+               torture_assert(tctx, (LPBYTE)info2, "malloc failed");
+               if (!GetPrinter(handle, 2, (LPBYTE)info2, needed, &needed)) {
+                       err = GetLastError();
+               }
+       }
+       if (err) {
+               sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
+                       2, printername, needed, errstr(err));
+               torture_fail(tctx, tmp);
+       }
+
+       if (tctx->print) {
+               print_printer_info_2(info2);
+       }
+
+       torture_comment(tctx, "Testing GetPrinter level %d", 8);
+
+       GetPrinter(handle, 8, NULL, 0, &needed);
+       err = GetLastError();
+       if (err == ERROR_INSUFFICIENT_BUFFER) {
+               err = 0;
+               info8 = (PPRINTER_INFO_8)malloc(needed);
+               torture_assert(tctx, (LPBYTE)info8, "malloc failed");
+               if (!GetPrinter(handle, 8, (LPBYTE)info8, needed, &needed)) {
+                       err = GetLastError();
+               }
+       }
+       if (err) {
+               sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
+                       8, printername, needed, errstr(err));
+               torture_fail(tctx, tmp);
+       }
+
+       if (tctx->print) {
+               print_printer_info_8(info8);
+       }
+
+       torture_assert(tctx, test_devicemode_equal(tctx, info2->pDevMode, info8->pDevMode), "");
+
+       free(info2);
+       free(info8);
+
+       return TRUE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL test_GetJob(struct torture_context *tctx,
+                       LPSTR printername,
+                       HANDLE handle,
+                       DWORD job_id)
+{
+       DWORD levels[]  = { 1, 2, 3, 4 };
+       DWORD success[] = { 1, 1, 1, 1 };
+       DWORD i;
+       LPBYTE buffer = NULL;
+
+       for (i=0; i < ARRAY_SIZE(levels); i++) {
+
+               DWORD needed = 0;
+               DWORD err = 0;
+               char tmp[1024];
+
+               torture_comment(tctx, "Testing GetJob(%d) level %d", job_id, levels[i]);
+
+               if (tctx->samba3 && (levels[i] == 4) || (levels[i] == 3)) {
+                       torture_comment(tctx, "skipping level %d getjob against samba\n", levels[i]);
+                       continue;
+               }
+
+               GetJob(handle, job_id, levels[i], NULL, 0, &needed);
+               err = GetLastError();
+               if (err == ERROR_INSUFFICIENT_BUFFER) {
+                       err = 0;
+                       buffer = malloc(needed);
+                       torture_assert(tctx, buffer, "malloc failed");
+                       if (!GetJob(handle, job_id, levels[i], buffer, needed, &needed)) {
+                               err = GetLastError();
+                       }
+               }
+               if (err) {
+                       sprintf(tmp, "GetJob failed level %d on [%s] (buffer size = %d), error: %s\n",
+                               levels[i], printername, needed, errstr(err));
+                       if (success[i]) {
+                               torture_fail(tctx, tmp);
+                       } else {
+                               torture_warning(tctx, tmp);
+                       }
+               }
+
+               if (tctx->print) {
+                       print_job_info_bylevel(levels[i], buffer, 1);
+               }
+
+               free(buffer);
+               buffer = NULL;
+       }
+
+       return TRUE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL test_EachJob(struct torture_context *tctx,
+                        LPSTR printername,
+                        HANDLE handle)
+{
+       DWORD i;
+       PJOB_INFO_1 buffer = NULL;
+       DWORD needed = 0;
+       DWORD returned = 0;
+       DWORD err = 0;
+       DWORD level = 1;
+       char tmp[1024];
+       BOOL ret = TRUE;
+
+       torture_comment(tctx, "Testing Each PrintJob %d");
+
+       EnumJobs(handle, 0, 100, level, NULL, 0, &needed, &returned);
+       err = GetLastError();
+       if (err == ERROR_INSUFFICIENT_BUFFER) {
+               err = 0;
+               buffer = (PJOB_INFO_1)malloc(needed);
+               torture_assert(tctx, buffer, "malloc failed");
+               if (!EnumJobs(handle, 0, 100, level, (LPBYTE)buffer, needed, &needed, &returned)) {
+                       err = GetLastError();
+               }
+       }
+       if (err) {
+               sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
+                       level, printername, needed, errstr(err));
+               torture_fail(tctx, tmp);
+       }
+
+       if (tctx->print) {
+               print_job_info_bylevel(level, (LPBYTE)buffer, returned);
+       }
+
+       for (i=0; i < returned; i++) {
+               ret = test_GetJob(tctx, printername, handle, buffer[i].JobId);
+       }
+
+       free(buffer);
+
+       return ret;
+
+}
 
 /****************************************************************************
 ****************************************************************************/
@@ -739,9 +979,11 @@ static BOOL test_OnePrinter(struct torture_context *tctx,
        ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
        ret &= test_EnumForms(tctx, printername, handle);
        ret &= test_EnumJobs(tctx, printername, handle);
+       ret &= test_EachJob(tctx, printername, handle);
        ret &= test_EnumPrinterKey(tctx, printername, handle, "");
        ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
        ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
+       ret &= test_DeviceModes(tctx, printername, handle);
        ret &= test_ClosePrinter(tctx, handle);
 
        return ret;
@@ -831,6 +1073,10 @@ static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
                        }
                }
 
+               if (tctx->print) {
+                       printf("\tPrint Processor Directory\t= %s\n\n", (LPSTR)buffer);
+               }
+
                free(buffer);
                buffer = NULL;
        }
@@ -878,6 +1124,10 @@ static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
                        }
                }
 
+               if (tctx->print) {
+                       printf("\tPrinter Driver Directory\t= %s\n\n", (LPSTR)buffer);
+               }
+
                free(buffer);
                buffer = NULL;
        }
@@ -993,9 +1243,83 @@ static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
 /****************************************************************************
 ****************************************************************************/
 
-static BOOL test_PrinterData(struct torture_context *tctx,
-                            LPSTR servername,
-                            HANDLE handle)
+static BOOL test_DeletePrinterDataEx(struct torture_context *tctx,
+                                    LPSTR servername,
+                                    LPSTR keyname,
+                                    LPSTR valuename,
+                                    HANDLE handle)
+{
+       DWORD err = 0;
+       char tmp[1024];
+
+       torture_comment(tctx, "Testing DeletePrinterDataEx(%s - %s)", keyname, valuename);
+
+       err = DeletePrinterDataEx(handle, keyname, valuename);
+       if (err) {
+               sprintf(tmp, "DeletePrinterDataEx(%s - %s) failed on [%s], error: %s\n",
+                       keyname, valuename, servername, errstr(err));
+               torture_fail(tctx, tmp);
+       }
+
+       return TRUE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL test_DeletePrinterKey(struct torture_context *tctx,
+                                 LPSTR servername,
+                                 LPSTR keyname,
+                                 HANDLE handle)
+{
+       DWORD err = 0;
+       char tmp[1024];
+
+       torture_comment(tctx, "Testing DeletePrinterKey(%s)", keyname);
+
+       err = DeletePrinterKey(handle, keyname);
+       if (err) {
+               sprintf(tmp, "DeletePrinterKey(%s) failed on [%s], error: %s\n",
+                       keyname, servername, errstr(err));
+               torture_fail(tctx, tmp);
+       }
+
+       return TRUE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL test_SetPrinterDataEx(struct torture_context *tctx,
+                                 LPSTR servername,
+                                 LPSTR keyname,
+                                 LPSTR valuename,
+                                 HANDLE handle,
+                                 DWORD type,
+                                 LPBYTE buffer,
+                                 DWORD offered)
+{
+       DWORD err = 0;
+       char tmp[1024];
+
+       torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s)", keyname, valuename);
+
+       err = SetPrinterDataEx(handle, keyname, valuename, type, buffer, offered);
+       if (err) {
+               sprintf(tmp, "SetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
+                       valuename, servername, offered, errstr(err));
+               torture_fail(tctx, tmp);
+       }
+
+       return TRUE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL test_PrinterData_Server(struct torture_context *tctx,
+                                   LPSTR servername,
+                                   HANDLE handle)
 {
        BOOL ret = TRUE;
        DWORD i;
@@ -1028,6 +1352,21 @@ static BOOL test_PrinterData(struct torture_context *tctx,
 /****************************************************************************
 ****************************************************************************/
 
+const char *get_string_param(const char *str)
+{
+       const char *p;
+
+       p = strchr(str, '=');
+       if (!p) {
+               return NULL;
+       }
+
+       return (p+1);
+}
+
+/****************************************************************************
+****************************************************************************/
+
 int main(int argc, char *argv[])
 {
        BOOL ret = FALSE;
@@ -1036,9 +1375,10 @@ int main(int argc, char *argv[])
        HANDLE server_handle;
        PRINTER_DEFAULTS defaults_admin, defaults_use;
        struct torture_context *tctx;
+       int i;
 
        if (argc < 2) {
-               fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
+               fprintf(stderr, "usage: %s <servername> [print] [samba3] [architecture=ARCHITECTURE]\n", argv[0]);
                exit(-1);
        }
 
@@ -1051,12 +1391,20 @@ int main(int argc, char *argv[])
 
        servername = argv[1];
 
-       if (argc >= 3) {
-               if (strcmp(argv[2], "print") == 0) {
+       for (i=1; i < argc; i++) {
+               if (strcmp(argv[i], "print") == 0) {
                        tctx->print = TRUE;
                }
+               if (strcmp(argv[i], "samba3") == 0) {
+                       tctx->samba3 = TRUE;
+               }
+               if (strncmp(argv[i], "architecture", strlen("architecture")) == 0) {
+                       architecture = get_string_param(argv[i]);
+               }
        }
 
+       printf("Running testsuite with architecture: %s\n", architecture);
+
        defaults_admin.pDatatype = NULL;
        defaults_admin.pDevMode = NULL;
        defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
@@ -1065,11 +1413,20 @@ int main(int argc, char *argv[])
        defaults_use.pDevMode = NULL;
        defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
 
+       if ((servername[0] == '\\') && (servername[1] == '\\')) {
+               LPSTR p = servername+2;
+               LPSTR p2;
+               if ((p2 = strchr(p, '\\')) != NULL) {
+                       ret = test_OnePrinter(tctx, servername, architecture, NULL);
+                       goto done;
+               }
+       }
+
        ret &= test_EnumPrinters(tctx, servername);
        ret &= test_EnumDrivers(tctx, servername, architecture);
        ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
 /*     ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
-       ret &= test_PrinterData(tctx, servername, server_handle);
+       ret &= test_PrinterData_Server(tctx, servername, server_handle);
        ret &= test_EnumForms(tctx, servername, server_handle);
        ret &= test_ClosePrinter(tctx, server_handle);
        ret &= test_EnumPorts(tctx, servername);
@@ -1080,6 +1437,7 @@ int main(int argc, char *argv[])
        ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
        ret &= test_EachPrinter(tctx, servername, architecture, NULL);
 
+ done:
        if (!ret) {
                if (tctx->last_reason) {
                        fprintf(stderr, "failed: %s\n", tctx->last_reason);