GetPrinterData on a printer server Handle.
********************************************************************/
-static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
+static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
+ const char *value,
+ enum winreg_Type *type,
+ union spoolss_PrinterData *data)
{
- int i;
-
DEBUG(8,("getprinterdata_printer_server:%s\n", value));
if (!StrCaseCmp(value, "W3SvcInstalled")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
- SIVAL(*data, 0, 0x00);
- *needed = 0x4;
+ data->value = 0x00;
return WERR_OK;
}
if (!StrCaseCmp(value, "BeepEnabled")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
- SIVAL(*data, 0, 0x00);
- *needed = 0x4;
+ data->value = 0x00;
return WERR_OK;
}
if (!StrCaseCmp(value, "EventLog")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
/* formally was 0x1b */
- SIVAL(*data, 0, 0x0);
- *needed = 0x4;
+ data->value = 0x00;
return WERR_OK;
}
if (!StrCaseCmp(value, "NetPopup")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
- SIVAL(*data, 0, 0x00);
- *needed = 0x4;
+ data->value = 0x00;
return WERR_OK;
}
if (!StrCaseCmp(value, "MajorVersion")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
/* Windows NT 4.0 seems to not allow uploading of drivers
to a server that reports 0x3 as the MajorVersion.
need to investigate more how Win2k gets around this .
-- jerry */
- if ( RA_WINNT == get_remote_arch() )
- SIVAL(*data, 0, 2);
- else
- SIVAL(*data, 0, 3);
+ if (RA_WINNT == get_remote_arch()) {
+ data->value = 0x02;
+ } else {
+ data->value = 0x03;
+ }
- *needed = 0x4;
return WERR_OK;
}
if (!StrCaseCmp(value, "MinorVersion")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
- SIVAL(*data, 0, 0);
- *needed = 0x4;
+ data->value = 0x00;
return WERR_OK;
}
* extra unicode string = e.g. "Service Pack 3"
*/
if (!StrCaseCmp(value, "OSVersion")) {
- *type = REG_BINARY;
- *needed = 0x114;
-
- if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
- return WERR_NOMEM;
-
- SIVAL(*data, 0, *needed); /* size */
- SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
- SIVAL(*data, 8, 0);
- SIVAL(*data, 12, 2195); /* build */
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct spoolss_OSVersion os;
+
+ os.major = 5; /* Windows 2000 == 5.0 */
+ os.minor = 0;
+ os.build = 2195; /* build */
+ os.extra_string = ""; /* leave extra string empty */
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
+ (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_GENERAL_FAILURE;
+ }
- /* leave extra string empty */
+ *type = REG_BINARY;
+ data->binary = blob;
return WERR_OK;
}
if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
- const char *string="C:\\PRINTERS";
*type = REG_SZ;
- *needed = 2*(strlen(string)+1);
- if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
- return WERR_NOMEM;
- memset(*data, 0, (*needed > in_size) ? *needed:in_size);
- /* it's done by hand ready to go on the wire */
- for (i=0; i<strlen(string); i++) {
- (*data)[2*i]=string[i];
- (*data)[2*i+1]='\0';
- }
+ data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
+ W_ERROR_HAVE_NO_MEMORY(data->string);
+
return WERR_OK;
}
if (!StrCaseCmp(value, "Architecture")) {
- const char *string="Windows NT x86";
*type = REG_SZ;
- *needed = 2*(strlen(string)+1);
- if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
- return WERR_NOMEM;
- memset(*data, 0, (*needed > in_size) ? *needed:in_size);
- for (i=0; i<strlen(string); i++) {
- (*data)[2*i]=string[i];
- (*data)[2*i+1]='\0';
- }
+
+ data->string = talloc_strdup(mem_ctx, "Windows NT x86");
+ W_ERROR_HAVE_NO_MEMORY(data->string);
+
return WERR_OK;
}
if (!StrCaseCmp(value, "DsPresent")) {
*type = REG_DWORD;
- if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
- return WERR_NOMEM;
/* only show the publish check box if we are a
- memeber of a AD domain */
-
- if ( lp_security() == SEC_ADS )
- SIVAL(*data, 0, 0x01);
- else
- SIVAL(*data, 0, 0x00);
+ member of a AD domain */
- *needed = 0x4;
+ if (lp_security() == SEC_ADS) {
+ data->value = 0x01;
+ } else {
+ data->value = 0x00;
+ }
return WERR_OK;
}
if (!StrCaseCmp(value, "DNSMachineName")) {
const char *hostname = get_mydnsfullname();
- if (!hostname)
+ if (!hostname) {
return WERR_BADFILE;
- *type = REG_SZ;
- *needed = 2*(strlen(hostname)+1);
- if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
- return WERR_NOMEM;
- memset(*data, 0, (*needed > in_size) ? *needed:in_size);
- for (i=0; i<strlen(hostname); i++) {
- (*data)[2*i]=hostname[i];
- (*data)[2*i+1]='\0';
}
+
+ *type = REG_SZ;
+ data->string = talloc_strdup(mem_ctx, hostname);
+ W_ERROR_HAVE_NO_MEMORY(data->string);
+
return WERR_OK;
}
-
return WERR_BADFILE;
}
-/********************************************************************
- * spoolss_getprinterdata
- ********************************************************************/
+/****************************************************************
+ _spoolss_GetPrinterData
+****************************************************************/
-WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
+WERROR _spoolss_GetPrinterData(pipes_struct *p,
+ struct spoolss_GetPrinterData *r)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *valuename = &q_u->valuename;
- uint32 in_size = q_u->size;
- uint32 *type = &r_u->type;
- uint32 *out_size = &r_u->size;
- uint8 **data = &r_u->data;
- uint32 *needed = &r_u->needed;
- WERROR status;
- fstring value;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum = 0;
+ WERROR result;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int snum = 0;
/*
* Reminder: when it's a string, the length is in BYTES
* JFM, 4/19/1999
*/
- *out_size = in_size;
-
/* in case of problem, return some default values */
- *needed = 0;
- *type = 0;
+ *r->out.needed = 0;
+ *r->out.type = 0;
- DEBUG(4,("_spoolss_getprinterdata\n"));
+ DEBUG(4,("_spoolss_GetPrinterData\n"));
- if ( !Printer ) {
- DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- status = WERR_BADFID;
+ if (!Printer) {
+ DEBUG(2,("_spoolss_GetPrinterData: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(r->in.handle)));
+ result = WERR_BADFID;
goto done;
}
- unistr2_to_ascii(value, valuename, sizeof(value));
-
- if ( Printer->printer_type == SPLHND_SERVER )
- status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
- else
- {
- if ( !get_printer_snum(p,handle, &snum, NULL) ) {
- status = WERR_BADFID;
+ if (Printer->printer_type == SPLHND_SERVER) {
+ result = getprinterdata_printer_server(p->mem_ctx,
+ r->in.value_name,
+ r->out.type,
+ r->out.data);
+ } else {
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+ result = WERR_BADFID;
goto done;
}
- status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
- if ( !W_ERROR_IS_OK(status) )
+ result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
goto done;
+ }
/* XP sends this and wants to change id value from the PRINTER_INFO_0 */
- if ( strequal(value, "ChangeId") ) {
- *type = REG_DWORD;
- *needed = sizeof(uint32);
- if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
- status = WERR_NOMEM;
+ if (strequal(r->in.value_name, "ChangeId")) {
+ *r->out.type = REG_DWORD;
+ r->out.data->value = printer->info_2->changeid;
+ result = WERR_OK;
+ } else {
+ REGISTRY_VALUE *v;
+ DATA_BLOB blob;
+
+ v = get_printer_data(printer->info_2,
+ SPOOL_PRINTERDATA_KEY,
+ r->in.value_name);
+ if (!v) {
+ result = WERR_BADFILE;
goto done;
}
- SIVAL( *data, 0, printer->info_2->changeid );
- status = WERR_OK;
- }
- else
- status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
- }
-
- if (*needed > *out_size)
- status = WERR_MORE_DATA;
-done:
- if ( !W_ERROR_IS_OK(status) )
- {
- DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
+ *r->out.type = v->type;
- /* reply this param doesn't exist */
+ blob = data_blob_const(v->data_p, v->size);
- if ( *out_size ) {
- if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
- if ( printer )
- free_a_printer( &printer, 2 );
- return WERR_NOMEM;
- }
- } else {
- *data = NULL;
+ result = pull_spoolss_PrinterData(p->mem_ctx, &blob,
+ r->out.data,
+ *r->out.type);
}
}
+ done:
/* cleanup & exit */
- if ( printer )
- free_a_printer( &printer, 2 );
+ if (printer) {
+ free_a_printer(&printer, 2);
+ }
- return status;
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ *r->out.needed = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, NULL, 0);
+ *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
+ r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
+
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
}
/*********************************************************
* 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;
-
- 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);
+ 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;
- free_a_printer(&ntprinter,2);
-
- return True;
+ return WERR_OK;
}
/****************************************************************************
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
}
/****************************************************************************
- Create a DEVMODE struct. Returns malloced memory.
+ Create a spoolss_DeviceMode struct. Returns talloced memory.
****************************************************************************/
-DEVICEMODE *construct_dev_mode(const char *servicename)
+struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
+ const char *servicename)
{
+ WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
- DEVICEMODE *devmode = NULL;
+ struct spoolss_DeviceMode *devmode = NULL;
- DEBUG(7,("construct_dev_mode\n"));
+ 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 ) {
+ if (!printer->info_2->devmode) {
DEBUG(5, ("BONG! There was no device mode!\n"));
goto done;
}
- if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
- DEBUG(2,("construct_dev_mode: malloc fail.\n"));
+ devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
+ if (!devmode) {
+ DEBUG(2,("construct_dev_mode_new: talloc fail.\n"));
goto done;
}
- ZERO_STRUCTP(devmode);
-
DEBUGADD(8,("loading DEVICEMODE\n"));
- if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
- free_dev_mode( devmode );
- devmode = NULL;
+ result = convert_nt_devicemode_new(mem_ctx, devmode, printer->info_2->devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(devmode);
}
done:
return devmode;
}
-/********************************************************************
- * construct_printer_info_2
- * fill a printer_info_2 struct
- ********************************************************************/
+/****************************************************************************
+ Create a DEVMODE struct. Returns malloced memory.
+****************************************************************************/
-static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
+DEVICEMODE *construct_dev_mode(const char *servicename)
{
- 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 */
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ DEVICEMODE *devmode = NULL;
- 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. */
+ DEBUG(7,("construct_dev_mode\n"));
- 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) */
+ DEBUGADD(8,("getting printer characteristics\n"));
- printer->attributes = ntprinter->info_2->attributes;
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
+ return NULL;
- 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->info_2->devmode ) {
+ DEBUG(5, ("BONG! There was no device mode!\n"));
+ goto done;
+ }
- if ( !(printer->devmode = construct_dev_mode(
- lp_const_servicename(snum))) )
- DEBUG(8, ("Returning NULL Devicemode!\n"));
+ if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
+ DEBUG(2,("construct_dev_mode: malloc fail.\n"));
+ goto done;
+ }
- printer->secdesc = NULL;
+ ZERO_STRUCTP(devmode);
- 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 */
+ DEBUGADD(8,("loading DEVICEMODE\n"));
- printer->secdesc = dup_sec_desc( talloc_tos(),
- ntprinter->info_2->secdesc_buf->sd );
+ if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
+ free_dev_mode( devmode );
+ devmode = NULL;
}
- free_a_printer(&ntprinter, 2);
+done:
+ free_a_printer(&printer,2);
- return True;
+ return devmode;
}
/********************************************************************
- * construct_printer_info_3
- * fill a printer_info_3 struct
+ * construct_printer_info3
+ * fill a spoolss_PrinterInfo3 struct
********************************************************************/
-static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
+static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo3 *r,
+ int snum)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- PRINTER_INFO_3 *printer = NULL;
-
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
-
- *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;
- }
-
- ZERO_STRUCTP(printer);
-
/* These are the components of the SD we are returning. */
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);
-
- *pp_printer = printer;
- return True;
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_4
- * fill a printer_info_4 struct
+ * construct_printer_info4
+ * fill a spoolss_PrinterInfo4 struct
********************************************************************/
-static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *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;
-
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
- return False;
+ 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);
- 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->attributes = ntprinter->info_2->attributes;
- free_a_printer(&ntprinter, 2);
- return True;
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_5
- * fill a printer_info_5 struct
+ * construct_printer_info5
+ * fill a spoolss_PrinterInfo5 struct
********************************************************************/
-static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
+static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo5 *r,
+ int snum)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+ 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 (!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);
- init_unistr(&printer->portname, ntprinter->info_2->portname);
- printer->attributes = ntprinter->info_2->attributes;
+ r->attributes = ntprinter->info_2->attributes;
/* these two are not used by NT+ according to MSDN */
- printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
- printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
-
- free_a_printer(&ntprinter, 2);
+ r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
+ r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
- return True;
+ return WERR_OK;
}
/********************************************************************
* construct_printer_info_6
- * fill a printer_info_6 struct
+ * fill a spoolss_PrinterInfo6 struct
********************************************************************/
-static bool construct_printer_info_6(Printer_entry *print_hnd,
- PRINTER_INFO_6 *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);
- printer->status = nt_printq_status(status.status);
-
- free_a_printer(&ntprinter, 2);
+ r->status = nt_printq_status(status.status);
- return True;
+ return WERR_OK;
}
/********************************************************************
- * construct_printer_info_7
- * fill a printer_info_7 struct
+ * construct_printer_info7
+ * fill a spoolss_PrinterInfo7 struct
********************************************************************/
-static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
+static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
+ Printer_entry *print_hnd,
+ struct spoolss_PrinterInfo7 *r,
+ int snum)
{
- char *guid_str = NULL;
struct GUID guid;
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;
+ r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
+ r->action = DSPRINT_PUBLISH;
} else {
- init_unistr(&printer->guid, "");
- printer->action = DSPRINT_UNPUBLISH;
+ r->guid = talloc_strdup(mem_ctx, "");
+ r->action = DSPRINT_UNPUBLISH;
}
+ W_ERROR_HAVE_NO_MEMORY(r->guid);
- return True;
+ return WERR_OK;
}
/********************************************************************
- Spoolss_enumprinters.
+ * construct_printer_info1
+ * fill a spoolss_PrinterInfo1 struct
********************************************************************/
-static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ uint32_t flags,
+ struct spoolss_PrinterInfo1 *r,
+ int snum)
{
- int snum;
- int i;
- int n_services=lp_numservices();
- PRINTER_INFO_1 *printers=NULL;
- PRINTER_INFO_1 current_prt;
- WERROR result = WERR_OK;
-
- DEBUG(4,("enum_all_printers_info_1\n"));
+ char *chaine = NULL;
+ r->flags = flags;
- 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, ¤t_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));
+ 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);
- memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
- (*returned)++;
- }
- }
+ 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_info2
+ * fill a spoolss_PrinterInfo2 struct
+********************************************************************/
+
+static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_INFO_LEVEL *ntprinter,
+ struct spoolss_PrinterInfo2 *r,
+ int snum)
+{
+ int count;
+
+ print_status_struct status;
+
+ count = print_queue_length(snum, &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);
+
+ 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);
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_printer_info_1(&printers[i]);
+ 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);
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ r->attributes = ntprinter->info_2->attributes;
+
+ 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;
+
+ r->devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+ if (!r->devmode) {
+ DEBUG(8,("Returning NULL Devicemode!\n"));
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ 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);
}
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- smb_io_printer_info_1("", buffer, &printers[i], 0);
+ return WERR_OK;
+}
-out:
- /* clear memory */
+/********************************************************************
+********************************************************************/
- SAFE_FREE(printers);
+static bool snum_is_shared_printer(int snum)
+{
+ return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
+}
- if ( !W_ERROR_IS_OK(result) )
- *returned = 0;
+/********************************************************************
+ Spoolss_enumprinters.
+********************************************************************/
- return result;
+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 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++) {
+
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+ struct spoolss_PrinterInfo1 info1;
+
+ if (!snum_is_shared_printer(snum)) {
+ continue;
+ }
+
+ DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
+
+ result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ continue;
+ }
+
+ result = construct_printer_info1(info, ntprinter, flags, &info1, snum);
+ free_a_printer(&ntprinter,2);
+ if (!W_ERROR_IS_OK(result)) {
+ continue;
+ }
+
+ 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;
+ }
+
+ DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count));
+
+ info[*count].info1 = info1;
+ (*count)++;
+ }
+
+ out:
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(info);
+ *count = 0;
+ 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 */
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"));
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);
}
/********************************************************************
* 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, ¤t_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], ¤t_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 */
}
* 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;
}
* 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:
* 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;
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
- 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;
- }
-
- /* 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;
+ const char *cservername = canon_servername(servername);
- if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
- return WERR_NOMEM;
- }
+ r->version = driver->info_3->cversion;
- if (!construct_printer_info_6(print_hnd, printer, snum)) {
- free_printer_info_6(printer);
- return WERR_NOMEM;
- }
-
- /* 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;
-
- if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
- return WERR_NOMEM;
-
- if (!construct_printer_info_7(print_hnd, printer, snum)) {
- result = WERR_NOMEM;
- goto out;
- }
+/********************************************************************
+ * fill a spoolss_DriverInfo3 struct
+ ********************************************************************/
- /* check the required size. */
- *needed += spoolss_size_printer_info_7(printer);
+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 (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ r->version = driver->info_3->cversion;
+
+ 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 (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);
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;
}
/********************************************************************
* 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);
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;
}
/********************************************************************
* 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;
#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;
}
/********************************************************************
* 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;
}
}
- 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;
+ return status;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinterDriver2
+****************************************************************/
-static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
+ struct spoolss_GetPrinterDriver2 *r)
{
- 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;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
-{
- 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;
+ }
+
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
}
- return WERR_UNKNOWN_LEVEL;
+ *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);
}
}
/****************************************************************************
+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;
- 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->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);
- make_systemtime(&job_info->submitted, t);
+ r->status = nt_printj_status(queue->status);
+ r->priority = queue->priority;
+ r->position = position;
+ r->total_pages = queue->page_count;
+ r->pages_printed = 0; /* ??? */
+
+ 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, "");
-
-/* and here the security descriptor */
+ 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; /* ??? */
- 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);
}
/****************************************************************
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)
+{
+ r->form_name = talloc_strdup(mem_ctx, form->name);
+ W_ERROR_HAVE_NO_MEMORY(r->form_name);
+
+ 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)
{
- form->form_name = talloc_strdup(mem_ctx, list->name);
- W_ERROR_HAVE_NO_MEMORY(form->form_name);
+ 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;
+ }
- 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;
+ *info_p = info;
return WERR_OK;
}
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 */
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;
}
/****************************************************************
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);
}
/****************************************************************************
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;
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;
}
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);
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinterData
+****************************************************************/
-WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
+WERROR _spoolss_EnumPrinterData(pipes_struct *p,
+ struct spoolss_EnumPrinterData *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 idx = q_u->index;
- uint32 in_value_len = q_u->valuesize;
- uint32 in_data_len = q_u->datasize;
- uint32 *out_max_value_len = &r_u->valuesize;
- uint16 **out_value = &r_u->value;
- uint32 *out_value_len = &r_u->realvaluesize;
- uint32 *out_type = &r_u->type;
- uint32 *out_max_data_len = &r_u->datasize;
- uint8 **data_out = &r_u->data;
- uint32 *out_data_len = &r_u->realdatasize;
-
NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- uint32 biggest_valuesize;
- uint32 biggest_datasize;
- uint32 data_len;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
int snum;
WERROR result;
REGISTRY_VALUE *val = NULL;
int i, key_index, num_values;
int name_length;
- *out_type = 0;
-
- *out_max_data_len = 0;
- *data_out = NULL;
- *out_data_len = 0;
+ *r->out.value_needed = 0;
+ *r->out.type = REG_NONE;
+ *r->out.data_needed = 0;
- DEBUG(5,("spoolss_enumprinterdata\n"));
+ DEBUG(5,("_spoolss_EnumPrinterData\n"));
if (!Printer) {
- DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(r->in.handle)));
return WERR_BADFID;
}
- if (!get_printer_snum(p,handle, &snum, NULL))
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(result))
+ if (!W_ERROR_IS_OK(result)) {
return result;
+ }
p_data = printer->info_2->data;
key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
* cf: MSDN EnumPrinterData remark section
*/
- if ( !in_value_len && !in_data_len && (key_index != -1) )
- {
- DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
+ if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
- biggest_valuesize = 0;
- biggest_datasize = 0;
+ uint32_t biggest_valuesize = 0;
+ uint32_t biggest_datasize = 0;
+
+ DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
num_values = regval_ctr_numvals( p_data->keys[key_index].values );
/* the value is an UNICODE string but real_value_size is the length
in bytes including the trailing 0 */
- *out_value_len = 2 * (1+biggest_valuesize);
- *out_data_len = biggest_datasize;
+ *r->out.value_needed = 2 * (1 + biggest_valuesize);
+ *r->out.data_needed = biggest_datasize;
- DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
+ DEBUG(6,("final values: [%d], [%d]\n",
+ *r->out.value_needed, *r->out.data_needed));
goto done;
}
* that's the number of bytes not the number of unicode chars
*/
- if ( key_index != -1 )
- val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
+ if (key_index != -1) {
+ val = regval_ctr_specific_value(p_data->keys[key_index].values,
+ r->in.enum_index);
+ }
- if ( !val )
- {
+ if (!val) {
/* out_value should default to "" or else NT4 has
problems unmarshalling the response */
- *out_max_value_len=(in_value_len/sizeof(uint16));
-
- if (in_value_len) {
- if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
- {
+ if (r->in.value_offered) {
+ *r->out.value_needed = 1;
+ r->out.value_name = talloc_strdup(r, "");
+ if (!r->out.value_name) {
result = WERR_NOMEM;
goto done;
}
- *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
} else {
- *out_value=NULL;
- *out_value_len = 0;
+ r->out.value_name = NULL;
+ *r->out.value_needed = 0;
}
/* the data is counted in bytes */
- *out_max_data_len = in_data_len;
- *out_data_len = in_data_len;
-
- /* only allocate when given a non-zero data_len */
-
- if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
- {
- result = WERR_NOMEM;
- goto done;
- }
+ *r->out.data_needed = r->in.data_offered;
result = WERR_NO_MORE_ITEMS;
- }
- else
- {
+ } else {
/*
* the value is:
* - counted in bytes in the request
*/
/* name */
- *out_max_value_len=(in_value_len/sizeof(uint16));
- if (in_value_len) {
- if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
- {
+ if (r->in.value_offered) {
+ r->out.value_name = talloc_strdup(r, regval_name(val));
+ if (!r->out.value_name) {
result = WERR_NOMEM;
goto done;
}
-
- *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
+ *r->out.value_needed = strlen_m(regval_name(val));
} else {
- *out_value = NULL;
- *out_value_len = 0;
+ r->out.value_name = NULL;
+ *r->out.value_needed = 0;
}
/* type */
- *out_type = regval_type( val );
+ *r->out.type = regval_type(val);
/* data - counted in bytes */
- *out_max_data_len = in_data_len;
- if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
- {
- result = WERR_NOMEM;
- goto done;
+ if (r->out.data && regval_size(val)) {
+ memcpy(r->out.data, regval_data_p(val), regval_size(val));
}
- data_len = regval_size(val);
- if ( *data_out && data_len )
- memcpy( *data_out, regval_data_p(val), data_len );
- *out_data_len = data_len;
+
+ *r->out.data_needed = regval_size(val);
}
done:
return result;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_SetPrinterData
+****************************************************************/
-WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
+WERROR _spoolss_SetPrinterData(pipes_struct *p,
+ struct spoolss_SetPrinterData *r)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *value = &q_u->value;
- uint32 type = q_u->type;
- uint8 *data = q_u->data;
- uint32 real_len = q_u->real_len;
-
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- WERROR status = WERR_OK;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- fstring valuename;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int snum=0;
+ WERROR result = WERR_OK;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+ DATA_BLOB blob;
- DEBUG(5,("spoolss_setprinterdata\n"));
+ DEBUG(5,("_spoolss_SetPrinterData\n"));
if (!Printer) {
- DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_SetPrinterData: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(r->in.handle)));
return WERR_BADFID;
}
- if ( Printer->printer_type == SPLHND_SERVER ) {
- DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
+ if (Printer->printer_type == SPLHND_SERVER) {
+ DEBUG(10,("_spoolss_SetPrinterData: "
+ "Not implemented for server handles yet\n"));
return WERR_INVALID_PARAM;
}
- if (!get_printer_snum(p,handle, &snum, NULL))
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
/*
* Access check : NT returns "access denied" if you make a
* when connecting to a printer --jerry
*/
- if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
- {
- DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
- status = WERR_ACCESS_DENIED;
+ if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
+ DEBUG(3,("_spoolss_SetPrinterData: "
+ "change denied by handle access permissions\n"));
+ result = WERR_ACCESS_DENIED;
goto done;
}
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
- return status;
+ result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
- unistr2_to_ascii(valuename, value, sizeof(valuename));
+ result = push_spoolss_PrinterData(p->mem_ctx, &blob,
+ r->in.type, &r->in.data);
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
/*
* When client side code sets a magic printer data key, detect it and save
* the current printer data and the magic key's data (its the DEVMODE) for
* future printer/driver initializations.
*/
- if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
- {
+ if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
/* Set devmode and printer initialization info */
- status = save_driver_init( printer, 2, data, real_len );
+ result = save_driver_init(printer, 2, blob.data, blob.length);
- srv_spoolss_reset_printerdata( printer->info_2->drivername );
+ srv_spoolss_reset_printerdata(printer->info_2->drivername);
+
+ goto done;
}
- else
- {
- status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
- type, data, real_len );
- if ( W_ERROR_IS_OK(status) )
- status = mod_a_printer(printer, 2);
+
+ result = set_printer_dataex(printer, SPOOL_PRINTERDATA_KEY,
+ r->in.value_name, r->in.type,
+ blob.data, blob.length);
+ if (W_ERROR_IS_OK(result)) {
+ result = mod_a_printer(printer, 2);
}
done:
free_a_printer(&printer, 2);
- return status;
+ return result;
}
/****************************************************************
*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)
-{
- 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;
- }
-
- for (i=0; i<count && found==False; i++) {
- if ((*queue)[i].job==(int)jobid)
- found=True;
- }
-
- if (found==False) {
- SAFE_FREE(info_1);
- /* NT treats not found as bad param... yet another bad choice */
- return WERR_INVALID_PARAM;
- }
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+}
- fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
+/****************************************************************************
+****************************************************************************/
- *needed += spoolss_size_job_info_1(info_1);
+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;
- if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ for (i=0; i<count && found == false; i++) {
+ if (queue[i].job == (int)jobid) {
+ found = true;
+ }
}
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ if (found == false) {
+ /* NT treats not found as bad param... yet another bad choice */
+ return WERR_INVALID_PARAM;
}
- 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;
}
/*
* 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;
/* 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);
+
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ return result;
+ }
- return wstatus;
+ *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);
}
/****************************************************************
WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
struct spoolss_GetPrinterDataEx *r)
{
- POLICY_HND *handle = r->in.handle;
- uint8 *data = NULL;
- const char *keyname = r->in.key_name;
- const char *valuename = r->in.value_name;
-
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+ REGISTRY_VALUE *val = NULL;
NT_PRINTER_INFO_LEVEL *printer = NULL;
int snum = 0;
- WERROR status = WERR_OK;
+ WERROR result = WERR_OK;
DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
- keyname, valuename));
+ r->in.key_name, r->in.value_name));
/* in case of problem, return some default values */
*r->out.needed = 0;
- *r->out.type = 0;
+ *r->out.type = REG_NONE;
if (!Printer) {
- DEBUG(2,("_spoolss_GetPrinterDataEx: "
- "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- status = WERR_BADFID;
+ DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(r->in.handle)));
+ result = WERR_BADFID;
goto done;
}
if (Printer->printer_type == SPLHND_SERVER) {
DEBUG(10,("_spoolss_GetPrinterDataEx: "
"Not implemented for server handles yet\n"));
- status = WERR_INVALID_PARAM;
+ result = WERR_INVALID_PARAM;
goto done;
}
- if ( !get_printer_snum(p,handle, &snum, NULL) )
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
- status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
- if ( !W_ERROR_IS_OK(status) )
+ result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
goto done;
+ }
/* check to see if the keyname is valid */
- if ( !strlen(keyname) ) {
- status = WERR_INVALID_PARAM;
+ if (!strlen(r->in.key_name)) {
+ result = WERR_INVALID_PARAM;
goto done;
}
- if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
+ if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
DEBUG(4,("_spoolss_GetPrinterDataEx: "
- "Invalid keyname [%s]\n", keyname ));
- free_a_printer( &printer, 2 );
- status = WERR_BADFILE;
+ "Invalid keyname [%s]\n", r->in.key_name ));
+ result = WERR_BADFILE;
goto done;
}
/* When given a new keyname, we should just create it */
- status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
- r->out.type, &data, r->out.needed,
- r->in.offered );
+ val = get_printer_data(printer->info_2,
+ r->in.key_name, r->in.value_name);
+ if (!val) {
+ result = WERR_BADFILE;
+ goto done;
+ }
+
+ *r->out.needed = regval_size(val);
if (*r->out.needed > r->in.offered) {
- status = WERR_MORE_DATA;
+ result = WERR_MORE_DATA;
+ goto done;
}
- if (W_ERROR_IS_OK(status)) {
- memcpy(r->out.buffer, data, r->in.offered);
- }
+ *r->out.type = regval_type(val);
-done:
- if ( printer )
- free_a_printer( &printer, 2 );
+ memcpy(r->out.buffer, regval_data_p(val), regval_size(val));
- return status;
+ done:
+ if (printer) {
+ free_a_printer(&printer, 2);
+ }
+
+ return result;
}
/****************************************************************
WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
struct spoolss_SetPrinterDataEx *r)
{
- POLICY_HND *handle = r->in.handle;
NT_PRINTER_INFO_LEVEL *printer = NULL;
int snum = 0;
- WERROR status = WERR_OK;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ WERROR result = WERR_OK;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
char *oid_string;
DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
SetPrinterData if key is "PrinterDriverData" */
if (!Printer) {
- DEBUG(2,("_spoolss_SetPrinterDataEx: "
- "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(r->in.handle)));
return WERR_BADFID;
}
- if ( Printer->printer_type == SPLHND_SERVER ) {
+ if (Printer->printer_type == SPLHND_SERVER) {
DEBUG(10,("_spoolss_SetPrinterDataEx: "
"Not implemented for server handles yet\n"));
return WERR_INVALID_PARAM;
}
- if ( !get_printer_snum(p,handle, &snum, NULL) )
+ if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID;
+ }
/*
* Access check : NT returns "access denied" if you make a
* when connecting to a printer --jerry
*/
- if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
- {
+ if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
DEBUG(3, ("_spoolss_SetPrinterDataEx: "
"change denied by handle access permissions\n"));
return WERR_ACCESS_DENIED;
}
- status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(status))
- return status;
+ result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
/* check for OID in valuename */
- if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
- {
+ oid_string = strchr(r->in.value_name, ',');
+ if (oid_string) {
*oid_string = '\0';
oid_string++;
}
/* save the registry data */
- status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
- r->in.type, r->in.buffer, r->in.offered );
+ result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
+ r->in.type, r->in.buffer, r->in.offered);
- if ( W_ERROR_IS_OK(status) )
- {
+ if (W_ERROR_IS_OK(result)) {
/* save the OID if one was specified */
- if ( oid_string ) {
+ if (oid_string) {
char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
r->in.key_name, SPOOL_OID_KEY);
if (!str) {
- return WERR_NOMEM;
+ result = WERR_NOMEM;
+ goto done;
}
/*
* this is right. --jerry
*/
- set_printer_dataex( printer, str, r->in.value_name,
- REG_SZ, (uint8 *)oid_string,
- strlen(oid_string)+1 );
+ set_printer_dataex(printer, str, r->in.value_name,
+ REG_SZ, (uint8_t *)oid_string,
+ strlen(oid_string)+1);
}
- status = mod_a_printer(printer, 2);
+ result = mod_a_printer(printer, 2);
}
+ done:
free_a_printer(&printer, 2);
- return status;
+ return result;
}
/****************************************************************
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;
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;
}
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);
}
/*******************************************************************
return WERR_OK;
}
-/****************************************************************
- _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
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _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
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_GetPrinterData
-****************************************************************/
-
-WERROR _spoolss_GetPrinterData(pipes_struct *p,
- struct spoolss_GetPrinterData *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_SetPrinterData
-****************************************************************/
-
-WERROR _spoolss_SetPrinterData(pipes_struct *p,
- struct spoolss_SetPrinterData *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_WaitForPrinterChange
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_GetPrinterDriver2
-****************************************************************/
-
-WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
- struct spoolss_GetPrinterDriver2 *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_FindFirstPrinterChangeNotification
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_EnumPrinterData
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterData(pipes_struct *p,
- struct spoolss_EnumPrinterData *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_4a
****************************************************************/