summaryrefslogtreecommitdiff
path: root/source3/rpc_parse/parse_spoolss.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_parse/parse_spoolss.c')
-rw-r--r--source3/rpc_parse/parse_spoolss.c744
1 files changed, 628 insertions, 116 deletions
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index e9f0ca858a..b10a5c4377 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -4,8 +4,8 @@
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
* Copyright (C) Jean François Micouleau 1998-2000,
- * Copyright (C) Gerald Carter 2000-2002
- * Copyright (C) Tim Potter 2001.
+ * Copyright (C) Gerald Carter 2000-2002,
+ * Copyright (C) Tim Potter 2001-2002.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +24,9 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
/*******************************************************************
return the length of a UNISTR string.
********************************************************************/
@@ -45,7 +48,7 @@ static uint32 str_len_uni(UNISTR *source)
This should be moved in a more generic lib.
********************************************************************/
-static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
+BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
{
if(!prs_uint16("year", ps, depth, &systime->year))
return False;
@@ -321,53 +324,64 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs
{
uint32 useless_ptr=0xADDE0FF0;
- uint32 how_many_words;
- BOOL isvalue;
- uint32 x;
-
prs_debug(ps, depth, desc, "smb_io_notify_info_data");
depth++;
- how_many_words=data->size;
- if (how_many_words==POINTER) {
- how_many_words=TWO_VALUE;
- }
-
- isvalue=data->enc_type;
-
if(!prs_align(ps))
return False;
if(!prs_uint16("type", ps, depth, &data->type))
return False;
if(!prs_uint16("field", ps, depth, &data->field))
return False;
- /*prs_align(ps);*/
- if(!prs_uint32("how many words", ps, depth, &how_many_words))
+ if(!prs_uint32("how many words", ps, depth, &data->size))
return False;
if(!prs_uint32("id", ps, depth, &data->id))
return False;
- if(!prs_uint32("how many words", ps, depth, &how_many_words))
+ if(!prs_uint32("how many words", ps, depth, &data->size))
return False;
+ switch (data->enc_type) {
+
+ /* One and two value data has two uint32 values */
- /*prs_align(ps);*/
+ case NOTIFY_ONE_VALUE:
+ case NOTIFY_TWO_VALUE:
- if (isvalue==True) {
if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
return False;
if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
return False;
- /*prs_align(ps);*/
- } else {
- /* it's a string */
- /* length in ascii including \0 */
- x=2*(data->notify_data.data.length+1);
- if(!prs_uint32("string length", ps, depth, &x ))
+ break;
+
+ /* Pointers and strings have a string length and a
+ pointer. For a string the length is expressed as
+ the number of uint16 characters plus a trailing
+ \0\0. */
+
+ case NOTIFY_POINTER:
+
+ if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
return False;
if(!prs_uint32("pointer", ps, depth, &useless_ptr))
return False;
- /*prs_align(ps);*/
+
+ break;
+
+ case NOTIFY_STRING:
+
+ if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
+ return False;
+
+ if(!prs_uint32("pointer", ps, depth, &useless_ptr))
+ return False;
+
+ break;
+
+ default:
+ DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
+ data->enc_type));
+ break;
}
return True;
@@ -380,22 +394,79 @@ reads or writes an NOTIFY INFO DATA structure.
BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
prs_struct *ps, int depth)
{
- uint32 x;
- BOOL isvalue;
-
prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
depth++;
if(!prs_align(ps))
return False;
- isvalue=data->enc_type;
+ switch(data->enc_type) {
+
+ /* No data for values */
+
+ case NOTIFY_ONE_VALUE:
+ case NOTIFY_TWO_VALUE:
+
+ break;
+
+ /* Strings start with a length in uint16s */
+
+ case NOTIFY_STRING:
+
+ if (UNMARSHALLING(ps)) {
+ data->notify_data.data.string =
+ (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
+
+ if (!data->notify_data.data.string)
+ return False;
+ }
+
+ if (MARSHALLING(ps))
+ data->notify_data.data.length /= 2;
+
+ if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
+ return False;
+
+ if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
+ data->notify_data.data.length))
+ return False;
+
+ if (MARSHALLING(ps))
+ data->notify_data.data.length *= 2;
+
+ break;
+
+ case NOTIFY_POINTER:
+
+ if (UNMARSHALLING(ps)) {
+ data->notify_data.data.string =
+ (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
+
+ if (!data->notify_data.data.string)
+ return False;
+ }
+
+ if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
+ return False;
+
+ break;
+
+ default:
+ DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
+ data->enc_type));
+ break;
+ }
+#if 0
if (isvalue==False) {
+
/* length of string in unicode include \0 */
x=data->notify_data.data.length+1;
+
+ if (data->field != 16)
if(!prs_uint32("string length", ps, depth, &x ))
return False;
+
if (MARSHALLING(ps)) {
/* These are already in little endian format. Don't byte swap. */
if (x == 1) {
@@ -409,6 +480,10 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2))
return False;
} else {
+
+ if (data->field == 16)
+ x /= 2;
+
if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
return False;
}
@@ -424,10 +499,11 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
return False;
}
}
-#if 0 /* JERRY */
- /* Win2k does not seem to put this parse align here */
+#endif
+#if 0 /* JERRY */
+ /* Win2k does not seem to put this parse align here */
if(!prs_align(ps))
return False;
#endif
@@ -546,8 +622,40 @@ static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps,
* on reading allocate memory for the private member
********************************************************************/
+#define DM_NUM_OPTIONAL_FIELDS 8
+
BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
+ uint32 available_space; /* size of the device mode left to parse */
+ /* only important on unmarshalling */
+ int i = 0;
+
+ struct optional_fields {
+ fstring name;
+ uint32* field;
+ } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
+ { "icmmethod", NULL },
+ { "icmintent", NULL },
+ { "mediatype", NULL },
+ { "dithertype", NULL },
+ { "reserved1", NULL },
+ { "reserved2", NULL },
+ { "panningwidth", NULL },
+ { "panningheight", NULL }
+ };
+
+ /* assign at run time to keep non-gcc vompilers happy */
+
+ opt_fields[0].field = &devmode->icmmethod;
+ opt_fields[1].field = &devmode->icmintent;
+ opt_fields[2].field = &devmode->mediatype;
+ opt_fields[3].field = &devmode->dithertype;
+ opt_fields[4].field = &devmode->reserved1;
+ opt_fields[5].field = &devmode->reserved2;
+ opt_fields[6].field = &devmode->panningwidth;
+ opt_fields[7].field = &devmode->panningheight;
+
+
prs_debug(ps, depth, desc, "spoolss_io_devmode");
depth++;
@@ -559,8 +667,27 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, 32))
return False;
+
if (!prs_uint16("specversion", ps, depth, &devmode->specversion))
return False;
+
+ /* Sanity Check - look for unknown specversions, but don't fail if we see one.
+ Let the size determine that */
+
+ switch (devmode->specversion) {
+ case 0x0320:
+ case 0x0400:
+ case 0x0401:
+ break;
+
+ default:
+ DEBUG(0,("spoolss_io_devmode: Unknown specversion in devicemode [0x%x]\n",
+ devmode->specversion));
+ DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
+ break;
+ }
+
+
if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion))
return False;
if (!prs_uint16("size", ps, depth, &devmode->size))
@@ -616,45 +743,50 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
return False;
if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
return False;
+ /*
+ * every device mode I've ever seen on the wire at least has up
+ * to the displayfrequency field. --jerry (05-09-2002)
+ */
+
+ /* add uint32's + uint16's + two UNICODE strings */
+
+ available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
+
+ /* Sanity check - we only have uint32's left tp parse */
+
+ if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
+ DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
+ available_space, devmode->size));
+ DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
+ return False;
+ }
/*
* Conditional parsing. Assume that the DeviceMode has been
* zero'd by the caller.
*/
- switch(devmode->specversion) {
- /* Used by spooler when issuing OpenPrinter() calls. NT 3.5x? */
- case 0x0320:
- break;
+ while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
+ {
+ DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
+ if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
+ return False;
+ available_space -= sizeof(uint32);
+ i++;
+ }
+
+ /* Sanity Check - we should no available space at this point unless
+ MS changes the device mode structure */
- /* See the comments on the DEVMODE in the msdn GDI documentation */
- case 0x0400:
- case 0x0401:
- if (!prs_uint32("icmmethod", ps, depth, &devmode->icmmethod))
- return False;
- if (!prs_uint32("icmintent", ps, depth, &devmode->icmintent))
- return False;
- if (!prs_uint32("mediatype", ps, depth, &devmode->mediatype))
- return False;
- if (!prs_uint32("dithertype", ps, depth, &devmode->dithertype))
- return False;
- if (!prs_uint32("reserved1", ps, depth, &devmode->reserved1))
- return False;
- if (!prs_uint32("reserved2", ps, depth, &devmode->reserved2))
+ if (available_space) {
+ DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
+ DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
+ available_space, devmode->size));
+ DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
return False;
- if (!prs_uint32("panningwidth", ps, depth, &devmode->panningwidth))
- return False;
- if (!prs_uint32("panningheight", ps, depth, &devmode->panningheight))
- return False;
- break;
-
- /* log an error if we see something else */
- default:
- DEBUG(0,("spoolss_io_devmode: Unknown specversion [0x%x]!\n", devmode->specversion));
- DEBUG(0,("spoolss_io_devmode: Please report to samba-technical@samba.org\n"));
- break;
}
+
if (devmode->driverextra!=0) {
if (UNMARSHALLING(ps)) {
devmode->private=(uint8 *)prs_alloc_mem(ps, devmode->driverextra*sizeof(uint8));
@@ -900,6 +1032,7 @@ BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2
return True;
}
+
/*******************************************************************
* read a structure.
* called from spoolss_q_open_printer_ex (srv_spoolss.c)
@@ -1047,15 +1180,15 @@ BOOL make_spoolss_q_deleteprinterdriver(
********************************************************************/
BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
- const POLICY_HND *handle,
- UNISTR2 *valuename, uint32 size)
+ const POLICY_HND *handle,
+ char *valuename, uint32 size)
{
if (q_u == NULL) return False;
DEBUG(5,("make_spoolss_q_getprinterdata\n"));
q_u->handle = *handle;
- copy_unistr2(&q_u->valuename, valuename);
+ init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1);
q_u->size = size;
return True;
@@ -1131,6 +1264,48 @@ BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u,
}
/*******************************************************************
+ * read a structure.
+ * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
+ ********************************************************************/
+
+BOOL spoolss_io_q_deleteprinterdataex(char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+ if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("keyname ", &q_u->keyname, True, ps, depth))
+ return False;
+ if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
+ ********************************************************************/
+
+BOOL spoolss_io_r_deleteprinterdataex(char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
+ depth++;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
* write a structure.
* called from spoolss_r_getprinterdata (srv_spoolss.c)
********************************************************************/
@@ -1150,6 +1325,12 @@ BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_st
if (!prs_uint32("size", ps, depth, &r_u->size))
return False;
+ if (UNMARSHALLING(ps) && r_u->size) {
+ r_u->data = prs_alloc_mem(ps, r_u->size);
+ if(r_u->data)
+ return False;
+ }
+
if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
return False;
@@ -1311,6 +1492,64 @@ BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r
}
+/*******************************************************************
+ * read a structure.
+ * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
+ * called from spoolss_deleteprinterdriver (cli_spoolss.c)
+ ********************************************************************/
+
+BOOL spoolss_io_q_deleteprinterdriverex(char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
+ return False;
+ if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
+ return False;
+ if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
+ return False;
+ if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
+ return False;
+ if(!prs_uint32("version ", ps, depth, &q_u->version))
+ return False;
+
+
+ return True;
+}
+
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+BOOL spoolss_io_r_deleteprinterdriverex(char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
/*******************************************************************
* read a structure.
@@ -2072,6 +2311,10 @@ static BOOL smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEM
/* read the offset */
if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
return False;
+ if (buffer->string_at_end == 0) {
+ *devmode = NULL;
+ return True;
+ }
old_offset = prs_offset(ps);
if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
@@ -2222,6 +2465,8 @@ BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info,
BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
+ uint32 dm_offset, sd_offset, current_offset;
+ uint32 dummy_value = 0;
prs_debug(ps, depth, desc, "smb_io_printer_info_2");
depth++;
@@ -2243,8 +2488,9 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info,
if (!smb_io_relstr("location", buffer, depth, &info->location))
return False;
- /* NT parses the DEVMODE at the end of the struct */
- if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
+ /* save current offset and wind forwared by a uint32 */
+ dm_offset = prs_offset(ps);
+ if (!prs_uint32("devmode", ps, depth, &dummy_value))
return False;
if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
@@ -2256,9 +2502,31 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info,
if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
return False;
+ /* save current offset for the sec_desc */
+ sd_offset = prs_offset(ps);
+ if (!prs_uint32("sec_desc", ps, depth, &dummy_value))
+ return False;
+
+
+ /* save current location so we can pick back up here */
+ current_offset = prs_offset(ps);
+
+ /* parse the devmode */
+ if (!prs_set_offset(ps, dm_offset))
+ return False;
+ if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
+ return False;
+
+ /* parse the sec_desc */
+ if (!prs_set_offset(ps, sd_offset))
+ return False;
if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
return False;
+ /* pick up where we left off */
+ if (!prs_set_offset(ps, current_offset))
+ return False;
+
if (!prs_uint32("attributes", ps, depth, &info->attributes))
return False;
if (!prs_uint32("priority", ps, depth, &info->priority))
@@ -2276,13 +2544,6 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info,
if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
return False;
-#if 0 /* JFMTEST */
- if (!prs_uint32_post("secdesc_ptr", ps, depth, NULL, sec_offset, info->secdesc ? prs_offset(ps)-buffer->struct_start : 0 ))
- return False;
-
- if (!sec_io_desc("secdesc", &info->secdesc, ps, depth))
- return False;
-#endif
return True;
}
@@ -3034,7 +3295,7 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
uint32 size=0;
size += 4;
- /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
+
size += sec_desc_size( info->secdesc );
size+=size_of_device_mode( info->devmode );
@@ -3060,6 +3321,16 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
size+=size_of_uint32( &info->status );
size+=size_of_uint32( &info->cjobs );
size+=size_of_uint32( &info->averageppm );
+
+ /*
+ * add any adjustments for alignment. This is
+ * not optimal since we could be calling this
+ * function from a loop (e.g. enumprinters), but
+ * it is easier to maintain the calculation here and
+ * not place the burden on the caller to remember. --jerry
+ */
+ size += size % 4;
+
return size;
}
@@ -3529,7 +3800,7 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
BOOL make_spoolss_q_enumprinters(
SPOOL_Q_ENUMPRINTERS *q_u,
uint32 flags,
- fstring servername,
+ char *servername,
uint32 level,
NEW_BUFFER *buffer,
uint32 offered
@@ -4767,60 +5038,56 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_
if(!prs_align(ps))
return False;
+ /*
+ * I know this seems weird, but I have no other explanation.
+ * This is observed behavior on both NT4 and 2K servers.
+ * --jerry
+ */
+
+ if (!prs_align_uint64(ps))
+ return False;
/* parse the main elements the packet */
- if(!prs_uint32("version", ps, depth, &il->version))
+ if(!prs_uint32("cversion ", ps, depth, &il->version))
return False;
-
- if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
- return False;
- /*
- * If name_ptr is NULL then the next 4 bytes are the name_ptr. A driver
- * with a NULL name just isn't a driver For example: "HP LaserJet 4si"
- * from W2K CDROM (which uses unidriver). JohnR 010205
- */
- if (!il->name_ptr) {
- DEBUG(5,("spool_io_printer_driver_info_level_6: name_ptr is NULL! Get next value\n"));
- if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
- return False;
- }
-
- if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr))
+ if(!prs_uint32("name ", ps, depth, &il->name_ptr))
return False;
- if(!prs_uint32("driverpath_ptr", ps, depth, &il->driverpath_ptr))
+ if(!prs_uint32("environment ", ps, depth, &il->environment_ptr))
return False;
- if(!prs_uint32("datafile_ptr", ps, depth, &il->datafile_ptr))
+ if(!prs_uint32("driverpath ", ps, depth, &il->driverpath_ptr))
return False;
- if(!prs_uint32("configfile_ptr", ps, depth, &il->configfile_ptr))
+ if(!prs_uint32("datafile ", ps, depth, &il->datafile_ptr))
return False;
- if(!prs_uint32("helpfile_ptr", ps, depth, &il->helpfile_ptr))
+ if(!prs_uint32("configfile ", ps, depth, &il->configfile_ptr))
return False;
- if(!prs_uint32("monitorname_ptr", ps, depth, &il->monitorname_ptr))
+ if(!prs_uint32("helpfile ", ps, depth, &il->helpfile_ptr))
return False;
- if(!prs_uint32("defaultdatatype_ptr", ps, depth, &il->defaultdatatype_ptr))
+ if(!prs_uint32("monitorname ", ps, depth, &il->monitorname_ptr))
return False;
- if(!prs_uint32("dependentfiles_len", ps, depth, &il->dependentfiles_len))
+ if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
return False;
- if(!prs_uint32("dependentfiles_ptr", ps, depth, &il->dependentfiles_ptr))
+ if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
return False;
- if(!prs_uint32("previousnames_len", ps, depth, &il->previousnames_len))
+ if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
return False;
- if(!prs_uint32("previousnames_ptr", ps, depth, &il->previousnames_ptr))
+ if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_len))
return False;
- if(!smb_io_time("driverdate", &il->driverdate, ps, depth))
+ if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_ptr))
return False;
- if(!prs_uint32("dummy4", ps, depth, &il->dummy4))
+ if(!smb_io_time("driverdate ", &il->driverdate, ps, depth))
return False;
- if(!prs_uint64("driverversion", ps, depth, &il->driverversion))
+ if(!prs_uint32("dummy4 ", ps, depth, &il->dummy4))
return False;
- if(!prs_uint32("mfgname_ptr", ps, depth, &il->mfgname_ptr))
+ if(!prs_uint64("driverversion ", ps, depth, &il->driverversion))
return False;
- if(!prs_uint32("oemurl_ptr", ps, depth, &il->oemurl_ptr))
+ if(!prs_uint32("mfgname ", ps, depth, &il->mfgname_ptr))
return False;
- if(!prs_uint32("hardwareid_ptr", ps, depth, &il->hardwareid_ptr))
+ if(!prs_uint32("oemurl ", ps, depth, &il->oemurl_ptr))
return False;
- if(!prs_uint32("provider_ptr", ps, depth, &il->provider_ptr))
+ if(!prs_uint32("hardwareid ", ps, depth, &il->hardwareid_ptr))
+ return False;
+ if(!prs_uint32("provider ", ps, depth, &il->provider_ptr))
return False;
/* parse the structures in the packet */
@@ -5147,6 +5414,53 @@ BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, pr
}
/*******************************************************************
+ fill in the prs_struct for a ADDPRINTERDRIVER request PDU
+ ********************************************************************/
+
+BOOL spoolss_io_q_addprinterdriverex(char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
+ return False;
+ if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("info_level", ps, depth, &q_u->level))
+ return False;
+
+ if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL spoolss_io_r_addprinterdriverex(char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
+ depth++;
+
+ if(!prs_werror("status", ps, depth, &q_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
********************************************************************/
BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
@@ -5653,6 +5967,14 @@ BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_
if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
return False;
+ if (UNMARSHALLING(ps) && r_u->valuesize) {
+ r_u->value = (uint16 *)prs_alloc_mem(ps, r_u->valuesize * 2);
+ if (!r_u->value) {
+ DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
+ return False;
+ }
+ }
+
if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
return False;
@@ -5667,6 +5989,15 @@ BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_
if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
return False;
+
+ if (UNMARSHALLING(ps) && r_u->datasize) {
+ r_u->data = (uint8 *)prs_alloc_mem(ps, r_u->datasize);
+ if (!r_u->data) {
+ DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
+ return False;
+ }
+ }
+
if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
return False;
if(!prs_align(ps))
@@ -5719,19 +6050,15 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
/*******************************************************************
********************************************************************/
-BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd,
- char* value, char* data)
+BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
+ char* value, char* data, uint32 data_size)
{
- UNISTR2 tmp;
-
memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
q_u->type = REG_SZ;
init_unistr2(&q_u->value, value, strlen(value)+1);
- init_unistr2(&tmp, data, strlen(data)+1);
- q_u->max_len = q_u->real_len = tmp.uni_max_len*2;
- q_u->data = talloc(ctx, q_u->real_len);
- memcpy(q_u->data, tmp.buffer, q_u->real_len);
+ q_u->max_len = q_u->real_len = data_size;
+ q_u->data = data;
return True;
}
@@ -6696,6 +7023,44 @@ BOOL spoolss_io_r_enumprinterkey(char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_st
return True;
}
+/*******************************************************************
+ * read a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_q_deleteprinterkey(char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_r_deleteprinterkey(char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
/*******************************************************************
* read a structure.
@@ -7016,3 +7381,150 @@ BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
return True;
}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle,
+ uint32 jobid, uint32 level, uint32 command)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+ q_u->jobid = jobid;
+ q_u->level = level;
+
+ /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
+ the server side code has it marked as unused. */
+
+ q_u->command = command;
+
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
+ uint32 jobid, uint32 level, NEW_BUFFER *buffer,
+ uint32 offered)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+ q_u->jobid = jobid;
+ q_u->level = level;
+ q_u->buffer = buffer;
+ q_u->offered = offered;
+
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u,
+ POLICY_HND *handle)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u,
+ POLICY_HND *handle)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u,
+ POLICY_HND *handle, uint32 level,
+ char *docname, char *outputfile,
+ char *datatype)
+{
+ DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
+
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+
+ ctr->level = level;
+
+ switch (level) {
+ case 1:
+ ctr->docinfo.switch_value = level;
+
+ ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
+ ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
+ ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
+
+ if (docname)
+ init_unistr2(&ctr->docinfo.doc_info_1.docname, docname,
+ strlen(docname) + 1);
+
+ if (outputfile)
+ init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile,
+ strlen(outputfile) + 1);
+
+ if (datatype)
+ init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype,
+ strlen(datatype) + 1);
+
+ break;
+ case 2:
+ /* DOC_INFO_2 is only used by Windows 9x and since it
+ doesn't do printing over RPC we don't have to worry
+ about it. */
+ default:
+ DEBUG(3, ("unsupported info level %d\n", level));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u,
+ POLICY_HND *handle)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u,
+ POLICY_HND *handle, uint32 data_size,
+ char *data)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+ q_u->buffer_size = q_u->buffer_size2 = data_size;
+ q_u->buffer = data;
+ return True;
+}
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u,
+ POLICY_HND *handle, char *valuename)
+{
+ memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+ init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1);
+
+ return True;
+}