void print_spool_end(files_struct *fsp, enum file_close_type close_type) { NTSTATUS status; WERROR werr; struct dcerpc_binding_handle *b = NULL; b = fsp->conn->spoolss_pipe->binding_handle; switch (close_type) { case NORMAL_CLOSE: case SHUTDOWN_CLOSE: /* this also automatically calls spoolss_EndDocPrinter */ status = dcerpc_spoolss_ClosePrinter(b, fsp->print_file, &fsp->print_file->handle, &werr); if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(status = werror_to_ntstatus(werr))) { DEBUG(3, ("Failed to close printer %s [%s]\n", fsp->print_file->svcname, nt_errstr(status))); } break; case ERROR_CLOSE: print_spool_terminate(fsp->conn, fsp->print_file); break; } }
void print_spool_terminate(struct connection_struct *conn, struct print_file_data *print_file) { NTSTATUS status; WERROR werr; struct dcerpc_binding_handle *b = NULL; rap_jobid_delete(print_file->svcname, print_file->jobid); status = rpc_pipe_open_interface(conn, &ndr_table_spoolss.syntax_id, conn->session_info, &conn->sconn->client_id, conn->sconn->msg_ctx, &conn->spoolss_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("print_spool_terminate: " "Failed to get spoolss pipe [%s]\n", nt_errstr(status))); return; } b = conn->spoolss_pipe->binding_handle; status = dcerpc_spoolss_SetJob(b, print_file, &print_file->handle, print_file->jobid, NULL, SPOOLSS_JOB_CONTROL_DELETE, &werr); if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(status = werror_to_ntstatus(werr))) { DEBUG(3, ("Failed to delete job %d [%s]\n", print_file->jobid, nt_errstr(status))); return; } status = dcerpc_spoolss_ClosePrinter(b, print_file, &print_file->handle, &werr); if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(status = werror_to_ntstatus(werr))) { DEBUG(3, ("Failed to close printer %s [%s]\n", print_file->svcname, nt_errstr(status))); return; } }
WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, ADS_MODLIST *mods, const char *printer) { struct dcerpc_binding_handle *b = cli->binding_handle; WERROR result; char *printername; struct spoolss_PrinterEnumValues *info; uint32_t count; uint32 i; struct policy_handle pol; WERROR werr; if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) { DEBUG(3, ("Insufficient memory\n")); return WERR_NOMEM; } result = rpccli_spoolss_openprinter_ex(cli, mem_ctx, printername, SEC_FLAG_MAXIMUM_ALLOWED, &pol); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to open printer %s, error is %s.\n", printername, win_errstr(result))); SAFE_FREE(printername); return result; } result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, 0, &count, &info); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, win_errstr(result))); } else { /* Have the data we need now, so start building */ for (i=0; i < count; i++) { struct registry_value v; v.type = info[i].type; v.data = *info[i].data; map_regval_to_ads(mem_ctx, mods, info[i].value_name, &v); } } result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, 0, &count, &info); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, win_errstr(result))); } else { for (i=0; i < count; i++) { struct registry_value v; v.type = info[i].type; v.data = *info[i].data; map_regval_to_ads(mem_ctx, mods, info[i].value_name, &v); } } ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer); dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &werr); SAFE_FREE(printername); return result; }