summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_spoolss_nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server/srv_spoolss_nt.c')
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c3400
1 files changed, 1534 insertions, 1866 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 0a4f5ae05c..950dc013b2 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -27,6 +27,16 @@
#include "includes.h"
+/* macros stolen from s4 spoolss server */
+#define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
+ ((info)?ndr_size_##fn(info, level, ic, 0):0)
+
+#define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
+ ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
+
+#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
+
+
extern userdom_struct current_user_info;
#undef DBGC_CLASS
@@ -3914,149 +3924,81 @@ done:
* fill a printer_info_0 struct
********************************************************************/
-static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
+static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo0 *r,
+ int snum)
{
- char *chaine = NULL;
int count;
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
counter_printer_0 *session_counter;
- uint32 global_counter;
- struct tm *t;
time_t setuptime;
print_status_struct status;
- TALLOC_CTX *ctx = talloc_tos();
-
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
- init_unistr(&printer->printername, ntprinter->info_2->printername);
+ r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+ W_ERROR_HAVE_NO_MEMORY(r->printername);
- chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
- if (!chaine) {
- free_a_printer(&ntprinter,2);
- return false;
- }
+ r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+ W_ERROR_HAVE_NO_MEMORY(r->servername);
count = print_queue_length(snum, &status);
/* check if we already have a counter for this printer */
- for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
+ for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
if (session_counter->snum == snum)
break;
}
- init_unistr(&printer->servername, chaine);
-
/* it's the first time, add it to the list */
- if (session_counter==NULL) {
- if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
- free_a_printer(&ntprinter, 2);
- return False;
- }
+ if (session_counter == NULL) {
+ session_counter = SMB_MALLOC_P(counter_printer_0);
+ W_ERROR_HAVE_NO_MEMORY(session_counter);
ZERO_STRUCTP(session_counter);
- session_counter->snum=snum;
- session_counter->counter=0;
+ session_counter->snum = snum;
+ session_counter->counter = 0;
DLIST_ADD(counter_list, session_counter);
}
/* increment it */
session_counter->counter++;
- /* JFM:
- * the global_counter should be stored in a TDB as it's common to all the clients
- * and should be zeroed on samba startup
- */
- global_counter=session_counter->counter;
- printer->cjobs = count;
- printer->total_jobs = 0;
- printer->total_bytes = 0;
+ r->cjobs = count;
+ r->total_jobs = 0;
+ r->total_bytes = 0;
setuptime = (time_t)ntprinter->info_2->setuptime;
- t=gmtime(&setuptime);
-
- printer->year = t->tm_year+1900;
- printer->month = t->tm_mon+1;
- printer->dayofweek = t->tm_wday;
- printer->day = t->tm_mday;
- printer->hour = t->tm_hour;
- printer->minute = t->tm_min;
- printer->second = t->tm_sec;
- printer->milliseconds = 0;
- printer->global_counter = global_counter;
- printer->total_pages = 0;
+ init_systemtime(&r->time, gmtime(&setuptime));
+ /* JFM:
+ * the global_counter should be stored in a TDB as it's common to all the clients
+ * and should be zeroed on samba startup
+ */
+ r->global_counter = session_counter->counter;
+ r->total_pages = 0;
/* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
- printer->major_version = 0x0005; /* NT 5 */
- printer->build_version = 0x0893; /* build 2195 */
-
- printer->unknown7 = 0x1;
- printer->unknown8 = 0x0;
- printer->unknown9 = 0x0;
- printer->session_counter = session_counter->counter;
- printer->unknown11 = 0x0;
- printer->printer_errors = 0x0; /* number of print failure */
- printer->unknown13 = 0x0;
- printer->unknown14 = 0x1;
- printer->unknown15 = 0x024a; /* 586 Pentium ? */
- printer->unknown16 = 0x0;
- printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
- printer->unknown18 = 0x0;
- printer->status = nt_printq_status(status.status);
- printer->unknown20 = 0x0;
- printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
- printer->unknown22 = 0x0;
- printer->unknown23 = 0x6; /* 6 ???*/
- printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
- printer->unknown25 = 0;
- printer->unknown26 = 0;
- printer->unknown27 = 0;
- printer->unknown28 = 0;
- printer->unknown29 = 0;
-
- free_a_printer(&ntprinter,2);
- return (True);
-}
-
-/********************************************************************
- * construct_printer_info_1
- * fill a printer_info_1 struct
- ********************************************************************/
-static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
-{
- char *chaine = NULL;
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- TALLOC_CTX *ctx = talloc_tos();
-
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return false;
-
- printer->flags=flags;
+ r->version = 0x0005; /* NT 5 */
+ r->free_build = 0x0893; /* build 2195 */
+ r->spooling = 0;
+ r->max_spooling = 0;
+ r->session_counter = session_counter->counter;
+ r->num_error_out_of_paper = 0x0;
+ r->num_error_not_ready = 0x0; /* number of print failure */
+ r->job_error = 0x0;
+ r->number_of_processors = 0x1;
+ r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
+ r->high_part_total_bytes = 0x0;
+ r->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
+ r->last_error = WERR_OK;
+ r->status = nt_printq_status(status.status);
+ r->enumerate_network_printers = 0x0;
+ r->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
+ r->processor_architecture = 0x0;
+ r->processor_level = 0x6; /* 6 ???*/
+ r->ref_ic = 0;
+ r->reserved2 = 0;
+ r->reserved3 = 0;
- if (*ntprinter->info_2->comment == '\0') {
- init_unistr(&printer->comment, lp_comment(snum));
- chaine = talloc_asprintf(ctx,
- "%s,%s,%s", ntprinter->info_2->printername,
- ntprinter->info_2->drivername, lp_comment(snum));
- }
- else {
- init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
- chaine = talloc_asprintf(ctx,
- "%s,%s,%s", ntprinter->info_2->printername,
- ntprinter->info_2->drivername, ntprinter->info_2->comment);
- }
-
- if (!chaine) {
- free_a_printer(&ntprinter,2);
- return false;
- }
-
- init_unistr(&printer->description, chaine);
- init_unistr(&printer->name, ntprinter->info_2->printername);
-
- free_a_printer(&ntprinter,2);
-
- return True;
+ return WERR_OK;
}
/****************************************************************************
@@ -4072,6 +4014,73 @@ static void free_dev_mode(DEVICEMODE *dev)
SAFE_FREE(dev);
}
+/****************************************************************************
+ Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers
+ should be valid upon entry
+****************************************************************************/
+
+static WERROR convert_nt_devicemode_new(TALLOC_CTX *mem_ctx,
+ struct spoolss_DeviceMode *r,
+ const NT_DEVICEMODE *ntdevmode)
+{
+ if (!r || !ntdevmode) {
+ return WERR_INVALID_PARAM;
+ }
+
+ r->devicename = talloc_strdup(mem_ctx, ntdevmode->devicename);
+ W_ERROR_HAVE_NO_MEMORY(r->devicename);
+
+ r->specversion = ntdevmode->specversion;
+ r->driverversion = ntdevmode->driverversion;
+ r->size = ntdevmode->size;
+ r->__driverextra_length = ntdevmode->driverextra;
+ r->fields = ntdevmode->fields;
+
+ r->orientation = ntdevmode->orientation;
+ r->papersize = ntdevmode->papersize;
+ r->paperlength = ntdevmode->paperlength;
+ r->paperwidth = ntdevmode->paperwidth;
+ r->scale = ntdevmode->scale;
+ r->copies = ntdevmode->copies;
+ r->defaultsource = ntdevmode->defaultsource;
+ r->printquality = ntdevmode->printquality;
+ r->color = ntdevmode->color;
+ r->duplex = ntdevmode->duplex;
+ r->yresolution = ntdevmode->yresolution;
+ r->ttoption = ntdevmode->ttoption;
+ r->collate = ntdevmode->collate;
+
+ r->formname = talloc_strdup(mem_ctx, ntdevmode->formname);
+ W_ERROR_HAVE_NO_MEMORY(r->formname);
+
+ /* all 0 below are values that have not been set in the old parsing/copy
+ * function, maybe they should... - gd */
+
+ r->logpixels = 0;
+ r->bitsperpel = 0;
+ r->pelswidth = 0;
+ r->pelsheight = 0;
+ r->displayflags = 0;
+ r->displayfrequency = 0;
+ r->icmmethod = ntdevmode->icmmethod;
+ r->icmintent = ntdevmode->icmintent;
+ r->mediatype = ntdevmode->mediatype;
+ r->dithertype = ntdevmode->dithertype;
+ r->reserved1 = 0;
+ r->reserved2 = 0;
+ r->panningwidth = 0;
+ r->panningheight = 0;
+
+ if (ntdevmode->nt_dev_private != NULL) {
+ r->driverextra_data = data_blob_talloc(mem_ctx,
+ ntdevmode->nt_dev_private,
+ ntdevmode->driverextra);
+ W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
+ }
+
+ return WERR_OK;
+}
+
/****************************************************************************
Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
@@ -4120,6 +4129,48 @@ static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode
}
/****************************************************************************
+ Create a spoolss_DeviceMode struct. Returns talloced memory.
+****************************************************************************/
+
+struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
+ const char *servicename)
+{
+ WERROR result;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ struct spoolss_DeviceMode *devmode = NULL;
+
+ DEBUG(7,("construct_dev_mode_new\n"));
+
+ DEBUGADD(8,("getting printer characteristics\n"));
+
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
+ return NULL;
+
+ if (!printer->info_2->devmode) {
+ DEBUG(5, ("BONG! There was no device mode!\n"));
+ goto done;
+ }
+
+ devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
+ if (!devmode) {
+ DEBUG(2,("construct_dev_mode_new: talloc fail.\n"));
+ goto done;
+ }
+
+ DEBUGADD(8,("loading DEVICEMODE\n"));
+
+ result = convert_nt_devicemode_new(mem_ctx, devmode, printer->info_2->devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(devmode);
+ }
+
+done:
+ free_a_printer(&printer,2);
+
+ return devmode;
+}
+
+/****************************************************************************
Create a DEVMODE struct. Returns malloced memory.
****************************************************************************/
@@ -4161,298 +4212,336 @@ done:
}
/********************************************************************
- * construct_printer_info_2
- * fill a printer_info_2 struct
+ * construct_printer_info3
+ * fill a spoolss_PrinterInfo3 struct
********************************************************************/
-static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
+static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo3 *r,
+ int snum)
{
- int count;
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-
- print_status_struct status;
-
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
-
- count = print_queue_length(snum, &status);
-
- init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
- init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
- init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
- init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
- init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
-
- if (*ntprinter->info_2->comment == '\0')
- init_unistr(&printer->comment, lp_comment(snum)); /* comment */
- else
- init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
-
- init_unistr(&printer->location, ntprinter->info_2->location); /* location */
- init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
- init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
- init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
- init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
-
- printer->attributes = ntprinter->info_2->attributes;
-
- printer->priority = ntprinter->info_2->priority; /* priority */
- printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
- printer->starttime = ntprinter->info_2->starttime; /* starttime */
- printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
- printer->status = nt_printq_status(status.status); /* status */
- printer->cjobs = count; /* jobs */
- printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
-
- if ( !(printer->devmode = construct_dev_mode(
- lp_const_servicename(snum))) )
- DEBUG(8, ("Returning NULL Devicemode!\n"));
-
- printer->secdesc = NULL;
+ /* These are the components of the SD we are returning. */
- if ( ntprinter->info_2->secdesc_buf
- && ntprinter->info_2->secdesc_buf->sd_size != 0 )
- {
+ if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
/* don't use talloc_steal() here unless you do a deep steal of all
the SEC_DESC members */
- printer->secdesc = dup_sec_desc( talloc_tos(),
- ntprinter->info_2->secdesc_buf->sd );
+ r->secdesc = dup_sec_desc(mem_ctx,
+ ntprinter->info_2->secdesc_buf->sd);
+ W_ERROR_HAVE_NO_MEMORY(r->secdesc);
}
- free_a_printer(&ntprinter, 2);
-
- return True;
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_3
- * fill a printer_info_3 struct
+ * construct_printer_info4
+ * fill a spoolss_PrinterInfo4 struct
********************************************************************/
-static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
+static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo4 *r,
+ int snum)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- PRINTER_INFO_3 *printer = NULL;
+ r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+ W_ERROR_HAVE_NO_MEMORY(r->printername);
+ r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+ W_ERROR_HAVE_NO_MEMORY(r->servername);
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
+ r->attributes = ntprinter->info_2->attributes;
- *pp_printer = NULL;
- if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
- DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
- free_a_printer(&ntprinter, 2);
- return False;
- }
+ return WERR_OK;
+}
- ZERO_STRUCTP(printer);
+/********************************************************************
+ * construct_printer_info5
+ * fill a spoolss_PrinterInfo5 struct
+ ********************************************************************/
- /* These are the components of the SD we are returning. */
+static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo5 *r,
+ int snum)
+{
+ r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+ W_ERROR_HAVE_NO_MEMORY(r->printername);
+ r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
+ W_ERROR_HAVE_NO_MEMORY(r->portname);
- if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
- /* don't use talloc_steal() here unless you do a deep steal of all
- the SEC_DESC members */
+ r->attributes = ntprinter->info_2->attributes;
- printer->secdesc = dup_sec_desc( talloc_tos(),
- ntprinter->info_2->secdesc_buf->sd );
- }
+ /* these two are not used by NT+ according to MSDN */
- free_a_printer(&ntprinter, 2);
+ r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
+ r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
- *pp_printer = printer;
- return True;
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_4
- * fill a printer_info_4 struct
+ * construct_printer_info_6
+ * fill a spoolss_PrinterInfo6 struct
********************************************************************/
-static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
+static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo6 *r,
+ int snum)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+ int count;
+ print_status_struct status;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
+ count = print_queue_length(snum, &status);
- init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
- init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
- printer->attributes = ntprinter->info_2->attributes;
+ r->status = nt_printq_status(status.status);
- free_a_printer(&ntprinter, 2);
- return True;
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_5
- * fill a printer_info_5 struct
+ * construct_printer_info7
+ * fill a spoolss_PrinterInfo7 struct
********************************************************************/
-static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
+static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
+ Printer_entry *print_hnd,
+ struct spoolss_PrinterInfo7 *r,
+ int snum)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+ struct GUID guid;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
+ if (is_printer_published(print_hnd, snum, &guid)) {
+ r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
+ r->action = DSPRINT_PUBLISH;
+ } else {
+ r->guid = talloc_strdup(mem_ctx, "");
+ r->action = DSPRINT_UNPUBLISH;
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->guid);
- init_unistr(&printer->printername, ntprinter->info_2->printername);
- init_unistr(&printer->portname, ntprinter->info_2->portname);
- printer->attributes = ntprinter->info_2->attributes;
+ return WERR_OK;
+}
- /* these two are not used by NT+ according to MSDN */
+/********************************************************************
+ * construct_printer_info1
+ * fill a spoolss_PrinterInfo1 struct
+********************************************************************/
- printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
- printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
+static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ uint32_t flags,
+ struct spoolss_PrinterInfo1 *r,
+ int snum)
+{
+ char *chaine = NULL;
+ r->flags = flags;
- free_a_printer(&ntprinter, 2);
+ if (*ntprinter->info_2->comment == '\0') {
+ r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
+ chaine = talloc_asprintf(mem_ctx,
+ "%s,%s,%s", ntprinter->info_2->printername,
+ ntprinter->info_2->drivername, lp_comment(snum));
+ } else {
+ r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
+ chaine = talloc_asprintf(mem_ctx,
+ "%s,%s,%s", ntprinter->info_2->printername,
+ ntprinter->info_2->drivername, ntprinter->info_2->comment);
+ }
+ W_ERROR_HAVE_NO_MEMORY(chaine);
+ W_ERROR_HAVE_NO_MEMORY(r->comment);
- return True;
+ r->description = talloc_strdup(mem_ctx, chaine);
+ W_ERROR_HAVE_NO_MEMORY(r->description);
+ r->name = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+ W_ERROR_HAVE_NO_MEMORY(r->name);
+
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_6
- * fill a printer_info_6 struct
- ********************************************************************/
+ * construct_printer_info2
+ * fill a spoolss_PrinterInfo2 struct
+********************************************************************/
-static bool construct_printer_info_6(Printer_entry *print_hnd,
- PRINTER_INFO_6 *printer,
- int snum)
+static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo2 *r,
+ int snum)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
int count;
- print_status_struct status;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
- lp_const_servicename(snum))))
- return False;
+ print_status_struct status;
count = print_queue_length(snum, &status);
- printer->status = nt_printq_status(status.status);
+ r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+ W_ERROR_HAVE_NO_MEMORY(r->servername);
+ r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+ W_ERROR_HAVE_NO_MEMORY(r->printername);
+ r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
+ W_ERROR_HAVE_NO_MEMORY(r->sharename);
+ r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
+ W_ERROR_HAVE_NO_MEMORY(r->portname);
+ r->drivername = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
+ W_ERROR_HAVE_NO_MEMORY(r->drivername);
- free_a_printer(&ntprinter, 2);
+ if (*ntprinter->info_2->comment == '\0') {
+ r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
+ } else {
+ r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->comment);
- return True;
-}
+ r->location = talloc_strdup(mem_ctx, ntprinter->info_2->location);
+ W_ERROR_HAVE_NO_MEMORY(r->location);
+ r->sepfile = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
+ W_ERROR_HAVE_NO_MEMORY(r->sepfile);
+ r->printprocessor = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
+ W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
+ r->datatype = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
+ W_ERROR_HAVE_NO_MEMORY(r->datatype);
+ r->parameters = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
+ W_ERROR_HAVE_NO_MEMORY(r->parameters);
-/********************************************************************
- * construct_printer_info_7
- * fill a printer_info_7 struct
- ********************************************************************/
+ r->attributes = ntprinter->info_2->attributes;
-static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
-{
- char *guid_str = NULL;
- struct GUID guid;
+ r->priority = ntprinter->info_2->priority;
+ r->defaultpriority = ntprinter->info_2->default_priority;
+ r->starttime = ntprinter->info_2->starttime;
+ r->untiltime = ntprinter->info_2->untiltime;
+ r->status = nt_printq_status(status.status);
+ r->cjobs = count;
+ r->averageppm = ntprinter->info_2->averageppm;
- if (is_printer_published(print_hnd, snum, &guid)) {
- if (asprintf(&guid_str, "{%s}",
- GUID_string(talloc_tos(), &guid)) == -1) {
- return false;
- }
- strupper_m(guid_str);
- init_unistr(&printer->guid, guid_str);
- SAFE_FREE(guid_str);
- printer->action = DSPRINT_PUBLISH;
- } else {
- init_unistr(&printer->guid, "");
- printer->action = DSPRINT_UNPUBLISH;
+ r->devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+ if (!r->devmode) {
+ DEBUG(8,("Returning NULL Devicemode!\n"));
}
- return True;
+ r->secdesc = NULL;
+
+ if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
+ /* don't use talloc_steal() here unless you do a deep steal of all
+ the SEC_DESC members */
+
+ r->secdesc = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
+ }
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+static bool snum_is_shared_printer(int snum)
+{
+ return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
}
/********************************************************************
Spoolss_enumprinters.
********************************************************************/
-static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ union spoolss_PrinterInfo **info_p,
+ uint32_t *count)
{
int snum;
- int i;
- int n_services=lp_numservices();
- PRINTER_INFO_1 *printers=NULL;
- PRINTER_INFO_1 current_prt;
+ int n_services = lp_numservices();
+ union spoolss_PrinterInfo *info = NULL;
WERROR result = WERR_OK;
DEBUG(4,("enum_all_printers_info_1\n"));
+ *count = 0;
+
for (snum=0; snum<n_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
- if (construct_printer_info_1(NULL, flags, &current_prt, snum)) {
- if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
- DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
- *returned=0;
- return WERR_NOMEM;
- }
- DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
- memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_1));
- (*returned)++;
- }
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+ struct spoolss_PrinterInfo1 info1;
+
+ if (!snum_is_shared_printer(snum)) {
+ continue;
}
- }
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_printer_info_1(&printers[i]);
+ DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
+ result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ continue;
+ }
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
+ result = construct_printer_info1(info, ntprinter, flags, &info1, snum);
+ free_a_printer(&ntprinter,2);
+ if (!W_ERROR_IS_OK(result)) {
+ continue;
+ }
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- smb_io_printer_info_1("", buffer, &printers[i], 0);
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ union spoolss_PrinterInfo,
+ *count + 1);
+ if (!info) {
+ DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
+ result = WERR_NOMEM;
+ goto out;
+ }
-out:
- /* clear memory */
+ DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count));
- SAFE_FREE(printers);
+ info[*count].info1 = info1;
+ (*count)++;
+ }
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+ out:
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
+ }
- return result;
+ *info_p = info;
+
+ return WERR_OK;
}
/********************************************************************
enum_all_printers_info_1_local.
*********************************************************************/
-static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
{
DEBUG(4,("enum_all_printers_info_1_local\n"));
- return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+ return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
}
/********************************************************************
enum_all_printers_info_1_name.
*********************************************************************/
-static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
+ const char *name,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
{
- char *s = name;
+ const char *s = name;
DEBUG(4,("enum_all_printers_info_1_name\n"));
- if ((name[0] == '\\') && (name[1] == '\\'))
+ if ((name[0] == '\\') && (name[1] == '\\')) {
s = name + 2;
-
- if (is_myname_or_ipaddr(s)) {
- return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
}
- else
+
+ if (!is_myname_or_ipaddr(s)) {
return WERR_INVALID_NAME;
+ }
+
+ return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
}
#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
@@ -4523,9 +4612,12 @@ out:
enum_all_printers_info_1_network.
*********************************************************************/
-static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
+ const char *name,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
{
- char *s = name;
+ const char *s = name;
DEBUG(4,("enum_all_printers_info_1_network\n"));
@@ -4537,13 +4629,15 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
listed. Windows responds to this call with a
WERR_CAN_NOT_COMPLETE so we should do the same. */
- if (name[0] == '\\' && name[1] == '\\')
+ if (name[0] == '\\' && name[1] == '\\') {
s = name + 2;
+ }
- if (is_myname_or_ipaddr(s))
+ if (is_myname_or_ipaddr(s)) {
return WERR_CAN_NOT_COMPLETE;
+ }
- return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
+ return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
}
/********************************************************************
@@ -4552,92 +4646,96 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
+ union spoolss_PrinterInfo **info_p,
+ uint32_t *count)
{
int snum;
- int i;
- int n_services=lp_numservices();
- PRINTER_INFO_2 *printers=NULL;
- PRINTER_INFO_2 current_prt;
+ int n_services = lp_numservices();
+ union spoolss_PrinterInfo *info = NULL;
WERROR result = WERR_OK;
- *returned = 0;
+ *count = 0;
for (snum=0; snum<n_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
- if (construct_printer_info_2(NULL, &current_prt, snum)) {
- if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
- DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
- *returned = 0;
- return WERR_NOMEM;
- }
- DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
+ struct spoolss_PrinterInfo2 info2;
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_2));
-
- (*returned)++;
- }
+ if (!snum_is_shared_printer(snum)) {
+ continue;
}
- }
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_printer_info_2(&printers[i]);
+ DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
+ result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ continue;
+ }
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
+ result = construct_printer_info2(info, ntprinter, &info2, snum);
+ free_a_printer(&ntprinter, 2);
+ if (!W_ERROR_IS_OK(result)) {
+ continue;
+ }
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- smb_io_printer_info_2("", buffer, &(printers[i]), 0);
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ union spoolss_PrinterInfo,
+ *count + 1);
+ if (!info) {
+ DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
+ result = WERR_NOMEM;
+ goto out;
+ }
-out:
- /* clear memory */
+ DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *count + 1));
- for (i=0; i<*returned; i++)
- free_devmode(printers[i].devmode);
+ info[*count].info2 = info2;
- SAFE_FREE(printers);
+ (*count)++;
+ }
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+ out:
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
+ }
- return result;
+ *info_p = info;
+
+ return WERR_OK;
}
/********************************************************************
* handle enumeration of printers at level 1
********************************************************************/
-static WERROR enumprinters_level1( uint32 flags, fstring name,
- RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ const char *name,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
{
/* Not all the flags are equals */
- if (flags & PRINTER_ENUM_LOCAL)
- return enum_all_printers_info_1_local(buffer, offered, needed, returned);
+ if (flags & PRINTER_ENUM_LOCAL) {
+ return enum_all_printers_info_1_local(mem_ctx, info, count);
+ }
- if (flags & PRINTER_ENUM_NAME)
- return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
+ if (flags & PRINTER_ENUM_NAME) {
+ return enum_all_printers_info_1_name(mem_ctx, name, info, count);
+ }
#if 0 /* JERRY - disabled for now */
- if (flags & PRINTER_ENUM_REMOTE)
- return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
+ if (flags & PRINTER_ENUM_REMOTE) {
+ return enum_all_printers_info_1_remote(mem_ctx, name, info, count);
+ }
#endif
- if (flags & PRINTER_ENUM_NETWORK)
- return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
+ if (flags & PRINTER_ENUM_NETWORK) {
+ return enum_all_printers_info_1_network(mem_ctx, name, info, count);
+ }
return WERR_OK; /* NT4sp5 does that */
}
@@ -4646,23 +4744,27 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
* handle enumeration of printers at level 2
********************************************************************/
-static WERROR enumprinters_level2( uint32 flags, const char *servername,
- RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ const char *servername,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
{
if (flags & PRINTER_ENUM_LOCAL) {
- return enum_all_printers_info_2(buffer, offered, needed, returned);
+ return enum_all_printers_info_2(mem_ctx, info, count);
}
if (flags & PRINTER_ENUM_NAME) {
- if (is_myname_or_ipaddr(canon_servername(servername)))
- return enum_all_printers_info_2(buffer, offered, needed, returned);
- else
+ if (!is_myname_or_ipaddr(canon_servername(servername))) {
return WERR_INVALID_NAME;
+ }
+
+ return enum_all_printers_info_2(mem_ctx, info, count);
}
- if (flags & PRINTER_ENUM_REMOTE)
+ if (flags & PRINTER_ENUM_REMOTE) {
return WERR_UNKNOWN_LEVEL;
+ }
return WERR_OK;
}
@@ -4671,49 +4773,37 @@ static WERROR enumprinters_level2( uint32 flags, const char *servername,
* handle enumeration of printers at level 5
********************************************************************/
-static WERROR enumprinters_level5( uint32 flags, const char *servername,
- RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ const char *servername,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
{
-/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
+/* return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/
return WERR_OK;
}
-/********************************************************************
- * api_spoolss_enumprinters
- *
- * called from api_spoolss_enumprinters (see this to understand)
- ********************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinters
+****************************************************************/
-WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
+WERROR _spoolss_EnumPrinters(pipes_struct *p,
+ struct spoolss_EnumPrinters *r)
{
- uint32 flags = q_u->flags;
- UNISTR2 *servername = &q_u->servername;
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
- uint32 *returned = &r_u->returned;
-
- fstring name;
+ const char *name;
+ WERROR result;
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
- return WERR_INVALID_PARAM;
- }
-
- if (offered > MAX_RPC_DATA_SIZE) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
-
- DEBUG(4,("_spoolss_enumprinters\n"));
+ DEBUG(4,("_spoolss_EnumPrinters\n"));
- *needed=0;
- *returned=0;
+ *r->out.needed = 0;
+ *r->out.count = 0;
+ *r->out.info = NULL;
/*
* Level 1:
@@ -4728,392 +4818,376 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
* Level 5: same as Level 2
*/
- unistr2_to_ascii(name, servername, sizeof(name));
- strupper_m(name);
+ name = talloc_strdup_upper(p->mem_ctx, r->in.server);
+ W_ERROR_HAVE_NO_MEMORY(name);
- switch (level) {
+ switch (r->in.level) {
case 1:
- return enumprinters_level1(flags, name, buffer, offered, needed, returned);
+ result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
+ r->out.info, r->out.count);
+ break;
case 2:
- return enumprinters_level2(flags, name, buffer, offered, needed, returned);
+ result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
+ r->out.info, r->out.count);
+ break;
case 5:
- return enumprinters_level5(flags, name, buffer, offered, needed, returned);
+ result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
+ r->out.info, r->out.count);
+ break;
case 3:
case 4:
+ result = WERR_OK; /* ??? */
break;
- }
- return WERR_UNKNOWN_LEVEL;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_0 *printer=NULL;
- WERROR result = WERR_OK;
-
- if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
- return WERR_NOMEM;
-
- construct_printer_info_0(print_hnd, printer, snum);
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_0(printer);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ default:
+ return WERR_UNKNOWN_LEVEL;
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
}
- /* fill the buffer with the structures */
- smb_io_printer_info_0("", buffer, printer, 0);
-
-out:
- /* clear memory */
-
- SAFE_FREE(printer);
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumPrinters, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
- return result;
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinter
+****************************************************************/
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+WERROR _spoolss_GetPrinter(pipes_struct *p,
+ struct spoolss_GetPrinter *r)
{
- PRINTER_INFO_1 *printer=NULL;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
WERROR result = WERR_OK;
- if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
- return WERR_NOMEM;
-
- construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_1(printer);
+ int snum;
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
+ /* that's an [in out] buffer */
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ if (!r->in.buffer && (r->in.offered != 0)) {
+ return WERR_INVALID_PARAM;
}
- /* fill the buffer with the structures */
- smb_io_printer_info_1("", buffer, printer, 0);
-
-out:
- /* clear memory */
- SAFE_FREE(printer);
-
- return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_2 *printer=NULL;
- WERROR result = WERR_OK;
-
- if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
- return WERR_NOMEM;
-
- construct_printer_info_2(print_hnd, printer, snum);
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_2(printer);
+ *r->out.needed = 0;
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+ return WERR_BADFID;
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ result = get_a_printer(Printer, &ntprinter, 2,
+ lp_const_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
}
- /* fill the buffer with the structures */
- if (!smb_io_printer_info_2("", buffer, printer, 0))
- result = WERR_NOMEM;
-
-out:
- /* clear memory */
- free_printer_info_2(printer);
-
- return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_3 *printer=NULL;
- WERROR result = WERR_OK;
-
- if (!construct_printer_info_3(print_hnd, &printer, snum))
- return WERR_NOMEM;
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_3(printer);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ switch (r->in.level) {
+ case 0:
+ result = construct_printer_info0(p->mem_ctx, ntprinter,
+ &r->out.info->info0, snum);
+ break;
+ case 1:
+ result = construct_printer_info1(p->mem_ctx, ntprinter,
+ PRINTER_ENUM_ICON8,
+ &r->out.info->info1, snum);
+ break;
+ case 2:
+ result = construct_printer_info2(p->mem_ctx, ntprinter,
+ &r->out.info->info2, snum);
+ break;
+ case 3:
+ result = construct_printer_info3(p->mem_ctx, ntprinter,
+ &r->out.info->info3, snum);
+ break;
+ case 4:
+ result = construct_printer_info4(p->mem_ctx, ntprinter,
+ &r->out.info->info4, snum);
+ break;
+ case 5:
+ result = construct_printer_info5(p->mem_ctx, ntprinter,
+ &r->out.info->info5, snum);
+ break;
+ case 6:
+ result = construct_printer_info6(p->mem_ctx, ntprinter,
+ &r->out.info->info6, snum);
+ break;
+ case 7:
+ result = construct_printer_info7(p->mem_ctx, Printer,
+ &r->out.info->info7, snum);
+ break;
+ default:
+ result = WERR_UNKNOWN_LEVEL;
+ break;
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
+ free_a_printer(&ntprinter, 2);
- /* fill the buffer with the structures */
- smb_io_printer_info_3("", buffer, printer, 0);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
+ }
-out:
- /* clear memory */
- free_printer_info_3(printer);
+ *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL,
+ r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
- return result;
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ ********************************************************************/
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
+ fstring *fstring_array,
+ const char *cservername)
{
- PRINTER_INFO_4 *printer=NULL;
- WERROR result = WERR_OK;
+ int i, num_strings = 0;
+ const char **array = NULL;
- if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
- return WERR_NOMEM;
+ for (i=0; fstring_array && fstring_array[i][0] != '\0'; i++) {
- if (!construct_printer_info_4(print_hnd, printer, snum)) {
- SAFE_FREE(printer);
- return WERR_NOMEM;
- }
+ const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, fstring_array[i]);
+ if (!str) {
+ TALLOC_FREE(array);
+ return NULL;
+ }
- /* check the required size. */
- *needed += spoolss_size_printer_info_4(printer);
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
+ TALLOC_FREE(array);
+ return NULL;
+ }
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ if (i > 0) {
+ ADD_TO_ARRAY(mem_ctx, const char *, NULL,
+ &array, &num_strings);
}
- /* fill the buffer with the structures */
- smb_io_printer_info_4("", buffer, printer, 0);
-
-out:
- /* clear memory */
- free_printer_info_4(printer);
-
- return result;
+ return array;
}
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ * fill a spoolss_DriverInfo1 struct
+ ********************************************************************/
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo1 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername,
+ const char *architecture)
{
- PRINTER_INFO_5 *printer=NULL;
- WERROR result = WERR_OK;
-
- if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
- return WERR_NOMEM;
-
- if (!construct_printer_info_5(print_hnd, printer, snum)) {
- free_printer_info_5(printer);
- return WERR_NOMEM;
- }
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_5(printer);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
- /* fill the buffer with the structures */
- smb_io_printer_info_5("", buffer, printer, 0);
+ return WERR_OK;
+}
-out:
- /* clear memory */
- free_printer_info_5(printer);
+/********************************************************************
+ * fill a spoolss_DriverInfo2 struct
+ ********************************************************************/
- return result;
-}
+static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo2 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername)
-static WERROR getprinter_level_6(Printer_entry *print_hnd,
- int snum,
- RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed)
{
- PRINTER_INFO_6 *printer;
- WERROR result = WERR_OK;
-
- if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
- return WERR_NOMEM;
- }
+ const char *cservername = canon_servername(servername);
- if (!construct_printer_info_6(print_hnd, printer, snum)) {
- free_printer_info_6(printer);
- return WERR_NOMEM;
- }
+ r->version = driver->info_3->cversion;
- /* check the required size. */
- *needed += spoolss_size_printer_info_6(printer);
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+ r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment);
+ W_ERROR_HAVE_NO_MEMORY(r->architecture);
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ if (strlen(driver->info_3->driverpath)) {
+ r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->driverpath);
+ } else {
+ r->driver_path = talloc_strdup(mem_ctx, "");
}
+ W_ERROR_HAVE_NO_MEMORY(r->driver_path);
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ if (strlen(driver->info_3->datafile)) {
+ r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->datafile);
+ } else {
+ r->data_file = talloc_strdup(mem_ctx, "");
}
+ W_ERROR_HAVE_NO_MEMORY(r->data_file);
- /* fill the buffer with the structures */
- smb_io_printer_info_6("", buffer, printer, 0);
-
-out:
- /* clear memory */
- free_printer_info_6(printer);
+ if (strlen(driver->info_3->configfile)) {
+ r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->configfile);
+ } else {
+ r->config_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
- return result;
+ return WERR_OK;
}
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_7 *printer=NULL;
- WERROR result = WERR_OK;
+/********************************************************************
+ * fill a spoolss_DriverInfo3 struct
+ ********************************************************************/
- if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
- return WERR_NOMEM;
+static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo3 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername)
+{
+ const char *cservername = canon_servername(servername);
- if (!construct_printer_info_7(print_hnd, printer, snum)) {
- result = WERR_NOMEM;
- goto out;
- }
+ r->version = driver->info_3->cversion;
- /* check the required size. */
- *needed += spoolss_size_printer_info_7(printer);
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+ r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment);
+ W_ERROR_HAVE_NO_MEMORY(r->architecture);
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ if (strlen(driver->info_3->driverpath)) {
+ r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->driverpath);
+ } else {
+ r->driver_path = talloc_strdup(mem_ctx, "");
}
+ W_ERROR_HAVE_NO_MEMORY(r->driver_path);
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ if (strlen(driver->info_3->datafile)) {
+ r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->datafile);
+ } else {
+ r->data_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->data_file);
+ if (strlen(driver->info_3->configfile)) {
+ r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->configfile);
+ } else {
+ r->config_file = talloc_strdup(mem_ctx, "");
}
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
- /* fill the buffer with the structures */
- smb_io_printer_info_7("", buffer, printer, 0);
+ if (strlen(driver->info_3->helpfile)) {
+ r->help_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->helpfile);
+ } else {
+ r->help_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
-out:
- /* clear memory */
- free_printer_info_7(printer);
+ r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname);
+ W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+ r->default_datatype = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype);
+ W_ERROR_HAVE_NO_MEMORY(r->default_datatype);
- return result;
+ r->dependent_files = string_array_from_driver_info(mem_ctx,
+ driver->info_3->dependentfiles,
+ cservername);
+ return WERR_OK;
}
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ * fill a spoolss_DriverInfo6 struct
+ ********************************************************************/
-WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
+static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo6 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ const char *cservername = canon_servername(servername);
- int snum;
+ r->version = driver->info_3->cversion;
- /* that's an [in out] buffer */
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+ r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment);
+ W_ERROR_HAVE_NO_MEMORY(r->architecture);
- if (!q_u->buffer && (offered!=0)) {
- return WERR_INVALID_PARAM;
+ if (strlen(driver->info_3->driverpath)) {
+ r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->driverpath);
+ } else {
+ r->driver_path = talloc_strdup(mem_ctx, "");
}
+ W_ERROR_HAVE_NO_MEMORY(r->driver_path);
- if (offered > MAX_RPC_DATA_SIZE) {
- return WERR_INVALID_PARAM;
+ if (strlen(driver->info_3->datafile)) {
+ r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->datafile);
+ } else {
+ r->data_file = talloc_strdup(mem_ctx, "");
}
+ W_ERROR_HAVE_NO_MEMORY(r->data_file);
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
-
- *needed=0;
-
- if (!get_printer_snum(p, handle, &snum, NULL))
- return WERR_BADFID;
+ if (strlen(driver->info_3->configfile)) {
+ r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->configfile);
+ } else {
+ r->config_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
- switch (level) {
- case 0:
- return getprinter_level_0(Printer, snum, buffer, offered, needed);
- case 1:
- return getprinter_level_1(Printer, snum, buffer, offered, needed);
- case 2:
- return getprinter_level_2(Printer, snum, buffer, offered, needed);
- case 3:
- return getprinter_level_3(Printer, snum, buffer, offered, needed);
- case 4:
- return getprinter_level_4(Printer, snum, buffer, offered, needed);
- case 5:
- return getprinter_level_5(Printer, snum, buffer, offered, needed);
- case 6:
- return getprinter_level_6(Printer, snum, buffer, offered, needed);
- case 7:
- return getprinter_level_7(Printer, snum, buffer, offered, needed);
+ if (strlen(driver->info_3->helpfile)) {
+ r->help_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->helpfile);
+ } else {
+ r->help_file = talloc_strdup(mem_ctx, "");
}
- return WERR_UNKNOWN_LEVEL;
-}
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
-/********************************************************************
- * fill a DRIVER_INFO_1 struct
- ********************************************************************/
+ r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname);
+ W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+ r->default_datatype = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype);
+ W_ERROR_HAVE_NO_MEMORY(r->default_datatype);
+
+ r->dependent_files = string_array_from_driver_info(mem_ctx,
+ driver->info_3->dependentfiles,
+ cservername);
+ r->previous_names = string_array_from_driver_info(mem_ctx,
+ NULL,
+ cservername);
+
+ r->driver_date = 0;
+ r->driver_version = 0;
+
+ r->manufacturer_name = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->manufacturer_name);
+ r->manufacturer_url = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->manufacturer_url);
+ r->hardware_id = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->hardware_id);
+ r->provider = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->provider);
-static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
-{
- init_unistr( &info->name, driver.info_3->name);
+ return WERR_OK;
}
/********************************************************************
* construct_printer_driver_info_1
********************************************************************/
-static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_1(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo1 *r,
+ int snum,
+ const char *servername,
+ const char *architecture,
+ uint32_t version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
+ WERROR result;
ZERO_STRUCT(driver);
@@ -5125,58 +5199,11 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, con
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- fill_printer_driver_info_1(info, driver, servername, architecture);
+ result = fill_printer_driver_info1(mem_ctx, r, &driver, servername, architecture);
free_a_printer(&printer,2);
- return WERR_OK;
-}
-
-/********************************************************************
- * construct_printer_driver_info_2
- * fill a printer_info_2 struct
- ********************************************************************/
-
-static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
-{
- TALLOC_CTX *ctx = talloc_tos();
- char *temp = NULL;
- const char *cservername = canon_servername(servername);
-
- info->version=driver.info_3->cversion;
-
- init_unistr( &info->name, driver.info_3->name );
- init_unistr( &info->architecture, driver.info_3->environment );
-
- if (strlen(driver.info_3->driverpath)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->driverpath);
- init_unistr( &info->driverpath, temp );
- } else {
- init_unistr( &info->driverpath, "" );
- }
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->datafile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->datafile);
- init_unistr( &info->datafile, temp );
- } else
- init_unistr( &info->datafile, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->configfile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->configfile);
- init_unistr( &info->configfile, temp );
- } else
- init_unistr( &info->configfile, "" );
+ return result;
}
/********************************************************************
@@ -5184,10 +5211,16 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_IN
* fill a printer_info_2 struct
********************************************************************/
-static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_2(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo2 *r,
+ int snum,
+ const char *servername,
+ const char *architecture,
+ uint32_t version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
+ WERROR result;
ZERO_STRUCT(printer);
ZERO_STRUCT(driver);
@@ -5200,11 +5233,11 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, con
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- fill_printer_driver_info_2(info, driver, servername);
+ result = fill_printer_driver_info2(mem_ctx, r, &driver, servername);
free_a_printer(&printer,2);
- return WERR_OK;
+ return result;
}
/********************************************************************
@@ -5285,72 +5318,12 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
* fill a printer_info_3 struct
********************************************************************/
-static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
-{
- char *temp = NULL;
- TALLOC_CTX *ctx = talloc_tos();
- const char *cservername = canon_servername(servername);
-
- ZERO_STRUCTP(info);
-
- info->version=driver.info_3->cversion;
-
- init_unistr( &info->name, driver.info_3->name );
- init_unistr( &info->architecture, driver.info_3->environment );
-
- if (strlen(driver.info_3->driverpath)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->driverpath);
- init_unistr( &info->driverpath, temp );
- } else
- init_unistr( &info->driverpath, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->datafile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->datafile);
- init_unistr( &info->datafile, temp );
- } else
- init_unistr( &info->datafile, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->configfile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->configfile);
- init_unistr( &info->configfile, temp );
- } else
- init_unistr( &info->configfile, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->helpfile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->helpfile);
- init_unistr( &info->helpfile, temp );
- } else
- init_unistr( &info->helpfile, "" );
-
- TALLOC_FREE(temp);
- init_unistr( &info->monitorname, driver.info_3->monitorname );
- init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
-
- info->dependentfiles=NULL;
- init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
-}
-
-/********************************************************************
- * construct_printer_info_3
- * fill a printer_info_3 struct
- ********************************************************************/
-
-static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_3(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo3 *r,
+ int snum,
+ const char *servername,
+ const char *architecture,
+ uint32_t version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -5397,92 +5370,11 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, con
#endif
- fill_printer_driver_info_3(info, driver, servername);
+ status = fill_printer_driver_info3(mem_ctx, r, &driver, servername);
free_a_printer(&printer,2);
- return WERR_OK;
-}
-
-/********************************************************************
- * construct_printer_info_6
- * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
- ********************************************************************/
-
-static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
-{
- char *temp = NULL;
- fstring nullstr;
- TALLOC_CTX *ctx = talloc_tos();
- const char *cservername = canon_servername(servername);
-
- ZERO_STRUCTP(info);
- memset(&nullstr, '\0', sizeof(fstring));
-
- info->version=driver.info_3->cversion;
-
- init_unistr( &info->name, driver.info_3->name );
- init_unistr( &info->architecture, driver.info_3->environment );
-
- if (strlen(driver.info_3->driverpath)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->driverpath);
- init_unistr( &info->driverpath, temp );
- } else
- init_unistr( &info->driverpath, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->datafile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->datafile);
- init_unistr( &info->datafile, temp );
- } else
- init_unistr( &info->datafile, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->configfile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->configfile);
- init_unistr( &info->configfile, temp );
- } else
- init_unistr( &info->configfile, "" );
-
- TALLOC_FREE(temp);
- if (strlen(driver.info_3->helpfile)) {
- temp = talloc_asprintf(ctx,
- "\\\\%s%s",
- cservername,
- driver.info_3->helpfile);
- init_unistr( &info->helpfile, temp );
- } else
- init_unistr( &info->helpfile, "" );
-
- TALLOC_FREE(temp);
- init_unistr( &info->monitorname, driver.info_3->monitorname );
- init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
-
- info->dependentfiles = NULL;
- init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
-
- info->previousdrivernames=NULL;
- init_unistr_array(&info->previousdrivernames, &nullstr, servername);
-
- info->driver_date=0;
-
- info->padding=0;
- info->driver_version_low=0;
- info->driver_version_high=0;
-
- init_unistr( &info->mfgname, "");
- init_unistr( &info->oem_url, "");
- init_unistr( &info->hardware_id, "");
- init_unistr( &info->provider, "");
+ return status;
}
/********************************************************************
@@ -5490,8 +5382,12 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
* fill a printer_info_6 struct
********************************************************************/
-static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
- const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_6(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo6 *r,
+ int snum,
+ const char *servername,
+ const char *architecture,
+ uint32_t version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -5531,246 +5427,104 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
}
}
- fill_printer_driver_info_6(info, driver, servername);
+ status = fill_printer_driver_info6(mem_ctx, r, &driver, servername);
free_a_printer(&printer,2);
free_a_printer_driver(driver, 3);
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
-{
- SAFE_FREE(info->dependentfiles);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
-{
- SAFE_FREE(info->dependentfiles);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_1 *info=NULL;
- WERROR result;
-
- if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
- return WERR_NOMEM;
-
- result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(result))
- goto out;
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_1(info);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
-
- /* fill the buffer with the structures */
- smb_io_printer_driver_info_1("", buffer, info, 0);
-
-out:
- /* clear memory */
- SAFE_FREE(info);
-
- return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_2 *info=NULL;
- WERROR result;
-
- if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
- return WERR_NOMEM;
-
- result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(result))
- goto out;
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_2(info);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
-
- /* fill the buffer with the structures */
- smb_io_printer_driver_info_2("", buffer, info, 0);
-
-out:
- /* clear memory */
- SAFE_FREE(info);
-
- return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_3 info;
- WERROR result;
-
- ZERO_STRUCT(info);
-
- result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(result))
- goto out;
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_3(&info);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
-
- /* fill the buffer with the structures */
- smb_io_printer_driver_info_3("", buffer, &info, 0);
-
-out:
- free_printer_driver_info_3(&info);
-
- return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_6 info;
- WERROR result;
-
- ZERO_STRUCT(info);
-
- result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(result))
- goto out;
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_6(&info);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
-
- /* fill the buffer with the structures */
- smb_io_printer_driver_info_6("", buffer, &info, 0);
-
-out:
- free_printer_driver_info_6(&info);
-
- return result;
+ return status;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinterDriver2
+****************************************************************/
-WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
+WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
+ struct spoolss_GetPrinterDriver2 *r)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *uni_arch = &q_u->architecture;
- uint32 level = q_u->level;
- uint32 clientmajorversion = q_u->clientmajorversion;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
- uint32 *servermajorversion = &r_u->servermajorversion;
- uint32 *serverminorversion = &r_u->serverminorversion;
Printer_entry *printer;
+ WERROR result;
- fstring servername;
- fstring architecture;
+ const char *servername;
int snum;
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
- return WERR_INVALID_PARAM;
- }
-
- if (offered > MAX_RPC_DATA_SIZE) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
-
- DEBUG(4,("_spoolss_getprinterdriver2\n"));
+ DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
- if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
- DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
+ if (!(printer = find_printer_index_by_hnd( p, r->in.handle))) {
+ DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
return WERR_INVALID_PRINTER_NAME;
}
- *needed = 0;
- *servermajorversion = 0;
- *serverminorversion = 0;
+ *r->out.needed = 0;
+ *r->out.server_major_version = 0;
+ *r->out.server_minor_version = 0;
- fstrcpy(servername, get_server_name( printer ));
- unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
+ servername = get_server_name(printer);
- if (!get_printer_snum(p, handle, &snum, NULL))
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
- switch (level) {
+ switch (r->in.level) {
case 1:
- return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+ result = construct_printer_driver_info_1(p->mem_ctx,
+ &r->out.info->info1,
+ snum,
+ servername,
+ r->in.architecture,
+ r->in.client_major_version);
+ break;
case 2:
- return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+ result = construct_printer_driver_info_2(p->mem_ctx,
+ &r->out.info->info2,
+ snum,
+ servername,
+ r->in.architecture,
+ r->in.client_major_version);
+ break;
case 3:
- return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+ result = construct_printer_driver_info_3(p->mem_ctx,
+ &r->out.info->info3,
+ snum,
+ servername,
+ r->in.architecture,
+ r->in.client_major_version);
+ break;
case 6:
- return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+ result = construct_printer_driver_info_6(p->mem_ctx,
+ &r->out.info->info6,
+ snum,
+ servername,
+ r->in.architecture,
+ r->in.client_major_version);
+ break;
+ default:
#if 0 /* JERRY */
case 101:
/* apparently this call is the equivalent of
EnumPrinterDataEx() for the DsDriver key */
break;
#endif
+ result = WERR_UNKNOWN_LEVEL;
+ break;
}
- return WERR_UNKNOWN_LEVEL;
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL,
+ r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -5868,7 +5622,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
}
Printer->jobid = print_job_start(p->server_info, snum,
- CONST_DISCARD(char *,info_1->document_name),
+ info_1->document_name,
Printer->nt_devmode);
/* An error occured in print_job_start() so return an appropriate
@@ -6626,251 +6380,276 @@ WERROR _spoolss_AddJob(pipes_struct *p,
}
/****************************************************************************
+fill_job_info1
****************************************************************************/
-static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
- int position, int snum,
- const NT_PRINTER_INFO_LEVEL *ntprinter)
+static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
+ struct spoolss_JobInfo1 *r,
+ const print_queue_struct *queue,
+ int position, int snum,
+ const NT_PRINTER_INFO_LEVEL *ntprinter)
{
struct tm *t;
- t=gmtime(&queue->time);
+ t = gmtime(&queue->time);
+
+ r->job_id = queue->job;
+
+ r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
+ W_ERROR_HAVE_NO_MEMORY(r->printer_name);
+ r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+ W_ERROR_HAVE_NO_MEMORY(r->server_name);
+ r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
+ W_ERROR_HAVE_NO_MEMORY(r->user_name);
+ r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
+ W_ERROR_HAVE_NO_MEMORY(r->document_name);
+ r->data_type = talloc_strdup(mem_ctx, "RAW");
+ W_ERROR_HAVE_NO_MEMORY(r->data_type);
+ r->text_status = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->text_status);
- job_info->jobid=queue->job;
- init_unistr(&job_info->printername, lp_servicename(snum));
- init_unistr(&job_info->machinename, ntprinter->info_2->servername);
- init_unistr(&job_info->username, queue->fs_user);
- init_unistr(&job_info->document, queue->fs_file);
- init_unistr(&job_info->datatype, "RAW");
- init_unistr(&job_info->text_status, "");
- job_info->status=nt_printj_status(queue->status);
- job_info->priority=queue->priority;
- job_info->position=position;
- job_info->totalpages=queue->page_count;
- job_info->pagesprinted=0;
+ r->status = nt_printj_status(queue->status);
+ r->priority = queue->priority;
+ r->position = position;
+ r->total_pages = queue->page_count;
+ r->pages_printed = 0; /* ??? */
- make_systemtime(&job_info->submitted, t);
+ init_systemtime(&r->submitted, t);
+
+ return WERR_OK;
}
/****************************************************************************
+fill_job_info2
****************************************************************************/
-static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
- int position, int snum,
- const NT_PRINTER_INFO_LEVEL *ntprinter,
- DEVICEMODE *devmode)
+static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
+ struct spoolss_JobInfo2 *r,
+ const print_queue_struct *queue,
+ int position, int snum,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_DeviceMode *devmode)
{
struct tm *t;
- t=gmtime(&queue->time);
-
- job_info->jobid=queue->job;
-
- init_unistr(&job_info->printername, ntprinter->info_2->printername);
-
- init_unistr(&job_info->machinename, ntprinter->info_2->servername);
- init_unistr(&job_info->username, queue->fs_user);
- init_unistr(&job_info->document, queue->fs_file);
- init_unistr(&job_info->notifyname, queue->fs_user);
- init_unistr(&job_info->datatype, "RAW");
- init_unistr(&job_info->printprocessor, "winprint");
- init_unistr(&job_info->parameters, "");
- init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
- init_unistr(&job_info->text_status, "");
+ t = gmtime(&queue->time);
+
+ r->job_id = queue->job;
+
+ r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
+ W_ERROR_HAVE_NO_MEMORY(r->printer_name);
+ r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+ W_ERROR_HAVE_NO_MEMORY(r->server_name);
+ r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
+ W_ERROR_HAVE_NO_MEMORY(r->user_name);
+ r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
+ W_ERROR_HAVE_NO_MEMORY(r->document_name);
+ r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
+ W_ERROR_HAVE_NO_MEMORY(r->notify_name);
+ r->data_type = talloc_strdup(mem_ctx, "RAW");
+ W_ERROR_HAVE_NO_MEMORY(r->data_type);
+ r->print_processor = talloc_strdup(mem_ctx, "winprint");
+ W_ERROR_HAVE_NO_MEMORY(r->print_processor);
+ r->parameters = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->parameters);
+ r->driver_name = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+
+ r->devmode = devmode;
+
+ r->text_status = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->text_status);
+
+ r->secdesc = NULL;
+
+ r->status = nt_printj_status(queue->status);
+ r->priority = queue->priority;
+ r->position = position;
+ r->start_time = 0;
+ r->until_time = 0;
+ r->total_pages = queue->page_count;
+ r->size = queue->size;
+ init_systemtime(&r->submitted, t);
+ r->time = 0;
+ r->pages_printed = 0; /* ??? */
-/* and here the security descriptor */
-
- job_info->status=nt_printj_status(queue->status);
- job_info->priority=queue->priority;
- job_info->position=position;
- job_info->starttime=0;
- job_info->untiltime=0;
- job_info->totalpages=queue->page_count;
- job_info->size=queue->size;
- make_systemtime(&(job_info->submitted), t);
- job_info->timeelapsed=0;
- job_info->pagesprinted=0;
-
- job_info->devmode = devmode;
-
- return (True);
+ return WERR_OK;
}
/****************************************************************************
Enumjobs at level 1.
****************************************************************************/
-static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
+static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
+ const print_queue_struct *queue,
+ uint32_t num_queues, int snum,
const NT_PRINTER_INFO_LEVEL *ntprinter,
- RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+ union spoolss_JobInfo **info_p,
+ uint32_t *count)
{
- JOB_INFO_1 *info;
+ union spoolss_JobInfo *info;
int i;
WERROR result = WERR_OK;
- info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
- if (info==NULL) {
- *returned=0;
- return WERR_NOMEM;
- }
-
- for (i=0; i<*returned; i++)
- fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
+ info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+ W_ERROR_HAVE_NO_MEMORY(info);
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_job_info_1(&info[i]);
+ *count = num_queues;
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ for (i=0; i<*count; i++) {
+ result = fill_job_info1(info,
+ &info[i].info1,
+ &queue[i],
+ i,
+ snum,
+ ntprinter);
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ out:
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
}
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- smb_io_job_info_1("", buffer, &info[i], 0);
-
-out:
- /* clear memory */
- SAFE_FREE(info);
-
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+ *info_p = info;
- return result;
+ return WERR_OK;
}
/****************************************************************************
Enumjobs at level 2.
****************************************************************************/
-static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
+static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
+ const print_queue_struct *queue,
+ uint32_t num_queues, int snum,
const NT_PRINTER_INFO_LEVEL *ntprinter,
- RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+ union spoolss_JobInfo **info_p,
+ uint32_t *count)
{
- JOB_INFO_2 *info = NULL;
+ union spoolss_JobInfo *info;
int i;
WERROR result = WERR_OK;
- DEVICEMODE *devmode = NULL;
- if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
- *returned=0;
- return WERR_NOMEM;
- }
+ info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+ W_ERROR_HAVE_NO_MEMORY(info);
- /* this should not be a failure condition if the devmode is NULL */
+ *count = num_queues;
- devmode = construct_dev_mode(lp_const_servicename(snum));
+ for (i=0; i<*count; i++) {
- for (i=0; i<*returned; i++)
- fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
+ struct spoolss_DeviceMode *devmode;
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_job_info_2(&info[i]);
+ devmode = construct_dev_mode_new(info, lp_const_servicename(snum));
+ if (!devmode) {
+ result = WERR_NOMEM;
+ goto out;
+ }
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ result = fill_job_info2(info,
+ &info[i].info2,
+ &queue[i],
+ i,
+ snum,
+ ntprinter,
+ devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ out:
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
}
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- smb_io_job_info_2("", buffer, &info[i], 0);
-
-out:
- free_devmode(devmode);
- SAFE_FREE(info);
-
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
-
- return result;
+ *info_p = info;
+ return WERR_OK;
}
-/****************************************************************************
- Enumjobs.
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumJobs
+****************************************************************/
-WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
+WERROR _spoolss_EnumJobs(pipes_struct *p,
+ struct spoolss_EnumJobs *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
- uint32 *returned = &r_u->returned;
- WERROR wret;
+ WERROR result;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
int snum;
print_status_struct prt_status;
- print_queue_struct *queue=NULL;
+ print_queue_struct *queue = NULL;
+ uint32_t count;
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
- return WERR_INVALID_PARAM;
- }
-
- if (offered > MAX_RPC_DATA_SIZE) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
-
- DEBUG(4,("_spoolss_enumjobs\n"));
+ DEBUG(4,("_spoolss_EnumJobs\n"));
- *needed=0;
- *returned=0;
+ *r->out.needed = 0;
+ *r->out.count = 0;
+ *r->out.info = NULL;
/* lookup the printer snum and tdb entry */
- if (!get_printer_snum(p, handle, &snum, NULL))
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
- wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
- if ( !W_ERROR_IS_OK(wret) )
- return wret;
+ result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
- *returned = print_queue_status(snum, &queue, &prt_status);
- DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
+ count = print_queue_status(snum, &queue, &prt_status);
+ DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
+ count, prt_status.status, prt_status.message));
- if (*returned == 0) {
+ if (count == 0) {
SAFE_FREE(queue);
free_a_printer(&ntprinter, 2);
return WERR_OK;
}
- switch (level) {
+ switch (r->in.level) {
case 1:
- wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
+ result = enumjobs_level1(p->mem_ctx, queue, count, snum,
+ ntprinter, r->out.info, r->out.count);
break;
case 2:
- wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
+ result = enumjobs_level2(p->mem_ctx, queue, count, snum,
+ ntprinter, r->out.info, r->out.count);
break;
default:
- *returned=0;
- wret = WERR_UNKNOWN_LEVEL;
+ result = WERR_UNKNOWN_LEVEL;
break;
}
SAFE_FREE(queue);
- free_a_printer( &ntprinter, 2 );
- return wret;
+ free_a_printer(&ntprinter, 2);
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumJobs, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************
@@ -6934,330 +6713,369 @@ WERROR _spoolss_SetJob(pipes_struct *p,
Enumerates all printer drivers at level 1.
****************************************************************************/
-static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *architecture,
+ union spoolss_DriverInfo **info_p,
+ uint32_t *count)
{
int i;
int ndrivers;
- uint32 version;
+ uint32_t version;
fstring *list = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_1 *driver_info_1=NULL;
+ union spoolss_DriverInfo *info = NULL;
WERROR result = WERR_OK;
- *returned=0;
+ *count = 0;
for (version=0; version<DRIVER_MAX_VERSION; version++) {
- list=NULL;
- ndrivers=get_ntdrivers(&list, architecture, version);
- DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
+ list = NULL;
+ ndrivers = get_ntdrivers(&list, architecture, version);
+ DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+ ndrivers, architecture, version));
- if(ndrivers == -1) {
- SAFE_FREE(driver_info_1);
- return WERR_NOMEM;
+ if (ndrivers == -1) {
+ result = WERR_NOMEM;
+ goto out;
}
- if(ndrivers != 0) {
- if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
- DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
- SAFE_FREE(list);
- return WERR_NOMEM;
+ if (ndrivers != 0) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ union spoolss_DriverInfo,
+ *count + ndrivers);
+ if (!info) {
+ DEBUG(0,("enumprinterdrivers_level1: "
+ "failed to enlarge driver info buffer!\n"));
+ result = WERR_NOMEM;
+ goto out;
}
}
for (i=0; i<ndrivers; i++) {
- WERROR status;
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- status = get_a_printer_driver(&driver, 3, list[i],
+ result = get_a_printer_driver(&driver, 3, list[i],
architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(list);
- SAFE_FREE(driver_info_1);
- return status;
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
+ result = fill_printer_driver_info1(info, &info[*count+i].info1,
+ &driver, servername,
+ architecture);
+ if (!W_ERROR_IS_OK(result)) {
+ free_a_printer_driver(driver, 3);
+ goto out;
}
- fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
free_a_printer_driver(driver, 3);
}
- *returned+=ndrivers;
+ *count += ndrivers;
SAFE_FREE(list);
}
- /* check the required size. */
- for (i=0; i<*returned; i++) {
- DEBUGADD(6,("adding driver [%d]'s size\n",i));
- *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
+ out:
+ SAFE_FREE(list);
- /* fill the buffer with the driver structures */
- for (i=0; i<*returned; i++) {
- DEBUGADD(6,("adding driver [%d] to buffer\n",i));
- smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
}
-out:
- SAFE_FREE(driver_info_1);
-
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+ *info_p = info;
- return result;
+ return WERR_OK;
}
/****************************************************************************
Enumerates all printer drivers at level 2.
****************************************************************************/
-static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *architecture,
+ union spoolss_DriverInfo **info_p,
+ uint32_t *count)
{
int i;
int ndrivers;
- uint32 version;
+ uint32_t version;
fstring *list = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_2 *driver_info_2=NULL;
+ union spoolss_DriverInfo *info = NULL;
WERROR result = WERR_OK;
- *returned=0;
+ *count = 0;
for (version=0; version<DRIVER_MAX_VERSION; version++) {
- list=NULL;
- ndrivers=get_ntdrivers(&list, architecture, version);
- DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
+ list = NULL;
+ ndrivers = get_ntdrivers(&list, architecture, version);
+ DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+ ndrivers, architecture, version));
- if(ndrivers == -1) {
- SAFE_FREE(driver_info_2);
- return WERR_NOMEM;
+ if (ndrivers == -1) {
+ result = WERR_NOMEM;
+ goto out;
}
- if(ndrivers != 0) {
- if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
- DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
- SAFE_FREE(list);
- return WERR_NOMEM;
+ if (ndrivers != 0) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ union spoolss_DriverInfo,
+ *count + ndrivers);
+ if (!info) {
+ DEBUG(0,("enumprinterdrivers_level2: "
+ "failed to enlarge driver info buffer!\n"));
+ result = WERR_NOMEM;
+ goto out;
}
}
for (i=0; i<ndrivers; i++) {
- WERROR status;
-
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- status = get_a_printer_driver(&driver, 3, list[i],
+ result = get_a_printer_driver(&driver, 3, list[i],
architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(list);
- SAFE_FREE(driver_info_2);
- return status;
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
+ result = fill_printer_driver_info2(info, &info[*count+i].info2,
+ &driver, servername);
+ if (!W_ERROR_IS_OK(result)) {
+ free_a_printer_driver(driver, 3);
+ goto out;
}
- fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
free_a_printer_driver(driver, 3);
}
- *returned+=ndrivers;
+ *count += ndrivers;
SAFE_FREE(list);
}
- /* check the required size. */
- for (i=0; i<*returned; i++) {
- DEBUGADD(6,("adding driver [%d]'s size\n",i));
- *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
+ out:
+ SAFE_FREE(list);
- /* fill the buffer with the form structures */
- for (i=0; i<*returned; i++) {
- DEBUGADD(6,("adding driver [%d] to buffer\n",i));
- smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
}
-out:
- SAFE_FREE(driver_info_2);
-
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+ *info_p = info;
- return result;
+ return WERR_OK;
}
/****************************************************************************
Enumerates all printer drivers at level 3.
****************************************************************************/
-static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *architecture,
+ union spoolss_DriverInfo **info_p,
+ uint32_t *count)
{
int i;
int ndrivers;
- uint32 version;
+ uint32_t version;
fstring *list = NULL;
- DRIVER_INFO_3 *driver_info_3=NULL;
+ union spoolss_DriverInfo *info = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
WERROR result = WERR_OK;
- *returned=0;
+ *count = 0;
for (version=0; version<DRIVER_MAX_VERSION; version++) {
- list=NULL;
- ndrivers=get_ntdrivers(&list, architecture, version);
- DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
+ list = NULL;
+ ndrivers = get_ntdrivers(&list, architecture, version);
+ DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+ ndrivers, architecture, version));
- if(ndrivers == -1) {
- SAFE_FREE(driver_info_3);
- return WERR_NOMEM;
+ if (ndrivers == -1) {
+ result = WERR_NOMEM;
+ goto out;
}
- if(ndrivers != 0) {
- if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
- DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
- SAFE_FREE(list);
- return WERR_NOMEM;
+ if (ndrivers != 0) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ union spoolss_DriverInfo,
+ *count + ndrivers);
+ if (!info) {
+ DEBUG(0,("enumprinterdrivers_level3: "
+ "failed to enlarge driver info buffer!\n"));
+ result = WERR_NOMEM;
+ goto out;
}
}
for (i=0; i<ndrivers; i++) {
- WERROR status;
-
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- status = get_a_printer_driver(&driver, 3, list[i],
+ result = get_a_printer_driver(&driver, 3, list[i],
architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(list);
- SAFE_FREE(driver_info_3);
- return status;
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
+ result = fill_printer_driver_info3(info, &info[*count+i].info3,
+ &driver, servername);
+ if (!W_ERROR_IS_OK(result)) {
+ free_a_printer_driver(driver, 3);
+ goto out;
}
- fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
+
free_a_printer_driver(driver, 3);
}
- *returned+=ndrivers;
+ *count += ndrivers;
SAFE_FREE(list);
}
- /* check the required size. */
- for (i=0; i<*returned; i++) {
- DEBUGADD(6,("adding driver [%d]'s size\n",i));
- *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
-
- /* fill the buffer with the driver structures */
- for (i=0; i<*returned; i++) {
- DEBUGADD(6,("adding driver [%d] to buffer\n",i));
- smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
- }
+ out:
+ SAFE_FREE(list);
-out:
- for (i=0; i<*returned; i++) {
- SAFE_FREE(driver_info_3[i].dependentfiles);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
}
- SAFE_FREE(driver_info_3);
-
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+ *info_p = info;
- return result;
+ return WERR_OK;
}
-/****************************************************************************
- Enumerates all printer drivers.
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinterDrivers
+****************************************************************/
-WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
+WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
+ struct spoolss_EnumPrinterDrivers *r)
{
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
- uint32 *returned = &r_u->returned;
const char *cservername;
- fstring servername;
- fstring architecture;
+ WERROR result;
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
- return WERR_INVALID_PARAM;
- }
-
- if (offered > MAX_RPC_DATA_SIZE) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
-
- DEBUG(4,("_spoolss_enumprinterdrivers\n"));
-
- *needed = 0;
- *returned = 0;
+ DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
- unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
- unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
+ *r->out.needed = 0;
+ *r->out.count = 0;
+ *r->out.info = NULL;
- cservername = canon_servername(servername);
+ cservername = canon_servername(r->in.server);
- if (!is_myname_or_ipaddr(cservername))
+ if (!is_myname_or_ipaddr(cservername)) {
return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
- switch (level) {
+ switch (r->in.level) {
case 1:
- return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
+ result = enumprinterdrivers_level1(p->mem_ctx, cservername,
+ r->in.environment,
+ r->out.info, r->out.count);
+ break;
case 2:
- return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
+ result = enumprinterdrivers_level2(p->mem_ctx, cservername,
+ r->in.environment,
+ r->out.info, r->out.count);
+ break;
case 3:
- return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
+ result = enumprinterdrivers_level3(p->mem_ctx, cservername,
+ r->in.environment,
+ r->out.info, r->out.count);
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumPrinterDrivers, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
****************************************************************************/
static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
- struct spoolss_FormInfo1 *form,
- nt_forms_struct *list)
+ struct spoolss_FormInfo1 *r,
+ const nt_forms_struct *form)
{
- form->form_name = talloc_strdup(mem_ctx, list->name);
- W_ERROR_HAVE_NO_MEMORY(form->form_name);
+ r->form_name = talloc_strdup(mem_ctx, form->name);
+ W_ERROR_HAVE_NO_MEMORY(r->form_name);
- form->flags = list->flag;
- form->size.width = list->width;
- form->size.height = list->length;
- form->area.left = list->left;
- form->area.top = list->top;
- form->area.right = list->right;
- form->area.bottom = list->bottom;
+ r->flags = form->flag;
+ r->size.width = form->width;
+ r->size.height = form->length;
+ r->area.left = form->left;
+ r->area.top = form->top;
+ r->area.right = form->right;
+ r->area.bottom = form->bottom;
+
+ return WERR_OK;
+}
+
+/****************************************************************
+ spoolss_enumforms_level1
+****************************************************************/
+
+static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
+ const nt_forms_struct *builtin_forms,
+ uint32_t num_builtin_forms,
+ const nt_forms_struct *user_forms,
+ uint32_t num_user_forms,
+ union spoolss_FormInfo **info_p,
+ uint32_t *count)
+{
+ union spoolss_FormInfo *info;
+ WERROR result = WERR_OK;
+ int i;
+
+ *count = num_builtin_forms + num_user_forms;
+
+ info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
+ W_ERROR_HAVE_NO_MEMORY(info);
+
+ /* construct the list of form structures */
+ for (i=0; i<num_builtin_forms; i++) {
+ DEBUGADD(6,("Filling form number [%d]\n",i));
+ result = fill_form_info_1(info, &info[i].info1,
+ &builtin_forms[i]);
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
+ }
+
+ for (; i<num_user_forms; i++) {
+ DEBUGADD(6,("Filling form number [%d]\n",i));
+ result = fill_form_info_1(info, &info[i].info1,
+ &user_forms[i-num_builtin_forms]);
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
+ }
+
+ out:
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ return result;
+ }
+
+ *info_p = info;
return WERR_OK;
}
@@ -7269,15 +7087,15 @@ static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
WERROR _spoolss_EnumForms(pipes_struct *p,
struct spoolss_EnumForms *r)
{
- nt_forms_struct *list=NULL;
- nt_forms_struct *builtinlist=NULL;
- union spoolss_FormInfo *info;
- uint32_t count;
- uint32_t numbuiltinforms;
- size_t buffer_size = 0;
- int i;
+ WERROR result;
+ nt_forms_struct *user_forms = NULL;
+ nt_forms_struct *builtin_forms = NULL;
+ uint32_t num_user_forms;
+ uint32_t num_builtin_forms;
*r->out.count = 0;
+ *r->out.needed = 0;
+ *r->out.info = NULL;
/* that's an [in out] buffer */
@@ -7289,69 +7107,85 @@ WERROR _spoolss_EnumForms(pipes_struct *p,
DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
DEBUGADD(5,("Info level [%d]\n", r->in.level));
- numbuiltinforms = get_builtin_ntforms(&builtinlist);
- DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
- count = get_ntforms(&list);
- DEBUGADD(5,("Number of user forms [%d]\n", count));
- count += numbuiltinforms;
+ num_builtin_forms = get_builtin_ntforms(&builtin_forms);
+ DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
+ num_user_forms = get_ntforms(&user_forms);
+ DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
- if (count == 0) {
- SAFE_FREE(builtinlist);
- SAFE_FREE(list);
+ if (num_user_forms + num_builtin_forms == 0) {
+ SAFE_FREE(builtin_forms);
+ SAFE_FREE(user_forms);
return WERR_NO_MORE_ITEMS;
}
- info = TALLOC_ARRAY(p->mem_ctx, union spoolss_FormInfo, count);
- if (!info) {
- SAFE_FREE(builtinlist);
- SAFE_FREE(list);
- return WERR_NOMEM;
- }
-
switch (r->in.level) {
case 1:
- /* construct the list of form structures */
- for (i=0; i<numbuiltinforms; i++) {
- DEBUGADD(6,("Filling form number [%d]\n",i));
- fill_form_info_1(info, &info[i].info1, &builtinlist[i]);
- }
-
- SAFE_FREE(builtinlist);
+ result = spoolss_enumforms_level1(p->mem_ctx,
+ builtin_forms,
+ num_builtin_forms,
+ user_forms,
+ num_user_forms,
+ r->out.info,
+ r->out.count);
+ break;
+ default:
+ result = WERR_UNKNOWN_LEVEL;
+ break;
+ }
- for (; i<count; i++) {
- DEBUGADD(6,("Filling form number [%d]\n",i));
- fill_form_info_1(info, &info[i].info1, &list[i-numbuiltinforms]);
- }
+ SAFE_FREE(user_forms);
+ SAFE_FREE(builtin_forms);
- SAFE_FREE(list);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
- /* check the required size. */
- for (i=0; i<numbuiltinforms; i++) {
- DEBUGADD(6,("adding form [%d]'s size\n",i));
- buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
- }
- for (; i<count; i++) {
- DEBUGADD(6,("adding form [%d]'s size\n",i));
- buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
- }
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumForms, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
- *r->out.needed = buffer_size;
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+}
- if (*r->out.needed > r->in.offered) {
- TALLOC_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
- }
+/****************************************************************
+****************************************************************/
- *r->out.count = count;
- *r->out.info = info;
+static WERROR find_form_byname(const char *name,
+ nt_forms_struct *form)
+{
+ nt_forms_struct *list = NULL;
+ int num_forms = 0, i = 0;
+ if (get_a_builtin_ntform_by_string(name, form)) {
return WERR_OK;
+ }
- default:
- SAFE_FREE(list);
- SAFE_FREE(builtinlist);
- return WERR_UNKNOWN_LEVEL;
+ num_forms = get_ntforms(&list);
+ DEBUGADD(5,("Number of forms [%d]\n", num_forms));
+
+ if (num_forms == 0) {
+ return WERR_BADFID;
}
+
+ /* Check if the requested name is in the list of form structures */
+ for (i = 0; i < num_forms; i++) {
+
+ DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
+
+ if (strequal(name, list[i].name)) {
+ DEBUGADD(6,("Found form %s number [%d]\n", name, i));
+ *form = list[i];
+ SAFE_FREE(list);
+ return WERR_OK;
+ }
+ }
+
+ SAFE_FREE(list);
+
+ return WERR_BADFID;
}
/****************************************************************
@@ -7361,86 +7195,47 @@ WERROR _spoolss_EnumForms(pipes_struct *p,
WERROR _spoolss_GetForm(pipes_struct *p,
struct spoolss_GetForm *r)
{
- uint32 level = r->in.level;
- uint32 offered = r->in.offered;
- uint32 *needed = r->out.needed;
-
- nt_forms_struct *list=NULL;
- nt_forms_struct builtin_form;
- bool foundBuiltin;
- union spoolss_FormInfo info;
- struct spoolss_FormInfo1 form_1;
- int numofforms=0, i=0;
+ WERROR result;
+ nt_forms_struct form;
/* that's an [in out] buffer */
- if (!r->in.buffer && (offered!=0)) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
DEBUG(4,("_spoolss_GetForm\n"));
- DEBUGADD(5,("Offered buffer size [%d]\n", offered));
- DEBUGADD(5,("Info level [%d]\n", level));
-
- foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
- if (!foundBuiltin) {
- numofforms = get_ntforms(&list);
- DEBUGADD(5,("Number of forms [%d]\n", numofforms));
+ DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
+ DEBUGADD(5,("Info level [%d]\n", r->in.level));
- if (numofforms == 0)
- return WERR_BADFID;
+ result = find_form_byname(r->in.form_name, &form);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
}
- ZERO_STRUCT(form_1);
-
- switch (level) {
+ switch (r->in.level) {
case 1:
- if (foundBuiltin) {
- fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
- } else {
-
- /* Check if the requested name is in the list of form structures */
- for (i=0; i<numofforms; i++) {
-
- DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
- list[i].name, r->in.form_name));
-
- if (strequal(r->in.form_name, list[i].name)) {
- DEBUGADD(6,("Found form %s number [%d]\n",
- r->in.form_name, i));
- fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
- break;
- }
- }
-
- SAFE_FREE(list);
- if (i == numofforms) {
- return WERR_BADFID;
- }
- }
- /* check the required size. */
-
- info.info1 = form_1;
-
- *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
-
- if (*needed > offered) {
- r->out.info = NULL;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ result = fill_form_info_1(p->mem_ctx,
+ &r->out.info->info1,
+ &form);
+ break;
- r->out.info->info1 = form_1;
+ default:
+ result = WERR_UNKNOWN_LEVEL;
+ break;
+ }
- /* fill the buffer with the form structures */
- DEBUGADD(6,("adding form %s [%d] to buffer\n",
- r->in.form_name, i));
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
+ }
- return WERR_OK;
+ *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL,
+ r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
- default:
- SAFE_FREE(list);
- return WERR_UNKNOWN_LEVEL;
- }
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
@@ -7547,8 +7342,6 @@ WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
union spoolss_PortInfo **info_p,
- uint32_t offered,
- uint32_t *needed,
uint32_t *count)
{
union spoolss_PortInfo *info = NULL;
@@ -7580,17 +7373,6 @@ static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
}
TALLOC_FREE(qlines);
- /* check the required size. */
- for (i=0; i<numlines; i++) {
- DEBUGADD(6,("adding port [%d]'s size\n", i));
- *needed += ndr_size_spoolss_PortInfo1(&info[i].info1, NULL, 0);
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
@@ -7612,8 +7394,6 @@ out:
static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
union spoolss_PortInfo **info_p,
- uint32_t offered,
- uint32_t *needed,
uint32_t *count)
{
union spoolss_PortInfo *info = NULL;
@@ -7645,17 +7425,6 @@ static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
}
TALLOC_FREE(qlines);
- /* check the required size. */
- for (i=0; i<numlines; i++) {
- DEBUGADD(6,("adding port [%d]'s size\n", i));
- *needed += ndr_size_spoolss_PortInfo2(&info[i].info2, NULL, 0);
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
@@ -7678,6 +7447,8 @@ out:
WERROR _spoolss_EnumPorts(pipes_struct *p,
struct spoolss_EnumPorts *r)
{
+ WERROR result;
+
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
@@ -7692,16 +7463,29 @@ WERROR _spoolss_EnumPorts(pipes_struct *p,
switch (r->in.level) {
case 1:
- return enumports_level_1(p->mem_ctx, r->out.info,
- r->in.offered, r->out.needed,
- r->out.count);
+ result = enumports_level_1(p->mem_ctx, r->out.info,
+ r->out.count);
+ break;
case 2:
- return enumports_level_2(p->mem_ctx, r->out.info,
- r->in.offered, r->out.needed,
- r->out.count);
+ result = enumports_level_2(p->mem_ctx, r->out.info,
+ r->out.count);
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumPorts, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
@@ -8106,9 +7890,7 @@ static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
const char *servername,
const char *environment,
- struct spoolss_DriverDirectoryInfo1 *r,
- uint32_t offered,
- uint32_t *needed)
+ struct spoolss_DriverDirectoryInfo1 *r)
{
WERROR werr;
char *path = NULL;
@@ -8126,13 +7908,6 @@ static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
r->directory_name = path;
- *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
-
- if (*needed > offered) {
- talloc_free(path);
- return WERR_INSUFFICIENT_BUFFER;
- }
-
return WERR_OK;
}
@@ -8161,14 +7936,17 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
werror = getprinterdriverdir_level_1(p->mem_ctx,
r->in.server,
r->in.environment,
- &r->out.info->info1,
- r->in.offered,
- r->out.needed);
+ &r->out.info->info1);
if (!W_ERROR_IS_OK(werror)) {
TALLOC_FREE(r->out.info);
+ return werror;
}
- return werror;
+ *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL,
+ r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
@@ -8757,8 +8535,6 @@ static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
union spoolss_PrintProcessorInfo **info_p,
- uint32_t offered,
- uint32_t *needed,
uint32_t *count)
{
union spoolss_PrintProcessorInfo *info;
@@ -8774,13 +8550,6 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
goto out;
}
- *needed += ndr_size_spoolss_PrintProcessorInfo1(&info[0].info1, NULL, 0);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
@@ -8800,6 +8569,8 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
struct spoolss_EnumPrintProcessors *r)
{
+ WERROR result;
+
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
@@ -8821,12 +8592,25 @@ WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
switch (r->in.level) {
case 1:
- return enumprintprocessors_level_1(p->mem_ctx, r->out.info,
- r->in.offered, r->out.needed,
- r->out.count);
+ result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
+ r->out.count);
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumPrintProcessors, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
@@ -8849,8 +8633,6 @@ static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
union spoolss_PrintProcDataTypesInfo **info_p,
- uint32_t offered,
- uint32_t *needed,
uint32_t *count)
{
WERROR result;
@@ -8866,13 +8648,6 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
goto out;
}
- *needed += ndr_size_spoolss_PrintProcDataTypesInfo1(&info[0].info1, NULL, 0);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
@@ -8892,6 +8667,8 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
struct spoolss_EnumPrintProcDataTypes *r)
{
+ WERROR result;
+
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
@@ -8906,12 +8683,21 @@ WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
switch (r->in.level) {
case 1:
- return enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
- r->in.offered, r->out.needed,
- r->out.count);
+ result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
+ r->out.count);
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumPrintProcDataTypes, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
@@ -8954,13 +8740,10 @@ static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
union spoolss_MonitorInfo **info_p,
- uint32_t offered,
- uint32_t *needed,
uint32_t *count)
{
union spoolss_MonitorInfo *info;
WERROR result = WERR_OK;
- int i;
info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
W_ERROR_HAVE_NO_MEMORY(info);
@@ -8979,15 +8762,6 @@ static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
goto out;
}
- for (i=0; i<*count; i++) {
- *needed += ndr_size_spoolss_MonitorInfo1(&info[i].info1, NULL, 0);
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
@@ -9006,13 +8780,10 @@ out:
static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
union spoolss_MonitorInfo **info_p,
- uint32_t offered,
- uint32_t *needed,
uint32_t *count)
{
union spoolss_MonitorInfo *info;
WERROR result = WERR_OK;
- int i;
info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
W_ERROR_HAVE_NO_MEMORY(info);
@@ -9035,15 +8806,6 @@ static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
goto out;
}
- for (i=0; i<*count; i++) {
- *needed += ndr_size_spoolss_MonitorInfo2(&info[i].info2, NULL, 0);
- }
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
@@ -9063,6 +8825,8 @@ out:
WERROR _spoolss_EnumMonitors(pipes_struct *p,
struct spoolss_EnumMonitors *r)
{
+ WERROR result;
+
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
@@ -9084,101 +8848,89 @@ WERROR _spoolss_EnumMonitors(pipes_struct *p,
switch (r->in.level) {
case 1:
- return enumprintmonitors_level_1(p->mem_ctx, r->out.info,
- r->in.offered, r->out.needed,
- r->out.count);
+ result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
+ r->out.count);
+ break;
case 2:
- return enumprintmonitors_level_2(p->mem_ctx, r->out.info,
- r->in.offered, r->out.needed,
- r->out.count);
+ result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
+ r->out.count);
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+ spoolss_EnumMonitors, NULL,
+ *r->out.info, r->in.level,
+ *r->out.count);
+ *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+ *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
- NT_PRINTER_INFO_LEVEL *ntprinter,
- uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed)
+static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
+ const print_queue_struct *queue,
+ int count, int snum,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ uint32_t jobid,
+ struct spoolss_JobInfo1 *r)
{
- int i=0;
- bool found=False;
- JOB_INFO_1 *info_1=NULL;
- WERROR result = WERR_OK;
-
- info_1=SMB_MALLOC_P(JOB_INFO_1);
-
- if (info_1 == NULL) {
- return WERR_NOMEM;
- }
+ int i = 0;
+ bool found = false;
- for (i=0; i<count && found==False; i++) {
- if ((*queue)[i].job==(int)jobid)
- found=True;
+ for (i=0; i<count && found == false; i++) {
+ if (queue[i].job == (int)jobid) {
+ found = true;
+ }
}
- if (found==False) {
- SAFE_FREE(info_1);
+ if (found == false) {
/* NT treats not found as bad param... yet another bad choice */
return WERR_INVALID_PARAM;
}
- fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
-
- *needed += spoolss_size_job_info_1(info_1);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
- }
-
- smb_io_job_info_1("", buffer, info_1, 0);
-
-out:
- SAFE_FREE(info_1);
-
- return result;
+ return fill_job_info1(mem_ctx,
+ r,
+ &queue[i-1],
+ i,
+ snum,
+ ntprinter);
}
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
- NT_PRINTER_INFO_LEVEL *ntprinter,
- uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
- uint32 *needed)
-{
- int i = 0;
- bool found = False;
- JOB_INFO_2 *info_2;
- WERROR result;
- DEVICEMODE *devmode = NULL;
- NT_DEVICEMODE *nt_devmode = NULL;
-
- if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
- return WERR_NOMEM;
-
- ZERO_STRUCTP(info_2);
+static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
+ const print_queue_struct *queue,
+ int count, int snum,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ uint32_t jobid,
+ struct spoolss_JobInfo2 *r)
+{
+ int i = 0;
+ bool found = false;
+ struct spoolss_DeviceMode *devmode;
+ NT_DEVICEMODE *nt_devmode;
+ WERROR result;
- for ( i=0; i<count && found==False; i++ )
- {
- if ((*queue)[i].job == (int)jobid)
- found = True;
+ for (i=0; i<count && found == false; i++) {
+ if (queue[i].job == (int)jobid) {
+ found = true;
+ }
}
- if ( !found ) {
+ if (found == false) {
/* NT treats not found as bad param... yet another bad
choice */
- result = WERR_INVALID_PARAM;
- goto done;
+ return WERR_INVALID_PARAM;
}
/*
@@ -9187,54 +8939,36 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
* a failure condition
*/
- if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
- devmode = construct_dev_mode(lp_const_servicename(snum));
- else {
- if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
- ZERO_STRUCTP( devmode );
- convert_nt_devicemode( devmode, nt_devmode );
+ nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
+ if (nt_devmode) {
+ devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
+ W_ERROR_HAVE_NO_MEMORY(devmode);
+ result = convert_nt_devicemode_new(devmode, devmode, nt_devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
}
+ } else {
+ devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+ W_ERROR_HAVE_NO_MEMORY(devmode);
}
- fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
-
- *needed += spoolss_size_job_info_2(info_2);
-
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto done;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto done;
- }
-
- smb_io_job_info_2("", buffer, info_2, 0);
-
- result = WERR_OK;
-
- done:
- /* Cleanup allocated memory */
-
- free_job_info_2(info_2); /* Also frees devmode */
- SAFE_FREE(info_2);
-
- return result;
+ return fill_job_info2(mem_ctx,
+ r,
+ &queue[i-1],
+ i,
+ snum,
+ ntprinter,
+ devmode);
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetJob
+****************************************************************/
-WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
+WERROR _spoolss_GetJob(pipes_struct *p,
+ struct spoolss_GetJob *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 jobid = q_u->jobid;
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
- WERROR wstatus = WERR_OK;
+ WERROR result = WERR_OK;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
int snum;
int count;
@@ -9243,51 +8977,57 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
- return WERR_INVALID_PARAM;
- }
-
- if (offered > MAX_RPC_DATA_SIZE) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
-
- DEBUG(5,("spoolss_getjob\n"));
+ DEBUG(5,("_spoolss_GetJob\n"));
- *needed = 0;
+ *r->out.needed = 0;
- if (!get_printer_snum(p, handle, &snum, NULL))
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
- wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
- if ( !W_ERROR_IS_OK(wstatus) )
- return wstatus;
+ result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
count = print_queue_status(snum, &queue, &prt_status);
DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
count, prt_status.status, prt_status.message));
- switch ( level ) {
+ switch (r->in.level) {
case 1:
- wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
- buffer, offered, needed);
- break;
+ result = getjob_level_1(p->mem_ctx,
+ queue, count, snum, ntprinter,
+ r->in.job_id, &r->out.info->info1);
+ break;
case 2:
- wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
- buffer, offered, needed);
- break;
+ result = getjob_level_2(p->mem_ctx,
+ queue, count, snum, ntprinter,
+ r->in.job_id, &r->out.info->info2);
+ break;
default:
- wstatus = WERR_UNKNOWN_LEVEL;
- break;
+ result = WERR_UNKNOWN_LEVEL;
+ break;
}
SAFE_FREE(queue);
- free_a_printer( &ntprinter, 2 );
+ free_a_printer(&ntprinter, 2);
- return wstatus;
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
+ }
+
+ *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL,
+ r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/****************************************************************
@@ -9812,9 +9552,7 @@ done:
static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
const char *servername,
const char *environment,
- struct spoolss_PrintProcessorDirectoryInfo1 *r,
- uint32_t offered,
- uint32_t *needed)
+ struct spoolss_PrintProcessorDirectoryInfo1 *r)
{
WERROR werr;
char *path = NULL;
@@ -9832,13 +9570,6 @@ static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
r->directory_name = path;
- *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
-
- if (*needed > offered) {
- talloc_free(path);
- return WERR_INSUFFICIENT_BUFFER;
- }
-
return WERR_OK;
}
@@ -9867,14 +9598,17 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
result = getprintprocessordirectory_level_1(p->mem_ctx,
r->in.server,
r->in.environment,
- &r->out.info->info1,
- r->in.offered,
- r->out.needed);
+ &r->out.info->info1);
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(r->out.info);
+ return result;
}
- return result;
+ *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL,
+ r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
/*******************************************************************
@@ -10208,39 +9942,6 @@ WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
}
/****************************************************************
- _spoolss_EnumPrinters
-****************************************************************/
-
-WERROR _spoolss_EnumPrinters(pipes_struct *p,
- struct spoolss_EnumPrinters *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_GetJob
-****************************************************************/
-
-WERROR _spoolss_GetJob(pipes_struct *p,
- struct spoolss_GetJob *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumJobs
-****************************************************************/
-
-WERROR _spoolss_EnumJobs(pipes_struct *p,
- struct spoolss_EnumJobs *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
_spoolss_AddPrinter
****************************************************************/
@@ -10252,28 +9953,6 @@ WERROR _spoolss_AddPrinter(pipes_struct *p,
}
/****************************************************************
- _spoolss_GetPrinter
-****************************************************************/
-
-WERROR _spoolss_GetPrinter(pipes_struct *p,
- struct spoolss_GetPrinter *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumPrinterDrivers
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
- struct spoolss_EnumPrinterDrivers *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
_spoolss_GetPrinterDriver
****************************************************************/
@@ -10483,17 +10162,6 @@ WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
}
/****************************************************************
- _spoolss_GetPrinterDriver2
-****************************************************************/
-
-WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
- struct spoolss_GetPrinterDriver2 *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
_spoolss_FindFirstPrinterChangeNotification
****************************************************************/