summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-François Micouleau <jfm@samba.org>1999-07-27 10:46:44 +0000
committerJean-François Micouleau <jfm@samba.org>1999-07-27 10:46:44 +0000
commit4bff2675746518af740e475e4e996247ac21d817 (patch)
tree86cf0e3697c4091909be7dd9466bf213acc2964b
parentf2e0bbffb5e40df4850b6bd0eae73a8fb0edc6d7 (diff)
downloadsamba-4bff2675746518af740e475e4e996247ac21d817.tar.gz
samba-4bff2675746518af740e475e4e996247ac21d817.tar.bz2
samba-4bff2675746518af740e475e4e996247ac21d817.zip
- enumprintprocessors and enumprintmonitors added.
- getjob (level 1 and 2) done. - better handling of getprinterdriver (level 2). - added workaround to print PCL files. Now the spoolss code should be compliant with all kind of printers :-) Jean Francois (This used to be commit bf9b639bf9162d61eb152af506dc2c1a7e8a4c85)
-rw-r--r--source3/include/proto.h4
-rwxr-xr-xsource3/include/rpc_spoolss.h50
-rw-r--r--source3/rpc_parse/parse_spoolss.c407
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c334
4 files changed, 699 insertions, 96 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 04b002ae57..2c7b386ac2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2868,6 +2868,8 @@ void spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r
void spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
void spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
void spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
+void spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
void spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
void spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
void spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
@@ -2877,6 +2879,8 @@ void spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int
void spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth);
void spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth);
void spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth);
+void spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
+void spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_srv.c */
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
index 8476ad7691..a8f934fc47 100755
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -29,7 +29,6 @@
/* spoolss pipe: this are the calls which are not implemented ...
#define SPOOLSS_OPENPRINTER 0x01
-#define SPOOLSS_GETJOB 0x03
#define SPOOLSS_DELETEPRINTER 0x06
#define SPOOLSS_GETPRINTERDRIVER 0x0b
#define SPOOLSS_DELETEPRINTERDRIVER 0x0d
@@ -40,7 +39,6 @@
#define SPOOLSS_WAITFORPRINTERCHANGE 0x1c
#define SPOOLSS_DELETEFORM 0x1f
#define SPOOLSS_GETFORM 0x20
-#define SPOOLSS_ENUMMONITORS 0x24
#define SPOOLSS_ADDPORT 0x25
#define SPOOLSS_CONFIGUREPORT 0x26
#define SPOOLSS_DELETEPORT 0x27
@@ -73,6 +71,7 @@
#define SPOOLSS_ENUMPRINTERS 0x00
#define SPOOLSS_SETJOB 0x02
+#define SPOOLSS_GETJOB 0x03
#define SPOOLSS_ENUMJOBS 0x04
#define SPOOLSS_ADDPRINTER 0x05
#define SPOOLSS_SETPRINTER 0x07
@@ -95,6 +94,7 @@
#define SPOOLSS_SETFORM 0x21
#define SPOOLSS_ENUMFORMS 0x22
#define SPOOLSS_ENUMPORTS 0x23
+#define SPOOLSS_ENUMMONITORS 0x24
#define SPOOLSS_ENUMPRINTPROCESSORDATATYPES 0x33
#define SPOOLSS_GETPRINTERDRIVER2 0x35
/* find close printer notification */
@@ -891,7 +891,7 @@ typedef struct driver_info_3
UNISTR datafile;
UNISTR configfile;
UNISTR helpfile;
- UNISTR dependentfiles;
+ UNISTR **dependentfiles;
UNISTR monitorname;
UNISTR defaultdatatype;
} DRIVER_INFO_3;
@@ -977,7 +977,7 @@ typedef struct s_job_info_2
UNISTR printprocessor;
UNISTR parameters;
UNISTR drivername;
- DEVICEMODE devmode;
+ DEVICEMODE *devmode;
UNISTR text_status;
/* SEC_DESC sec_desc;*/
uint32 status;
@@ -1369,6 +1369,28 @@ typedef struct spool_r_enumprintprocessordatatypes
uint32 status;
} SPOOL_R_ENUMPRINTPROCESSORDATATYPES;
+typedef struct spool_q_enumprintmonitors
+{
+ UNISTR2 name;
+ uint32 level;
+ BUFFER buffer;
+ uint32 buf_size;
+} SPOOL_Q_ENUMPRINTMONITORS;
+
+typedef struct printmonitor_1
+{
+ UNISTR name;
+} PRINTMONITOR_1;
+
+typedef struct spool_r_enumprintmonitors
+{
+ uint32 level;
+ PRINTMONITOR_1 *info_1;
+ uint32 offered;
+ uint32 numofprintmonitors;
+ uint32 status;
+} SPOOL_R_ENUMPRINTMONITORS;
+
typedef struct spool_q_enumprinterdata
{
PRINTER_HND handle;
@@ -1445,6 +1467,26 @@ typedef struct spool_r_setform
uint32 status;
} SPOOL_R_SETFORM;
+typedef struct spool_q_getjob
+{
+ PRINTER_HND handle;
+ uint32 jobid;
+ uint32 level;
+ BUFFER buffer;
+ uint32 buf_size;
+} SPOOL_Q_GETJOB;
+
+typedef struct spool_r_getjob
+{
+ uint32 level;
+ union {
+ JOB_INFO_1 *job_info_1;
+ JOB_INFO_2 *job_info_2;
+ } job;
+ uint32 offered;
+ uint32 status;
+} SPOOL_R_GETJOB;
+
#define PRINTER_DRIVER_VERSION 2
#define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86"
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 08ea5f73a2..a1ee058e06 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -98,16 +98,13 @@ static void smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, in
prs_align(ps);
- prs_uint32("p_docname", ps, depth, &(info_1->p_docname));
+ prs_uint32("p_docname", ps, depth, &(info_1->p_docname));
prs_uint32("p_outputfile", ps, depth, &(info_1->p_outputfile));
- prs_uint32("p_datatype", ps, depth, &(info_1->p_datatype));
+ prs_uint32("p_datatype", ps, depth, &(info_1->p_datatype));
- if (info_1->p_docname)
- smb_io_unistr2("", &(info_1->docname),True,ps,depth);
- if (info_1->p_outputfile)
- smb_io_unistr2("", &(info_1->outputfile),True,ps,depth);
- if (info_1->p_datatype)
- smb_io_unistr2("", &(info_1->datatype),True,ps,depth);
+ smb_io_unistr2("", &(info_1->docname), info_1->p_docname, ps, depth);
+ smb_io_unistr2("", &(info_1->outputfile), info_1->p_outputfile, ps, depth);
+ smb_io_unistr2("", &(info_1->datatype), info_1->p_datatype, ps, depth);
}
/*******************************************************************
@@ -818,6 +815,35 @@ static void smb_io_relstr(char *desc, prs_struct *ps, int depth, UNISTR *buffer,
prs_uint32("offset", ps, depth, &(relative_offset));
}
+
+/*******************************************************************
+ * write a array UNICODE strings and its relative pointer.
+ * used by 2 RPC structs
+ ********************************************************************/
+static void smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR ***buffer,
+ uint32 *start_offset, uint32 *end_offset)
+{
+ int i=0;
+ uint32 struct_offset;
+ uint32 relative_offset;
+ struct_offset=ps->offset;
+
+
+ while ( (*buffer)[i]!=0x0000 )
+ {
+ *end_offset-= 2*(str_len_uni((*buffer)[i])+1);
+ ps->offset=*end_offset;
+ spoolss_smb_io_unistr(desc, (*buffer)[i], ps, depth);
+
+ i++;
+ }
+
+ ps->offset=struct_offset;
+ relative_offset=*end_offset-*start_offset;
+
+ prs_uint32("offset", ps, depth, &(relative_offset));
+}
+
/*******************************************************************
* write a DEVICEMODE struct.
* on reading allocate memory for the private member
@@ -1053,7 +1079,9 @@ static void smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_str
smb_io_relstr("datafile", ps, depth, &(info->datafile), start_offset, end_offset);
smb_io_relstr("configfile", ps, depth, &(info->configfile), start_offset, end_offset);
smb_io_relstr("helpfile", ps, depth, &(info->helpfile), start_offset, end_offset);
- smb_io_relstr("dependentfiles", ps, depth, &(info->dependentfiles), start_offset, end_offset);
+
+ smb_io_relarraystr("dependentfiles", ps, depth, &(info->dependentfiles), start_offset, end_offset);
+
smb_io_relstr("monitorname", ps, depth, &(info->monitorname), start_offset, end_offset);
smb_io_relstr("defaultdatatype", ps, depth, &(info->defaultdatatype), start_offset, end_offset);
}
@@ -1061,64 +1089,64 @@ static void smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_str
/*******************************************************************
********************************************************************/
static void smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int depth,
- uint32 *start_offset, uint32 *end_offset)
+ uint32 *start_offset, uint32 *end_offset)
{
prs_debug(ps, depth, desc, "smb_io_job_info_1");
depth++;
*start_offset=ps->offset;
- prs_uint32("jobid", ps, depth, &(info->jobid));
- smb_io_relstr("printername",ps, depth, &(info->printername), start_offset, end_offset);
- smb_io_relstr("machinename",ps, depth, &(info->machinename), start_offset, end_offset);
- smb_io_relstr("username",ps, depth, &(info->username), start_offset, end_offset);
- smb_io_relstr("document",ps, depth, &(info->document), start_offset, end_offset);
- smb_io_relstr("datatype",ps, depth, &(info->datatype), start_offset, end_offset);
- smb_io_relstr("text_status",ps, depth, &(info->text_status), start_offset, end_offset);
- prs_uint32("status", ps, depth, &(info->status));
- prs_uint32("priority", ps, depth, &(info->priority));
- prs_uint32("position", ps, depth, &(info->position));
- prs_uint32("totalpages", ps, depth, &(info->totalpages));
- prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted));
+ prs_uint32("jobid", ps, depth, &(info->jobid));
+ smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset);
+ smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset);
+ smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset);
+ smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset);
+ smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset);
+ smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset);
+ prs_uint32("status", ps, depth, &(info->status));
+ prs_uint32("priority", ps, depth, &(info->priority));
+ prs_uint32("position", ps, depth, &(info->position));
+ prs_uint32("totalpages", ps, depth, &(info->totalpages));
+ prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted));
spoolss_io_system_time("submitted", ps, depth, &(info->submitted) );
}
/*******************************************************************
********************************************************************/
static void smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth,
- uint32 *start_offset, uint32 *end_offset)
+ uint32 *start_offset, uint32 *end_offset)
{
int pipo=0;
prs_debug(ps, depth, desc, "smb_io_job_info_2");
depth++;
*start_offset=ps->offset;
- prs_uint32("jobid", ps, depth, &(info->jobid));
- smb_io_relstr("printername",ps, depth, &(info->printername), start_offset, end_offset);
- smb_io_relstr("machinename",ps, depth, &(info->machinename), start_offset, end_offset);
- smb_io_relstr("username",ps, depth, &(info->username), start_offset, end_offset);
- smb_io_relstr("document",ps, depth, &(info->document), start_offset, end_offset);
- smb_io_relstr("notifyname",ps, depth, &(info->notifyname), start_offset, end_offset);
- smb_io_relstr("datatype",ps, depth, &(info->datatype), start_offset, end_offset);
+ prs_uint32("jobid", ps, depth, &(info->jobid));
+ smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset);
+ smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset);
+ smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset);
+ smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset);
+ smb_io_relstr("notifyname", ps, depth, &(info->notifyname), start_offset, end_offset);
+ smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset);
- smb_io_relstr("printprocessor",ps, depth, &(info->printprocessor), start_offset, end_offset);
- smb_io_relstr("parameters",ps, depth, &(info->parameters), start_offset, end_offset);
- smb_io_relstr("drivername",ps, depth, &(info->drivername), start_offset, end_offset);
- smb_io_reldevmode("devmode", ps, depth, &(info->devmode), start_offset, end_offset);
- smb_io_relstr("text_status",ps, depth, &(info->text_status), start_offset, end_offset);
+ smb_io_relstr("printprocessor", ps, depth, &(info->printprocessor), start_offset, end_offset);
+ smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset);
+ smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset);
+ smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset);
+ smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset);
/* SEC_DESC sec_desc;*/
prs_uint32("Hack! sec desc", ps, depth, &pipo);
- prs_uint32("status", ps, depth, &(info->status));
- prs_uint32("priority", ps, depth, &(info->priority));
- prs_uint32("position", ps, depth, &(info->position));
- prs_uint32("starttime", ps, depth, &(info->starttime));
- prs_uint32("untiltime", ps, depth, &(info->untiltime));
- prs_uint32("totalpages", ps, depth, &(info->totalpages));
- prs_uint32("size", ps, depth, &(info->size));
+ prs_uint32("status", ps, depth, &(info->status));
+ prs_uint32("priority", ps, depth, &(info->priority));
+ prs_uint32("position", ps, depth, &(info->position));
+ prs_uint32("starttime", ps, depth, &(info->starttime));
+ prs_uint32("untiltime", ps, depth, &(info->untiltime));
+ prs_uint32("totalpages", ps, depth, &(info->totalpages));
+ prs_uint32("size", ps, depth, &(info->size));
spoolss_io_system_time("submitted", ps, depth, &(info->submitted) );
- prs_uint32("timeelapsed", ps, depth, &(info->timeelapsed));
- prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted));
+ prs_uint32("timeelapsed", ps, depth, &(info->timeelapsed));
+ prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted));
}
/*******************************************************************
@@ -1157,6 +1185,30 @@ static void smb_io_port_2(char *desc, PORT_INFO_2 *info, prs_struct *ps, int dep
}
/*******************************************************************
+********************************************************************/
+static void smb_io_processor_info_1(char *desc, PRINTPROCESSOR_1 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
+{
+ prs_debug(ps, depth, desc, "smb_io_processor_info_1");
+ depth++;
+ *start_offset=ps->offset;
+
+ smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset);
+}
+
+/*******************************************************************
+********************************************************************/
+static void smb_io_monitor_info_1(char *desc, PRINTMONITOR_1 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
+{
+ prs_debug(ps, depth, desc, "smb_io_monitor_info_1");
+ depth++;
+ *start_offset=ps->offset;
+
+ smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset);
+}
+
+/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
static uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
@@ -1255,6 +1307,9 @@ return the size required by a struct in the stream
static uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
{
int size=0;
+ UNISTR **string;
+ int i=0;
+
DEBUG(9,("Sizing driver info_3\n"));
size+=size_of_uint32( &(info->version) );
size+=size_of_relative_string( &(info->name) );
@@ -1263,9 +1318,17 @@ static uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
size+=size_of_relative_string( &(info->datafile) );
size+=size_of_relative_string( &(info->configfile) );
size+=size_of_relative_string( &(info->helpfile) );
- size+=size_of_relative_string( &(info->dependentfiles) );
size+=size_of_relative_string( &(info->monitorname) );
size+=size_of_relative_string( &(info->defaultdatatype) );
+
+ string=info->dependentfiles;
+
+ while ( (string)[i]!=0x0000 )
+ {
+ size+=2*(1+ str_len_uni( string[i] ) );
+ i++;
+ }
+ size+=4;
DEBUGADD(9,("size: [%d]\n", size));
return (size);
@@ -1312,7 +1375,7 @@ static uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
size+=size_of_relative_string( &(info->printprocessor) );
size+=size_of_relative_string( &(info->parameters) );
size+=size_of_relative_string( &(info->drivername) );
- size+=size_of_device_mode( &(info->devmode) );
+ size+=size_of_device_mode( info->devmode );
size+=size_of_relative_string( &(info->text_status) );
/* SEC_DESC sec_desc;*/
size+=size_of_uint32( &(info->status) );
@@ -1365,6 +1428,28 @@ static uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
}
/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+static uint32 spoolss_size_processor_info_1(PRINTPROCESSOR_1 *info)
+{
+ int size=0;
+ size+=size_of_relative_string( &(info->name) );
+
+ return (size);
+}
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+static uint32 spoolss_size_monitor_info_1(PRINTMONITOR_1 *info)
+{
+ int size=0;
+ size+=size_of_relative_string( &(info->name) );
+
+ return (size);
+}
+
+/*******************************************************************
* read a uint8 buffer of size *size.
* allocate memory for it
* return a pointer to the allocated memory and the size
@@ -3216,6 +3301,7 @@ void spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r
uint32 useless_ptr=0xADDE0FF0;
uint32 start_offset, end_offset, beginning;
uint32 bufsize_required=0;
+ int i;
prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
depth++;
@@ -3228,12 +3314,12 @@ void spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r
{
PRINTPROCESSOR_1 *info_1;
info_1=r_u->info_1;
-/*
+
for (i=0; i<r_u->numofprintprocessors; i++)
{
- bufsize_required += spoolss_size_port_info_2(&(info_1[i]));
+ bufsize_required += spoolss_size_processor_info_1(&(info_1[i]));
}
-*/ break;
+ break;
}
}
@@ -3265,14 +3351,14 @@ void spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r
switch (r_u->level)
{
- case 2:
+ case 1:
{
-/* PORT_INFO_2 *info;
- for (i=0; i<r_u->numofports; i++)
+ PRINTPROCESSOR_1 *info_1;
+ for (i=0; i<r_u->numofprintprocessors; i++)
{
- info = &(r_u->port.port_info_2[i]);
- smb_io_port_2(desc, info, ps, depth, &start_offset, &end_offset);
- }*/
+ info_1 = &(r_u->info_1[i]);
+ smb_io_processor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset);
+ }
break;
}
}
@@ -3313,6 +3399,106 @@ void spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q
/*******************************************************************
********************************************************************/
+void spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ int i;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ PRINTMONITOR_1 *info_1;
+ info_1=r_u->info_1;
+
+ for (i=0; i<r_u->numofprintmonitors; i++)
+ {
+ bufsize_required += spoolss_size_monitor_info_1(&(info_1[i]));
+ }
+ break;
+ }
+ }
+
+ DEBUG(4,("size needed: %d\n",bufsize_required));
+ DEBUG(4,("size offered: %d\n",r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
+
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
+
+ DEBUG(4,("buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
+
+ DEBUG(4,("buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ PRINTMONITOR_1 *info_1;
+ for (i=0; i<r_u->numofprintmonitors; i++)
+ {
+ info_1 = &(r_u->info_1[i]);
+ smb_io_monitor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("numofprintmonitors", ps, depth, &(r_u->numofprintmonitors));
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+********************************************************************/
+void spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
+{
+ uint32 useless;
+ prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+}
+
+/*******************************************************************
+********************************************************************/
void spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
@@ -3504,3 +3690,114 @@ void spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int
prs_uint32("status", ps, depth, &(r_u->status));
}
+/*******************************************************************
+********************************************************************/
+void spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ JOB_INFO_1 *info;
+ info=r_u->job.job_info_1;
+
+ bufsize_required += spoolss_size_job_info_1(info);
+ break;
+ }
+ case 2:
+ {
+ JOB_INFO_2 *info;
+ info=r_u->job.job_info_2;
+
+ bufsize_required += spoolss_size_job_info_2(info);
+ break;
+ }
+ }
+
+ DEBUG(4,("spoolss_io_r_getjob, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_getjob, size offered: %d\n",r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
+
+ DEBUG(4,("spoolss_io_r_getjob, buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
+
+ DEBUG(4,("spoolss_io_r_enumjobs, buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ JOB_INFO_1 *info;
+ info = r_u->job.job_info_1;
+ smb_io_job_info_1(desc, info, ps, depth, &start_offset, &end_offset);
+ break;
+ }
+ case 2:
+ {
+ JOB_INFO_2 *info;
+ info = r_u->job.job_info_2;
+ smb_io_job_info_2(desc, info, ps, depth, &start_offset, &end_offset);
+ break;
+ }
+
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+********************************************************************/
+void spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
+{
+
+ prs_debug(ps, depth, desc, "");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("jobid", ps, depth, &(q_u->jobid));
+ prs_uint32("level", ps, depth, &(q_u->level));
+
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+
+ prs_align(ps);
+
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+}
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 2cb5543f26..067fdd3ff7 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -1424,18 +1424,25 @@ static void api_spoolss_rfnpcnex(pipes_struct *p, prs_struct *data,
* construct_printer_info_0
* fill a printer_info_1 struct
********************************************************************/
-static void construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring servername, connection_struct *conn)
+static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring servername, connection_struct *conn)
{
pstring chaine;
int count;
+ NT_PRINTER_INFO_LEVEL ntprinter;
print_queue_struct *queue=NULL;
print_status_struct status;
bzero(&status,sizeof(status));
+
+ if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
+ {
+ return (False);
+ }
+
count=get_printqueue(snum, conn ,&queue,&status);
/* the description and the name are of the form \\server\share */
- slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, lp_servicename(snum));
+ slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter.info_2->printername);
make_unistr(&(printer->printername), chaine);
@@ -1472,8 +1479,11 @@ static void construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
printer->unknown21 = 0x0648;
printer->unknown22 = 0x0;
printer->unknown23 = 0x5;
+
if (queue) free(queue);
-
+
+ free_a_printer(ntprinter, 2);
+ return (True);
}
/********************************************************************
@@ -1729,12 +1739,19 @@ static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number,
/****************************************************************************
****************************************************************************/
+static void free_devmode(DEVICEMODE *devmode)
+{
+ if (devmode->private!=NULL)
+ free(devmode->private);
+ if (devmode!=NULL)
+ free(devmode);
+}
+
+/****************************************************************************
+****************************************************************************/
static void free_printer_info_2(PRINTER_INFO_2 *printer)
{
- if (printer->devmode->private!=NULL)
- free(printer->devmode->private);
- if (printer->devmode!=NULL)
- free(printer->devmode);
+ free_devmode(printer->devmode);
if (printer!=NULL)
free(printer);
}
@@ -2024,6 +2041,40 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum,
}
/********************************************************************
+ * copy a strings array and convert to UNICODE
+ ********************************************************************/
+static void make_unistr_array(UNISTR ***uni_array, char **char_array)
+{
+ int i=0;
+ char *v;
+
+ DEBUG(6,("make_unistr_array\n"));
+
+ for (v=char_array[i]; *v!='\0'; v=char_array[i])
+ {
+ DEBUGADD(6,("i:%d:", i));
+ DEBUGADD(6,("%s:%d:", v, strlen(v)));
+
+ *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1));
+ DEBUGADD(7,("realloc:[%p],", *uni_array));
+
+ (*uni_array)[i]=(UNISTR *)malloc( sizeof(UNISTR) );
+ DEBUGADD(7,("alloc:[%p],", (*uni_array)[i]));
+
+ make_unistr( (*uni_array)[i], v );
+ DEBUGADD(7,("copy\n"));
+
+ i++;
+ }
+ DEBUGADD(7,("last one\n"));
+
+ *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1));
+ (*uni_array)[i]=(UNISTR *)malloc( sizeof(UNISTR));
+ (*uni_array)[i]=0x0000;
+ DEBUGADD(6,("last one:done\n"));
+}
+
+/********************************************************************
* construct_printer_info_3
* fill a printer_info_3 struct
********************************************************************/
@@ -2062,7 +2113,8 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info,
make_unistr( &(info->monitorname), driver.info_3->monitorname );
make_unistr( &(info->defaultdatatype), driver.info_3->defaultdatatype );
- make_unistr( &(info->dependentfiles), "" );
+ info->dependentfiles=NULL;
+ make_unistr_array(&(info->dependentfiles), driver.info_3->dependentfiles);
}
/********************************************************************
@@ -2227,26 +2279,6 @@ static void api_spoolss_endpageprinter(pipes_struct *p, prs_struct *data,
spoolss_reply_endpageprinter(&q_u, rdata);
}
-/****************************************************************************
-****************************************************************************/
-static void spoolss_reply_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *rdata)
-{
- SPOOL_R_STARTDOCPRINTER r_u;
- int pnum = find_printer_index_by_hnd(&(q_u->handle));
-
- if (OPEN_HANDLE(pnum))
- {
- r_u.jobid=Printer[pnum].current_jobid;
- r_u.status=0x0;
-
- spoolss_io_r_startdocprinter("",&r_u,rdata,0);
- }
- else
- {
- DEBUG(3,("Error in startdocprinter printer handle (pnum=%x)\n",pnum));
- }
-}
-
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
@@ -2256,8 +2288,12 @@ static void api_spoolss_startdocprinter(pipes_struct *p, prs_struct *data,
prs_struct *rdata)
{
SPOOL_Q_STARTDOCPRINTER q_u;
+ SPOOL_R_STARTDOCPRINTER r_u;
+ DOC_INFO_1 *info_1;
+
pstring fname;
pstring tempname;
+ pstring datatype;
int fd = -1;
int snum;
int pnum;
@@ -2265,9 +2301,29 @@ static void api_spoolss_startdocprinter(pipes_struct *p, prs_struct *data,
/* decode the stream and fill the struct */
spoolss_io_q_startdocprinter("", &q_u, data, 0);
+ info_1=&(q_u.doc_info_container.docinfo.doc_info_1);
+ r_u.status=0x0;
pnum = find_printer_index_by_hnd(&(q_u.handle));
- if (OPEN_HANDLE(pnum))
+ /*
+ * a nice thing with NT is it doesn't listen to what you tell it.
+ * when asked to send _only_ RAW datas, it tries to send datas
+ * in EMF format.
+ *
+ * So I add checks like in NT Server ...
+ */
+
+ if (info_1->p_datatype != 0)
+ {
+ unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
+ if (strcmp(datatype, "RAW") != 0)
+ {
+ r_u.jobid=0;
+ r_u.status=1804;
+ }
+ }
+
+ if (r_u.status==0 && OPEN_HANDLE(pnum))
{
/* get the share number of the printer */
get_printer_snum(&(q_u.handle),&snum);
@@ -2291,8 +2347,12 @@ static void api_spoolss_startdocprinter(pipes_struct *p, prs_struct *data,
Printer[pnum].document_fd=fd;
Printer[pnum].document_started=True;
- }
- spoolss_reply_startdocprinter(&q_u, rdata);
+ r_u.jobid=Printer[pnum].current_jobid;
+ r_u.status=0x0;
+
+ }
+
+ spoolss_io_r_startdocprinter("",&r_u,rdata,0);
}
/****************************************************************************
@@ -2665,19 +2725,30 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
/****************************************************************************
****************************************************************************/
-static void fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
+static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
int position, int snum)
{
pstring temp_name;
+ DEVICEMODE *devmode;
+ NT_PRINTER_INFO_LEVEL ntprinter;
+ pstring chaine;
struct tm *t;
time_t unixdate = time(NULL);
+
+ if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
+ {
+ return (False);
+ }
t=gmtime(&unixdate);
snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
job_info->jobid=queue->job;
- make_unistr(&(job_info->printername), lp_servicename(snum));
+
+ snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter.info_2->printername);
+ make_unistr(&(job_info->printername), chaine);
+
make_unistr(&(job_info->machinename), temp_name);
make_unistr(&(job_info->username), queue->user);
make_unistr(&(job_info->document), queue->file);
@@ -2685,9 +2756,6 @@ static void fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
make_unistr(&(job_info->datatype), "RAW");
make_unistr(&(job_info->printprocessor), "winprint");
make_unistr(&(job_info->parameters), "");
-
-/* here the devicemode should be filled up */
-
make_unistr(&(job_info->text_status), "");
/* and here the security descriptor */
@@ -2702,6 +2770,14 @@ static void fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
make_systemtime(&(job_info->submitted), t);
job_info->timeelapsed=0;
job_info->pagesprinted=0;
+
+ devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
+ ZERO_STRUCTP(devmode);
+ construct_dev_mode(devmode, snum, global_myname);
+ job_info->devmode=devmode;
+
+ free_a_printer(ntprinter, 2);
+ return (True);
}
/****************************************************************************
@@ -2772,6 +2848,7 @@ static void spoolss_reply_enumjobs(SPOOL_Q_ENUMJOBS *q_u, prs_struct *rdata, con
}
case 2:
{
+ free_devmode(job_info_2->devmode);
free(job_info_2);
break;
}
@@ -3470,7 +3547,6 @@ static void api_spoolss_addform(pipes_struct *p, prs_struct *data,
spoolss_reply_addform(&q_u, rdata);
}
-
/****************************************************************************
****************************************************************************/
static void spoolss_reply_setform(SPOOL_Q_SETFORM *q_u, prs_struct *rdata)
@@ -3510,6 +3586,187 @@ static void api_spoolss_setform(pipes_struct *p, prs_struct *data,
spoolss_reply_setform(&q_u, rdata);
}
+/****************************************************************************
+****************************************************************************/
+static void spoolss_reply_enumprintprocessors(SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *rdata)
+{
+ SPOOL_R_ENUMPRINTPROCESSORS r_u;
+ PRINTPROCESSOR_1 *info_1;
+
+ DEBUG(5,("spoolss_reply_enumprintprocessors\n"));
+
+ /*
+ * Enumerate the print processors ...
+ *
+ * Just reply with "winprint", to keep NT happy
+ * and I can use my nice printer checker.
+ */
+
+ r_u.status = 0x0;
+ r_u.offered = q_u->buf_size;
+ r_u.level = q_u->level;
+
+ r_u.numofprintprocessors = 0x1;
+
+ info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1));
+
+ make_unistr(&(info_1->name), "winprint");
+
+ r_u.info_1=info_1;
+
+ spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0);
+}
+
+/****************************************************************************
+****************************************************************************/
+static void api_spoolss_enumprintprocessors(pipes_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ SPOOL_Q_ENUMPRINTPROCESSORS q_u;
+
+ spoolss_io_q_enumprintprocessors("", &q_u, data, 0);
+
+ spoolss_reply_enumprintprocessors(&q_u, rdata);
+}
+
+/****************************************************************************
+****************************************************************************/
+static void spoolss_reply_enumprintmonitors(SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *rdata)
+{
+ SPOOL_R_ENUMPRINTMONITORS r_u;
+ PRINTMONITOR_1 *info_1;
+
+ DEBUG(5,("spoolss_reply_enumprintmonitors\n"));
+
+ /*
+ * Enumerate the print monitors ...
+ *
+ * Just reply with "Local Port", to keep NT happy
+ * and I can use my nice printer checker.
+ */
+
+ r_u.status = 0x0;
+ r_u.offered = q_u->buf_size;
+ r_u.level = q_u->level;
+
+ r_u.numofprintmonitors = 0x1;
+
+ info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1));
+
+ make_unistr(&(info_1->name), "Local Port");
+
+ r_u.info_1=info_1;
+
+ spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0);
+}
+
+/****************************************************************************
+****************************************************************************/
+static void api_spoolss_enumprintmonitors(pipes_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ SPOOL_Q_ENUMPRINTMONITORS q_u;
+
+ spoolss_io_q_enumprintmonitors("", &q_u, data, 0);
+
+ spoolss_reply_enumprintmonitors(&q_u, rdata);
+}
+
+/****************************************************************************
+****************************************************************************/
+static void spoolss_reply_getjob(SPOOL_Q_GETJOB *q_u, prs_struct *rdata, connection_struct *conn)
+{
+ SPOOL_R_GETJOB r_u;
+ int snum;
+ int count;
+ int i;
+ print_queue_struct *queue=NULL;
+ print_status_struct status;
+ JOB_INFO_1 *job_info_1=NULL;
+ JOB_INFO_2 *job_info_2=NULL;
+
+ DEBUG(4,("spoolss_reply_getjob\n"));
+
+ bzero(&status,sizeof(status));
+
+ r_u.offered=q_u->buf_size;
+
+ if (get_printer_snum(&(q_u->handle), &snum))
+ {
+ count=get_printqueue(snum, conn, &queue, &status);
+
+ r_u.level=q_u->level;
+
+ DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", count, status.status, status.message));
+
+ switch (r_u.level)
+ {
+ case 1:
+ {
+ job_info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
+
+ for (i=0; i<count; i++)
+ {
+ if (queue[i].job==(int)q_u->jobid)
+ {
+ fill_job_info_1(job_info_1, &(queue[i]), i, snum);
+ }
+ }
+ r_u.job.job_info_1=job_info_1;
+ break;
+ }
+ case 2:
+ {
+ job_info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
+
+ for (i=0; i<count; i++)
+ {
+ if (queue[i].job==(int)q_u->jobid)
+ {
+ fill_job_info_2(job_info_2, &(queue[i]), i, snum);
+ }
+ }
+ r_u.job.job_info_2=job_info_2;
+ break;
+ }
+ }
+ }
+
+ r_u.status=0x0;
+
+ spoolss_io_r_getjob("",&r_u,rdata,0);
+ switch (r_u.level)
+ {
+ case 1:
+ {
+ free(job_info_1);
+ break;
+ }
+ case 2:
+ {
+ free_devmode(job_info_2->devmode);
+ free(job_info_2);
+ break;
+ }
+ }
+ if (queue) free(queue);
+
+}
+
+/****************************************************************************
+****************************************************************************/
+static void api_spoolss_getjob(pipes_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ SPOOL_Q_GETJOB q_u;
+
+ spoolss_io_q_getjob("", &q_u, data, 0);
+
+ spoolss_reply_getjob(&q_u, rdata, p->conn);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
+}
+
/*******************************************************************
\pipe\spoolss commands
********************************************************************/
@@ -3544,6 +3801,9 @@ struct api_struct api_spoolss_cmds[] =
{"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata },
{"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform },
{"SPOOLSS_SETFORM", SPOOLSS_SETFORM, api_spoolss_setform },
+ {"SPOOLSS_ENUMPRINTPROCESSORS", SPOOLSS_ENUMPRINTPROCESSORS, api_spoolss_enumprintprocessors },
+ {"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors },
+ {"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob },
{ NULL, 0, NULL }
};