summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h8
-rwxr-xr-xsource3/include/rpc_spoolss.h48
-rw-r--r--source3/printing/nt_printing.c89
-rw-r--r--source3/rpc_parse/parse_spoolss.c109
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c117
5 files changed, 363 insertions, 8 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 41a68296d2..5ddcc0e650 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1581,6 +1581,9 @@ struct passgrp_ops *unix_initialise_password_grp(void);
/*The following definitions come from printing/nt_printing.c */
int get_ntforms(nt_forms_struct **list);
+int write_ntforms(nt_forms_struct **list, int number);
+void add_a_form(nt_forms_struct **list, FORM form, int count);
+void update_a_form(nt_forms_struct **list, FORM form, int count);
int get_ntdrivers(connection_struct *conn, fstring **list, char *architecture);
void get_short_archi(char *short_archi, char *long_archi);
void dump_a_param(NT_PRINTER_PARAM *param);
@@ -2748,6 +2751,7 @@ void spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u,
void spoolss_io_r_rfnpcnex(char *desc,
SPOOL_R_RFNPCNEX *r_u,
prs_struct *ps, int depth);
+void spoolss_io_free_buffer(BUFFER *buffer);
void spoolss_io_q_getprinterdriver2(char *desc,
SPOOL_Q_GETPRINTERDRIVER2 *q_u,
prs_struct *ps, int depth);
@@ -2814,6 +2818,10 @@ void spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_
void spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
void spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
void convert_specific_param(NT_PRINTER_PARAM **param, UNISTR2 value , uint32 type, uint8 *data, uint32 len);
+void spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth);
+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);
/*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 f8e7efe81b..8476ad7691 100755
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -38,10 +38,8 @@
#define SPOOLSS_ABORTPRINTER 0x15
#define SPOOLSS_READPRINTER 0x16
#define SPOOLSS_WAITFORPRINTERCHANGE 0x1c
-#define SPOOLSS_ADDFORM 0x1e
#define SPOOLSS_DELETEFORM 0x1f
#define SPOOLSS_GETFORM 0x20
-#define SPOOLSS_SETFORM 0x21
#define SPOOLSS_ENUMMONITORS 0x24
#define SPOOLSS_ADDPORT 0x25
#define SPOOLSS_CONFIGUREPORT 0x26
@@ -93,6 +91,8 @@
#define SPOOLSS_GETPRINTERDATA 0x1a
#define SPOOLSS_SETPRINTERDATA 0x1b
#define SPOOLSS_CLOSEPRINTER 0x1d
+#define SPOOLSS_ADDFORM 0x1e
+#define SPOOLSS_SETFORM 0x21
#define SPOOLSS_ENUMFORMS 0x22
#define SPOOLSS_ENUMPORTS 0x23
#define SPOOLSS_ENUMPRINTPROCESSORDATATYPES 0x33
@@ -1398,12 +1398,52 @@ typedef struct spool_q_setprinterdata
uint8 *data;
uint32 real_len;
uint32 numeric_data;
-}SPOOL_Q_SETPRINTERDATA;
+} SPOOL_Q_SETPRINTERDATA;
typedef struct spool_r_setprinterdata
{
uint32 status;
-}SPOOL_R_SETPRINTERDATA;
+} SPOOL_R_SETPRINTERDATA;
+
+typedef struct _form
+{
+ uint32 flags;
+ uint32 name_ptr;
+ uint32 size_x;
+ uint32 size_y;
+ uint32 left;
+ uint32 top;
+ uint32 right;
+ uint32 bottom;
+ UNISTR2 name;
+} FORM;
+
+typedef struct spool_q_addform
+{
+ PRINTER_HND handle;
+ uint32 level;
+ uint32 level2;
+ FORM form;
+} SPOOL_Q_ADDFORM;
+
+typedef struct spool_r_addform
+{
+ uint32 status;
+} SPOOL_R_ADDFORM;
+
+typedef struct spool_q_setform
+{
+ PRINTER_HND handle;
+ UNISTR2 name;
+ uint32 level;
+ uint32 level2;
+ FORM form;
+} SPOOL_Q_SETFORM;
+
+typedef struct spool_r_setform
+{
+ uint32 status;
+} SPOOL_R_SETFORM;
#define PRINTER_DRIVER_VERSION 2
#define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86"
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 76b9ee909d..0757d08b8c 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -87,11 +87,98 @@ int get_ntforms(nt_forms_struct **list)
return(total);
}
+/****************************************************************************
+write a form struct list
+****************************************************************************/
+int write_ntforms(nt_forms_struct **list, int number)
+{
+ FILE *f;
+ pstring line;
+ char *file = lp_nt_forms();
+ int total=0;
+ int i;
+
+ *line=0;
+
+ DEBUG(6,("write_ntforms\n"));
+
+ if((f = sys_fopen(file, "w")) == NULL)
+ {
+ DEBUG(1, ("cannot create forms file [%s]\n", file));
+ return(0);
+ }
+
+ for (i=0; i<number;i++)
+ {
+
+ fprintf(f,"%s:%d:%d:%d:%d:%d:%d:%d\n", (*list)[i].name,
+ (*list)[i].flag, (*list)[i].width, (*list)[i].length,
+ (*list)[i].left, (*list)[i].top, (*list)[i].right, (*list)[i].bottom);
+
+ DEBUGADD(7,("adding entry [%s]\n", (*list)[i].name));
+ }
+
+ fclose(f);
+ DEBUGADD(6,("closing file\n"));
+ return(total);
+}
+
+/****************************************************************************
+add a form struct at the end of the list
+****************************************************************************/
+void add_a_form(nt_forms_struct **list, FORM form, int count)
+{
+ int n=count;
+
+ *list=Realloc(*list, (n+1)*sizeof(nt_forms_struct));
+
+ (*list)[n].flag=form.flags;
+ (*list)[n].width=form.size_x;
+ (*list)[n].length=form.size_y;
+ (*list)[n].left=form.left;
+ (*list)[n].top=form.top;
+ (*list)[n].right=form.right;
+ (*list)[n].bottom=form.bottom;
+
+ if (form.name_ptr)
+ {
+ unistr2_to_ascii((*list)[n].name, &(form.name), sizeof((*list)[n].name)-1);
+ }
+
+}
+
+/****************************************************************************
+update a form struct
+****************************************************************************/
+void update_a_form(nt_forms_struct **list, FORM form, int count)
+{
+ int n=0;
+ fstring form_name;
+ unistr2_to_ascii(form_name, &(form.name), sizeof(form_name)-1);
+
+ DEBUG(6, ("[%s]\n", form_name));
+ for (n=0; n<count; n++)
+ {
+ DEBUGADD(6, ("n [%d]:[%s]\n", n, (*list)[n].name));
+ if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
+ break;
+ }
+
+ if (n==count) return;
+
+ (*list)[n].flag=form.flags;
+ (*list)[n].width=form.size_x;
+ (*list)[n].length=form.size_y;
+ (*list)[n].left=form.left;
+ (*list)[n].top=form.top;
+ (*list)[n].right=form.right;
+ (*list)[n].bottom=form.bottom;
+}
/****************************************************************************
get the nt drivers list
-open the rectory and look-up the matching names
+open the directory and look-up the matching names
****************************************************************************/
int get_ntdrivers(connection_struct *conn, fstring **list, char *architecture)
{
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 8f5c85c158..c090239f38 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -471,6 +471,7 @@ void spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_st
case 0x1:
case 0x3:
case 0x4:
+ case 0x7:
prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size);
prs_align(ps);
break;
@@ -1387,6 +1388,23 @@ static void spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER
}
}
+/*******************************************************************
+ * read a uint8 buffer of size *size.
+ * allocate memory for it
+ * return a pointer to the allocated memory and the size
+ * return NULL and a size of 0 if the buffer is empty
+ *
+ * jfmxxxx: fix it to also write a buffer
+ ********************************************************************/
+void spoolss_io_free_buffer(BUFFER *buffer)
+{
+ DEBUG(8,("spoolss_io_free_buffer\n"));
+
+ if (buffer->ptr != 0x0000)
+ {
+ free(buffer->data);
+ }
+}
/*******************************************************************
* read a structure.
@@ -3341,6 +3359,7 @@ void spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st
case 0x1:
case 0x3:
case 0x4:
+ case 0x7:
q_u->data=(uint8 *)malloc(q_u->max_len * sizeof(uint8));
prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len);
prs_align(ps);
@@ -3387,3 +3406,93 @@ void convert_specific_param(NT_PRINTER_PARAM **param, UNISTR2 value , uint32 typ
DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
}
+
+/*******************************************************************
+********************************************************************/
+static void spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_addform");
+ depth++;
+ prs_align(ps);
+
+ if (ptr!=0)
+ {
+ prs_uint32("flags", ps, depth, &(f->flags));
+ prs_uint32("name_ptr", ps, depth, &(f->name_ptr));
+ prs_uint32("size_x", ps, depth, &(f->size_x));
+ prs_uint32("size_y", ps, depth, &(f->size_y));
+ prs_uint32("left", ps, depth, &(f->left));
+ prs_uint32("top", ps, depth, &(f->top));
+ prs_uint32("right", ps, depth, &(f->right));
+ prs_uint32("bottom", ps, depth, &(f->bottom));
+
+ smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth);
+ }
+}
+
+/*******************************************************************
+********************************************************************/
+void spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0;
+ prs_debug(ps, depth, desc, "spoolss_io_q_addform");
+ depth++;
+
+ prs_align(ps);
+ smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ prs_uint32("level2", ps, depth, &(q_u->level2));
+
+ if (q_u->level==1)
+ {
+ prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
+ spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
+ }
+}
+
+/*******************************************************************
+********************************************************************/
+void spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_addform");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+********************************************************************/
+void spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0;
+ prs_debug(ps, depth, desc, "spoolss_io_q_setform");
+ depth++;
+
+ prs_align(ps);
+ smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth);
+ smb_io_unistr2("", &(q_u->name), True, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("level", ps, depth, &(q_u->level));
+ prs_uint32("level2", ps, depth, &(q_u->level2));
+
+ if (q_u->level==1)
+ {
+ prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
+ spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
+ }
+}
+
+/*******************************************************************
+********************************************************************/
+void spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_setform");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 5b3ea4502a..c8df41a810 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -430,6 +430,7 @@ static void api_spoolss_open_printer(pipes_struct *p, prs_struct *data, prs_stru
static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *type,
uint32 *numeric_data, uint8 **data, uint32 *needed)
{
+ int i;
if (!strcmp(value, "BeepEnabled"))
{
@@ -492,8 +493,14 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *ty
*type = 0x1;
*data = (uint8 *)malloc( size*sizeof(uint8) );
ZERO_STRUCTP(*data);
- make_unistr((UNISTR *)*data, directory);
- *needed = 2*(strlen(directory)+1);
+
+ /* it's done by hand ready to go on the wire */
+ for (i=0; i<strlen(directory); i++)
+ {
+ (*data)[2*i]=directory[i];
+ (*data)[2*i+1]='\0';
+ }
+ *needed = 2*(strlen(directory)+1);
return True;
}
@@ -503,7 +510,11 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *ty
*type = 0x1;
*data = (uint8 *)malloc( size*sizeof(uint8) );
ZERO_STRUCTP(*data);
- make_unistr((UNISTR *)*data, directory);
+ for (i=0; i<strlen(directory); i++)
+ {
+ (*data)[2*i]=directory[i];
+ (*data)[2*i+1]='\0';
+ }
*needed = 2*(strlen(directory)+1);
return True;
}
@@ -1824,6 +1835,8 @@ static void api_spoolss_enumprinters(pipes_struct *p, prs_struct *data,
spoolss_io_q_enumprinters("", &q_u, data, 0);
spoolss_reply_enumprinters(&q_u, rdata, p->conn);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
@@ -2124,6 +2137,8 @@ static void api_spoolss_getprinterdriver2(pipes_struct *p, prs_struct *data,
spoolss_io_q_getprinterdriver2("", &q_u, data, 0);
spoolss_reply_getprinterdriver2(&q_u, rdata);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
/****************************************************************************
@@ -2599,6 +2614,8 @@ static void api_spoolss_addjob(pipes_struct *p, prs_struct *data,
spoolss_io_q_addjob("", &q_u, data, 0);
spoolss_reply_addjob(&q_u, rdata);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
/****************************************************************************
@@ -2757,6 +2774,8 @@ static void api_spoolss_enumjobs(pipes_struct *p, prs_struct *data,
spoolss_io_q_enumjobs("", &q_u, data, 0);
spoolss_reply_enumjobs(&q_u, rdata, p->conn);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
/****************************************************************************
@@ -2958,6 +2977,8 @@ static void api_spoolss_enumprinterdrivers(pipes_struct *p, prs_struct *data,
spoolss_io_q_enumprinterdrivers("", &q_u, data, 0);
spoolss_reply_enumprinterdrivers(&q_u, rdata, p->conn);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
@@ -3033,8 +3054,12 @@ static void api_spoolss_enumforms(pipes_struct *p, prs_struct *data,
spoolss_io_q_enumforms("", &q_u, data, 0);
spoolss_reply_enumforms(&q_u, rdata);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
+/****************************************************************************
+****************************************************************************/
static void fill_port_2(PORT_INFO_2 *port, char *name)
{
make_unistr(&(port->port_name), name);
@@ -3101,6 +3126,8 @@ static void api_spoolss_enumports(pipes_struct *p, prs_struct *data,
spoolss_io_q_enumports("", &q_u, data, 0);
spoolss_reply_enumports(&q_u, rdata);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
/****************************************************************************
@@ -3225,6 +3252,8 @@ static void api_spoolss_getprinterdriverdirectory(pipes_struct *p, prs_struct *d
spoolss_io_q_getprinterdriverdir("", &q_u, data, 0);
spoolss_reply_getprinterdriverdirectory(&q_u, rdata);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
}
/****************************************************************************
@@ -3381,6 +3410,86 @@ static void api_spoolss_setprinterdata(pipes_struct *p, prs_struct *data,
free(q_u.data);
}
+/****************************************************************************
+****************************************************************************/
+static void spoolss_reply_addform(SPOOL_Q_ADDFORM *q_u, prs_struct *rdata)
+{
+ SPOOL_R_ADDFORM r_u;
+ int pnum=0;
+ int count=0;
+ nt_forms_struct *list=NULL;
+
+ DEBUG(5,("spoolss_reply_addform\n"));
+
+ pnum = find_printer_index_by_hnd(&(q_u->handle));
+
+ if (OPEN_HANDLE(pnum))
+ {
+ count=get_ntforms(&list);
+
+ add_a_form(&list, q_u->form, count);
+
+ write_ntforms(&list, count+1);
+
+ free(list);
+ }
+
+ r_u.status = 0x0;
+ spoolss_io_r_addform("", &r_u, rdata, 0);
+}
+
+/****************************************************************************
+****************************************************************************/
+static void api_spoolss_addform(pipes_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ SPOOL_Q_ADDFORM q_u;
+
+ spoolss_io_q_addform("", &q_u, data, 0);
+
+ spoolss_reply_addform(&q_u, rdata);
+}
+
+
+/****************************************************************************
+****************************************************************************/
+static void spoolss_reply_setform(SPOOL_Q_SETFORM *q_u, prs_struct *rdata)
+{
+ SPOOL_R_SETFORM r_u;
+ int pnum=0;
+ int count=0;
+ nt_forms_struct *list=NULL;
+
+ DEBUG(5,("spoolss_reply_setform\n"));
+
+ pnum = find_printer_index_by_hnd(&(q_u->handle));
+
+ if (OPEN_HANDLE(pnum))
+ {
+ count=get_ntforms(&list);
+
+ update_a_form(&list, q_u->form, count);
+
+ write_ntforms(&list, count);
+
+ free(list);
+ }
+ r_u.status = 0x0;
+ spoolss_io_r_setform("", &r_u, rdata, 0);
+}
+
+/****************************************************************************
+****************************************************************************/
+static void api_spoolss_setform(pipes_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ SPOOL_Q_SETFORM q_u;
+
+ spoolss_io_q_setform("", &q_u, data, 0);
+
+ spoolss_reply_setform(&q_u, rdata);
+}
+
/*******************************************************************
\pipe\spoolss commands
********************************************************************/
@@ -3413,6 +3522,8 @@ struct api_struct api_spoolss_cmds[] =
{"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory },
{"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata },
{"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata },
+ {"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform },
+ {"SPOOLSS_SETFORM", SPOOLSS_SETFORM, api_spoolss_setform },
{ NULL, 0, NULL }
};