/*
Unix SMB/CIFS implementation.
functions to calculate the free disk space
Copyright (C) Andrew Tridgell 1998-2000
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* 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-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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
/*******************************************************************
This should be moved in a more generic lib.
********************************************************************/
bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
{
if(!prs_uint16("year", ps, depth, &systime->year))
return False;
if(!prs_uint16("month", ps, depth, &systime->month))
return False;
if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
return False;
if(!prs_uint16("day", ps, depth, &systime->day))
return False;
if(!prs_uint16("hour", ps, depth, &systime->hour))
return False;
if(!prs_uint16("minute", ps, depth, &systime->minute))
return False;
if(!prs_uint16("second", ps, depth, &systime->second))
return False;
if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
return False;
return True;
}
/*******************************************************************
********************************************************************/
bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
{
systime->year=unixtime->tm_year+1900;
systime->month=unixtime->tm_mon+1;
systime->dayofweek=unixtime->tm_wday;
systime->day=unixtime->tm_mday;
systime->hour=unixtime->tm_hour;
systime->minute=unixtime->tm_min;
systime->second=unixtime->tm_sec;
systime->milliseconds=0;
return True;
}
/*******************************************************************
reads or writes an DOC_INFO structure.
********************************************************************/
static bool smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
{
if (info_1 == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_doc_info_1");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("p_docname", ps, depth, &info_1->p_docname))
return False;
if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
return False;
if(!prs_uint32("p_datatype", ps, depth, &info_1->p_datatype))
return False;
if(!smb_io_unistr2("", &info_1->docname, info_1->p_docname, ps, depth))
return False;
if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
return False;
if(!smb_io_unistr2("", &info_1->datatype, info_1->p_datatype, ps, depth))
return False;
return True;
}
/*******************************************************************
reads or writes an DOC_INFO structure.
********************************************************************/
static bool smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
{
uint32 useless_ptr=0;
if (info == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_doc_info");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
return False;
if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
return False;
switch (info->switch_value)
{
case 1:
if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
return False;
break;
case 2:
/*
this is just a placeholder
MSDN July 1998 says doc_info_2 is only on
Windows 95, and as Win95 doesn't do RPC to print
this case is nearly impossible
Maybe one day with Windows for dishwasher 2037 ...
*/
/* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
break;
default:
DEBUG(0,("Something is obviously wrong somewhere !\n"));
break;
}
return True;
}
/*******************************************************************
reads or writes an DOC_INFO_CONTAINER structure.
********************************************************************/
static bool smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
{
if (cont == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_doc_info_container");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("level", ps, depth, &cont->level))
return False;
if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
return False;
return True;
}
/*******************************************************************
reads or writes an NOTIFY OPTION TYPE structure.
********************************************************************/
/* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
structure. The _TYPE structure is really the deferred referrants (i.e
the notify fields array) of the _TYPE structure. -tpot */
static bool smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "smb_io_notify_option_type");
depth++;
if (!prs_align(ps))
return False;
if(!prs_uint16("type", ps, depth, &type->type))
return False;
if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
return False;
if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
return False;
if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
return False;
if(!prs_uint32("count", ps, depth, &type->count))
return False;
if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
return False;
return True;
}
/*******************************************************************
reads or writes an NOTIFY OPTION TYPE DATA.
********************************************************************/
static bool smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
{
int i;
prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
depth++;
/* if there are no fields just return */
if (type->fields_ptr==0)
return True;
if(!prs_align(ps))
return False;
if(!prs_uint32("count2", ps, depth, &type->count2))
return False;
if (type->count2 != type->count)
DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) {
return False;
}
/* parse the option type data */
for(i=0;i<type->count2;i++)
if(!prs_uint16("fields",ps,depth,&type->fields[i]))
return False;
return True;
}
/*******************************************************************
reads or writes an NOTIFY OPTION structure.
********************************************************************/
static bool smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
{
int i;
prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
depth++;
if(!prs_uint32("count", ps, depth, &ctr->count))
return False;
/* reading */
if (UNMARSHALLING(ps) && ctr->count)
if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
return False;
/* the option type struct */
for(i=0;i<ctr->count;i++)
if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
return False;
/* the type associated with the option type struct */
for(i=0;i<ctr->count;i++)
if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
return False;
return True;
}
/*******************************************************************
reads or writes an NOTIFY OPTION structure.
********************************************************************/
static bool smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "smb_io_notify_option");
depth++;
if(!prs_uint32("version", ps, depth, &option->version))
return False;
if(!prs_uint32("flags", ps, depth, &option->flags))
return False;
if(!prs_uint32("count", ps, depth, &option->count))
return False;
if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
return False;
/* marshalling or unmarshalling, that would work */
if (option->option_type_ptr!=0) {
if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
return False;
}
else {
option->ctr.type=NULL;
option->ctr.count=0;
}
return True;
}
/*******************************************************************
reads or writes an NOTIFY INFO DATA structure.
********************************************************************/
static bool smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
{
uint32 useless_ptr=0x0FF0ADDE;
prs_debug(ps, depth, desc, "smb_io_notify_info_data");
depth++;
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;
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, &data->size))
return False;
switch (data->enc_type) {
/* One and two value data has two uint32 values */
case NOTIFY_ONE_VALUE:
case NOTIFY_TWO_VALUE:
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;
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;
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;
case NOTIFY_SECDESC:
if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
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;
}
/*******************************************************************
reads or writes an NOTIFY INFO DATA structure.
********************************************************************/
bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
depth++;
if(!prs_align(ps))
return False;
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 (MARSHALLING(ps))
data->notify_data.data.length /= 2;
if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
return False;
if (UNMARSHALLING(ps) && data->notify_data.data.length) {
data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
data->notify_data.data.length);
if (!data->notify_data.data.string)
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.length) {
data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
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;
case NOTIFY_SECDESC:
if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
return False;
if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
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) {
/* No memory allocated for this string
therefore following the data.string
pointer is a bad idea. Use a pointer to
the uint32 length union member to
provide a source for a unicode NULL */
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;
}
} else {
/* Tallocate memory for string */
if (x) {
data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
if (!data->notify_data.data.string)
return False;
} else {
data->notify_data.data.string = NULL;
}
if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
return False;
}
}
#endif
#if 0 /* JERRY */
/* Win2k does not seem to put this parse align here */
if(!prs_align(ps))
return False;
#endif
return True;
}
/*******************************************************************
reads or writes an NOTIFY INFO structure.
********************************************************************/
static bool smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
{
int i;
prs_debug(ps, depth, desc, "smb_io_notify_info");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("count", ps, depth, &info->count))
return False;
if(!prs_uint32("version", ps, depth, &info->version))
return False;
if(!prs_uint32("flags", ps, depth, &info->flags))
return False;
if(!prs_uint32("count", ps, depth, &info->count))
return False;
for (i=0;i<info->count;i++) {
if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
return False;
}
/* now do the strings at the end of the stream */
for (i=0;i<info->count;i++) {
if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
return False;
}
return True;
}
/*******************************************************************
********************************************************************/
bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
{
prs_debug(ps, depth, desc, "");
depth++;
if (!prs_align(ps))
return False;
if (!prs_uint32("size", ps, depth, &q_u->size))
return False;
if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
return False;
if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
return False;
if (!prs_uint32("build", ps, depth, &q_u->build))
return False;
if (!prs_uint32("major", ps, depth, &q_u->major))
return False;
if (!prs_uint32("minor", ps, depth, &q_u->minor))
return False;
if (!prs_uint32("processor", ps, depth, &q_u->processor))
return False;
if (!prs_io_unistr2("", ps, depth, q_u->client_name))
return False;
if (!prs_align(ps))
return False;
if (!prs_io_unistr2("", ps, depth, q_u->user_name))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
{
if (q_u==NULL)
return False;
prs_debug(ps, depth, desc, "spool_io_user_level");
depth++;
if (!prs_align(ps))
return False;
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
switch ( q_u->level )
{
case 1:
if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1,
sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 ))
{
return False;
}
break;
default:
return False;
}
return True;
}
/*******************************************************************
* read or write a DEVICEMODE struct.
* on reading allocate memory for the private member
********************************************************************/
#define DM_NUM_OPTIONAL_FIELDS 8
bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
int available_space; /* size of the device mode left to parse */
/* only important on unmarshalling */
int i = 0;
uint16 *unistr_buffer;
int j;
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 compilers 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++;
if (UNMARSHALLING(ps)) {
devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
if (devmode->devicename.buffer == NULL)
return False;
unistr_buffer = devmode->devicename.buffer;
}
else {
/* devicename is a static sized string but the buffer we set is not */
unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
memset( unistr_buffer, 0x0, MAXDEVICENAME );
for ( j=0; devmode->devicename.buffer[j]; j++ )
unistr_buffer[j] = devmode->devicename.buffer[j];
}
if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
return False;
if (!prs_uint16("specversion", ps, depth, &devmode->specversion))
return False;
if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion))
return False;
if (!prs_uint16("size", ps, depth, &devmode->size))
return False;
if (!prs_uint16("driverextra", ps, depth, &devmode->driverextra))
return False;
if (!prs_uint32("fields", ps, depth, &devmode->fields))
return False;
if (!prs_uint16("orientation", ps, depth, &devmode->orientation))
return False;
if (!prs_uint16("papersize", ps, depth, &devmode->papersize))
return False;
if (!prs_uint16("paperlength", ps, depth, &devmode->paperlength))
return False;
if (!prs_uint16("paperwidth", ps, depth, &devmode->paperwidth))
return False;
if (!prs_uint16("scale", ps, depth, &devmode->scale))
return False;
if (!prs_uint16("copies", ps, depth, &devmode->copies))
return False;
if (!prs_uint16("defaultsource", ps, depth, &devmode->defaultsource))
return False;
if (!prs_uint16("printquality", ps, depth, &devmode->printquality))
return False;
if (!prs_uint16("color", ps, depth, &devmode->color))
return False;
if (!prs_uint16("duplex", ps, depth, &devmode->duplex))
return False;
if (!prs_uint16("yresolution", ps, depth, &devmode->yresolution))
return False;
if (!prs_uint16("ttoption", ps, depth, &devmode->ttoption))
return False;
if (!prs_uint16("collate", ps, depth, &devmode->collate))
return False;
if (UNMARSHALLING(ps)) {
devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
if (devmode->formname.buffer == NULL)
return False;
unistr_buffer = devmode->formname.buffer;
}
else {
/* devicename is a static sized string but the buffer we set is not */
unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
memset( unistr_buffer, 0x0, MAXDEVICENAME );
for ( j=0; devmode->formname.buffer[j]; j++ )
unistr_buffer[j] = devmode->formname.buffer[j];
}
if (!prs_uint16uni(True, "formname", ps, depth, unistr_buffer, MAXDEVICENAME))
return False;
if (!prs_uint16("logpixels", ps, depth, &devmode->logpixels))
return False;
if (!prs_uint32("bitsperpel", ps, depth, &devmode->bitsperpel))
return False;
if (!prs_uint32("pelswidth", ps, depth, &devmode->pelswidth))
return False;
if (!prs_uint32("pelsheight", ps, depth, &devmode->pelsheight))
return False;
if (!prs_uint32("displayflags", ps, depth, &devmode->displayflags))
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.
*/
while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
{
DEBUG(11, ("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 */
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 (devmode->driverextra!=0) {
if (UNMARSHALLING(ps)) {
devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
if(devmode->dev_private == NULL)
return False;
DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra));
}
DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
if (!prs_uint8s(False, "dev_private", ps, depth,
devmode->dev_private, devmode->driverextra))
return False;
}
return True;
}
/*******************************************************************
Read or write a DEVICEMODE container
********************************************************************/
static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
{
if (dm_c==NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
depth++;
if(!prs_align(ps))
return False;
if (!prs_uint32("size", ps, depth, &dm_c->size))
return False;
if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
return False;
if (dm_c->size==0 || dm_c->devmode_ptr==0) {
if (UNMARSHALLING(ps))
/* if while reading there is no DEVMODE ... */
dm_c->devmode=NULL;
return True;
}
/* so we have a DEVICEMODE to follow */
if (UNMARSHALLING(ps)) {
DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
if(dm_c->devmode == NULL)
return False;
}
/* this is bad code, shouldn't be there */
if (!prs_uint32("size", ps, depth, &dm_c->size))
return False;
if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static bool spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
{
if (pd==NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_printer_default");
depth++;
if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
return False;
if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
return False;
if (!prs_align(ps))
return False;
if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
return False;
if (!prs_align(ps))
return False;
if (!prs_uint32("access_required", ps, depth, &pd->access_required))
return False;
return True;
}
/*******************************************************************
* init a structure.
********************************************************************/
bool make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
const fstring printername,
const fstring datatype,
uint32 access_required,
const fstring clientname,
const fstring user_name)
{
DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
q_u->printername = TALLOC_P( talloc_tos(), UNISTR2 );
if (!q_u->printername) {
return False;
}
init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
q_u->printer_default.datatype_ptr = 0;
q_u->printer_default.devmode_cont.size=0;
q_u->printer_default.devmode_cont.devmode_ptr=0;
q_u->printer_default.devmode_cont.devmode=NULL;
q_u->printer_default.access_required=access_required;
q_u->user_switch = 1;
q_u->user_ctr.level = 1;
q_u->user_ctr.user.user1 = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
if (!q_u->user_ctr.user.user1) {
return False;
}
q_u->user_ctr.user.user1->size = strlen(clientname) + strlen(user_name) + 10;
q_u->user_ctr.user.user1->build = 1381;
q_u->user_ctr.user.user1->major = 2;
q_u->user_ctr.user.user1->minor = 0;
q_u->user_ctr.user.user1->processor = 0;
q_u->user_ctr.user.user1->client_name = TALLOC_P( talloc_tos(), UNISTR2 );
if (!q_u->user_ctr.user.user1->client_name) {
return False;
}
q_u->user_ctr.user.user1->user_name = TALLOC_P( talloc_tos(), UNISTR2 );
if (!q_u->user_ctr.user.user1->user_name) {
return False;
}
init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
return True;
}
/*******************************************************************
* init a structure.
********************************************************************/
bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u,
const char *srv_name, const char* clientname, const char* user_name,
uint32 level, PRINTER_INFO_CTR *ctr)
{
DEBUG(5,("make_spoolss_q_addprinterex\n"));
if (!ctr || !ctr->printers_2)
return False;
ZERO_STRUCTP(q_u);
q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
if (!q_u->server_name) {
return False;
}
init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
q_u->level = level;
q_u->info.level = level;
q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
switch (level) {
case 2:
/* init q_u->info.info2 from *info */
if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
return False;
}
break;
default :
break;
}
q_u->user_switch=1;
q_u->user_ctr.level = 1;
q_u->user_ctr.user.user1 = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
if (!q_u->user_ctr.user.user1) {
return False;
}
q_u->user_ctr.user.user1->build = 1381;
q_u->user_ctr.user.user1->major = 2;
q_u->user_ctr.user.user1->minor = 0;
q_u->user_ctr.user.user1->processor = 0;
q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
if (!q_u->user_ctr.user.user1->client_name) {
return False;
}
q_u->user_ctr.user.user1->user_name = TALLOC_P( mem_ctx, UNISTR2 );
if (!q_u->user_ctr.user.user1->user_name) {
return False;
}
init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
return True;
}
/*******************************************************************
create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
*******************************************************************/
bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
PRINTER_INFO_2 *info)
{
SPOOL_PRINTER_INFO_LEVEL_2 *inf;
/* allocate the necessary memory */
if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
return False;
}
inf->servername_ptr = (info->servername.buffer!=NULL)?1:0;
inf->printername_ptr = (info->printername.buffer!=NULL)?1:0;
inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0;
inf->portname_ptr = (info->portname.buffer!=NULL)?1:0;
inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0;
inf->comment_ptr = (info->comment.buffer!=NULL)?1:0;
inf->location_ptr = (info->location.buffer!=NULL)?1:0;
inf->devmode_ptr = (info->devmode!=NULL)?1:0;
inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0;
inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0;
inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0;
inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
inf->attributes = info->attributes;
inf->priority = info->priority;
inf->default_priority = info->defaultpriority;
inf->starttime = info->starttime;
inf->untiltime = info->untiltime;
inf->cjobs = info->cjobs;
inf->averageppm = info->averageppm;
init_unistr2_from_unistr(inf, &inf->servername, &info->servername);
init_unistr2_from_unistr(inf, &inf->printername, &info->printername);
init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename);
init_unistr2_from_unistr(inf, &inf->portname, &info->portname);
init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername);
init_unistr2_from_unistr(inf, &inf->comment, &info->comment);
init_unistr2_from_unistr(inf, &inf->location, &info->location);
init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile);
init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor);
init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters);
init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
*spool_info2 = inf;
return True;
}
/*******************************************************************
create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
*******************************************************************/
bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3,
PRINTER_INFO_3 *info)
{
SPOOL_PRINTER_INFO_LEVEL_3 *inf;
/* allocate the necessary memory */
if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
return False;
}
inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
*spool_info3 = inf;
return True;
}
/*******************************************************************
create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
*******************************************************************/
bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7,
PRINTER_INFO_7 *info)
{
SPOOL_PRINTER_INFO_LEVEL_7 *inf;
/* allocate the necessary memory */
if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
return False;
}
inf->guid_ptr = (info->guid.buffer!=NULL)?1:0;
inf->action = info->action;
init_unistr2_from_unistr(inf, &inf->guid, &info->guid);
*spool_info7 = inf;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_open_printer_ex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
depth++;
if (!prs_align(ps))
return False;
if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
return False;
if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
return False;
if (!prs_align(ps))
return False;
if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from static spoolss_r_open_printer_ex (srv_spoolss.c)
* called from spoolss_open_printer_ex (cli_spoolss.c)
********************************************************************/
bool spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
return False;
if (!prs_werror("status code", ps, depth, &(r_u->status)))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_open_printer_ex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
depth++;
if (!prs_align(ps))
return False;
if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
return False;
if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
return False;
if (!prs_align(ps))
return False;
if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
return False;
if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
return False;
if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from static spoolss_r_open_printer_ex (srv_spoolss.c)
* called from spoolss_open_printer_ex (cli_spoolss.c)
********************************************************************/
bool spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
return False;
if (!prs_werror("status code", ps, depth, &(r_u->status)))
return False;
return True;
}
/*******************************************************************
* init a structure.
********************************************************************/
bool make_spoolss_q_deleteprinterdriverex( TALLOC_CTX *mem_ctx,
SPOOL_Q_DELETEPRINTERDRIVEREX *q_u,
const char *server,
const char* arch,
const char* driver,
int version)
{
DEBUG(5,("make_spoolss_q_deleteprinterdriverex\n"));
q_u->server_ptr = (server!=NULL)?1:0;
q_u->delete_flags = DPD_DELETE_UNUSED_FILES;
/* these must be NULL terminated or else NT4 will
complain about invalid parameters --jerry */
init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
if (version >= 0) {
q_u->delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
q_u->version = version;
}
return True;
}
/*******************************************************************
* init a structure.
********************************************************************/
bool make_spoolss_q_deleteprinterdriver(
TALLOC_CTX *mem_ctx,
SPOOL_Q_DELETEPRINTERDRIVER *q_u,
const char *server,
const char* arch,
const char* driver
)
{
DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
q_u->server_ptr = (server!=NULL)?1:0;
/* these must be NULL terminated or else NT4 will
complain about invalid parameters --jerry */
init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
return True;
}
/*******************************************************************
* make a structure.
********************************************************************/
bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
const POLICY_HND *handle,
const char *valuename, uint32 size)
{
if (q_u == NULL) return False;
DEBUG(5,("make_spoolss_q_getprinterdata\n"));
q_u->handle = *handle;
init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
q_u->size = size;
return True;
}
/*******************************************************************
* make a structure.
********************************************************************/
bool make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
const POLICY_HND *handle,
const char *keyname,
const char *valuename, uint32 size)
{
if (q_u == NULL) return False;
DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
q_u->handle = *handle;
init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
q_u->size = size;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_getprinterdata (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
if (!prs_align(ps))
return False;
if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
return False;
if (!prs_align(ps))
return False;
if (!prs_uint32("size", ps, depth, &q_u->size))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_deleteprinterdata (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
if (!prs_align(ps))
return False;
if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_deleteprinterdata (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
depth++;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_deleteprinterdataex(const 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(const 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)
********************************************************************/
bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
depth++;
if (!prs_align(ps))
return False;
if (!prs_uint32("type", ps, depth, &r_u->type))
return False;
if (!prs_uint32("size", ps, depth, &r_u->size))
return False;
if (UNMARSHALLING(ps) && r_u->size) {
r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
if(!r_u->data)
return False;
}
if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
return False;
if (!prs_align(ps))
return False;
if (!prs_uint32("needed", ps, depth, &r_u->needed))
return False;
if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* make a structure.
********************************************************************/
bool make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
{
if (q_u == NULL) return False;
DEBUG(5,("make_spoolss_q_closeprinter\n"));
memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
return True;
}
/*******************************************************************
* read a structure.
* called from static spoolss_q_abortprinter (srv_spoolss.c)
* called from spoolss_abortprinter (cli_spoolss.c)
********************************************************************/
bool spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_abortprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
depth++;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from static spoolss_q_deleteprinter (srv_spoolss.c)
* called from spoolss_deleteprinter (cli_spoolss.c)
********************************************************************/
bool spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from static spoolss_r_deleteprinter (srv_spoolss.c)
* called from spoolss_deleteprinter (cli_spoolss.c)
********************************************************************/
bool spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
* called from spoolss_deleteprinterdriver (cli_spoolss.c)
********************************************************************/
bool spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
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;
return True;
}
/*******************************************************************
* write a structure.
********************************************************************/
bool spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
depth++;
if (!prs_align(ps))
return False;
if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
* called from spoolss_deleteprinterdriver (cli_spoolss.c)
********************************************************************/
bool spoolss_io_q_deleteprinterdriverex(const 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(const 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.
* called from static spoolss_q_closeprinter (srv_spoolss.c)
* called from spoolss_closeprinter (cli_spoolss.c)
********************************************************************/
bool spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from static spoolss_r_closeprinter (srv_spoolss.c)
* called from spoolss_closeprinter (cli_spoolss.c)
********************************************************************/
bool spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
depth++;
if (!prs_align(ps))
return False;
if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_startdocprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_startdocprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
depth++;
if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
return False;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_enddocprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_enddocprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
depth++;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_startpageprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_startpageprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
depth++;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_endpageprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_endpageprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
depth++;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_writeprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
return False;
if (q_u->buffer_size!=0)
{
if (UNMARSHALLING(ps))
q_u->buffer=PRS_ALLOC_MEM(ps, uint8, q_u->buffer_size);
if(q_u->buffer == NULL)
return False;
if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
return False;
}
if(!prs_align(ps))
return False;
if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
return False;
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_writeprinter (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
depth++;
if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
return False;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_rffpcnex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
return False;
if(!prs_uint32("flags", ps, depth, &q_u->flags))
return False;
if(!prs_uint32("options", ps, depth, &q_u->options))
return False;
if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
return False;
if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
return False;
if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
return False;
if (q_u->option_ptr!=0) {
if (UNMARSHALLING(ps))
if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
return False;
if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
return False;
}
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_rffpcnex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
depth++;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_q_rfnpcnex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
return False;
if(!prs_uint32("change", ps, depth, &q_u->change))
return False;
if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
return False;
if (q_u->option_ptr!=0) {
if (UNMARSHALLING(ps))
if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
return False;
if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
return False;
}
return True;
}
/*******************************************************************
* write a structure.
* called from spoolss_r_rfnpcnex (srv_spoolss.c)
********************************************************************/
bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
depth++;
if(!prs_align(ps))
return False;
if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
return False;
if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
return False;
if(!prs_align(ps))
return False;
if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
* return the length of a uint16 (obvious, but the code is clean)
********************************************************************/
static uint32 size_of_uint16(uint16 *value)
{
return (sizeof(*value));
}
/*******************************************************************
* return the length of a uint32 (obvious, but the code is clean)
********************************************************************/
static uint32 size_of_uint32(uint32 *value)
{
return (sizeof(*value));
}
/*******************************************************************
* return the length of a NTTIME (obvious, but the code is clean)
********************************************************************/
static uint32 size_of_nttime(NTTIME *value)
{
return (sizeof(*value));
}
/*******************************************************************
* return the length of a uint32 (obvious, but the code is clean)
********************************************************************/
static uint32 size_of_device_mode(DEVICEMODE *devmode)
{
if (devmode==NULL)
return (4);
else
return (4+devmode->size+devmode->driverextra);
}
/*******************************************************************
* return the length of a uint32 (obvious, but the code is clean)
********************************************************************/
static uint32 size_of_systemtime(SYSTEMTIME *systime)
{
if (systime==NULL)
return (4);
else
return (sizeof(SYSTEMTIME) +4);
}
/*******************************************************************
Parse a DEVMODE structure and its relative pointer.
********************************************************************/
static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
{
prs_struct *ps=&buffer->prs;
prs_debug(ps, depth, desc, "smb_io_reldevmode");
depth++;
if (MARSHALLING(ps)) {
uint32 struct_offset = prs_offset(ps);
uint32 relative_offset;
if (*devmode == NULL) {
relative_offset=0;
if (!prs_uint32("offset", ps, depth, &relative_offset))
return False;
DEBUG(8, ("boing, the devmode was NULL\n"));
return True;
}
buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
if(!prs_set_offset(ps, buffer->string_at_end))
return False;
/* write the DEVMODE */
if (!spoolss_io_devmode(desc, ps, depth, *devmode))
return False;
if(!prs_set_offset(ps, struct_offset))
return False;
relative_offset=buffer->string_at_end - buffer->struct_start;
/* write its offset */
if (!prs_uint32("offset", ps, depth, &relative_offset))
return False;
}
else {
uint32 old_offset;
/* 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))
return False;
/* read the string */
if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
return False;
if (!spoolss_io_devmode(desc, ps, depth, *devmode))
return False;
if(!prs_set_offset(ps, old_offset))
return False;
}
return True;
}
/*******************************************************************
Parse a PRINTER_INFO_0 structure.
********************************************************************/
bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
{
prs_struct *ps=&buffer->prs;
prs_debug(ps, depth, desc, "smb_io_printer_info_0");
depth++;
buffer->struct_start=prs_offset(ps);
if (!smb_io_relstr("printername", buffer, depth, &info->printername))
return False;
if (!smb_io_relstr("servername", buffer, depth, &info->servername))
return False;
if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
return False;
if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
return False;
if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
return False;
if(!prs_uint16("year", ps, depth, &info->year))
return False;
if(!prs_uint16("month", ps, depth, &info->month))
return False;
if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
return False;
if(!prs_uint16("day", ps, depth, &info->day))
return False;
if(!prs_uint16("hour", ps, depth, &info->hour))
return False;
if(!prs_uint16("minute", ps, depth, &info->minute))
return False;
if(!prs_uint16("second", ps, depth, &info->second))
return False;
if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
return False;
if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
return False;
if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
return False;
if(!prs_uint16("major_version", ps, depth, &info->major_version))
return False;
if(!prs_uint16("build_version", ps, depth, &info->build_version))
return False;
if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
return False;
if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
return False;
if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
return False;
if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
return False;
if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
return False;
if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
return False;
if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
return False;
if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
return False;
if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
return False;
if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
return False;
if(!prs_uint32("change_id", ps, depth, &info->change_id))
return False;
if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
return False;
if(!prs_uint32("status" , ps, depth, &info->status))
return False;
if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
return False;
if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
return False;
if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
return False;
if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
return False;
if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
return False;
if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
return False;
if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
return False;
if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
return False;
if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
return False;
if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
return False;
return True;
}
/*******************************************************************
Parse a PRINTER_INFO_1 structure.
********************************************************************/
bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
prs_debug(ps, depth, desc, "smb_io_printer_info_1");
depth++;
buffer->struct_start=prs_offset(ps);
if (!prs_uint32("flags", ps, depth, &info->flags))
return False;
if (!smb_io_relstr("description", buffer, depth, &info->description))