summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsource3/include/rpc_spoolss.h19
-rw-r--r--source3/lib/util_unistr.c32
-rw-r--r--source3/rpc_parse/parse_spoolss.c95
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c31
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c132
5 files changed, 282 insertions, 27 deletions
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
index d2b5efac07..71854b5d89 100755
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -27,7 +27,6 @@
#define STRING 2
/* spoolss pipe: this are the calls which are not implemented ...
-#define SPOOLSS_OPENPRINTER 0x01
#define SPOOLSS_GETPRINTERDRIVER 0x0b
#define SPOOLSS_READPRINTER 0x16
#define SPOOLSS_WAITFORPRINTERCHANGE 0x1c
@@ -59,6 +58,7 @@
/* those are implemented */
#define SPOOLSS_ENUMPRINTERS 0x00
+#define SPOOLSS_OPENPRINTER 0x01
#define SPOOLSS_SETJOB 0x02
#define SPOOLSS_GETJOB 0x03
#define SPOOLSS_ENUMJOBS 0x04
@@ -514,6 +514,23 @@ typedef struct _printer_default
}
PRINTER_DEFAULT;
+/* SPOOL_Q_OPEN_PRINTER request to open a printer */
+typedef struct spool_q_open_printer
+{
+ uint32 printername_ptr;
+ UNISTR2 printername;
+ PRINTER_DEFAULT printer_default;
+}
+SPOOL_Q_OPEN_PRINTER;
+
+/* SPOOL_R_OPEN_PRINTER reply to an open printer */
+typedef struct spool_r_open_printer
+{
+ POLICY_HND handle; /* handle used along all transactions (20*uint8) */
+ WERROR status;
+}
+SPOOL_R_OPEN_PRINTER;
+
/* SPOOL_Q_OPEN_PRINTER_EX request to open a printer */
typedef struct spool_q_open_printer_ex
{
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 060460bb2c..a1cff26169 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -743,3 +743,35 @@ BOOL trim_string_wa(smb_ucs2_t *s, const char *front,
else *b = 0;
return trim_string_w(s, f, b);
}
+
+/*******************************************************************
+ returns the length in number of wide characters
+ ******************************************************************/
+int unistrlen(uint16 *s)
+{
+ int len;
+
+ if (!s)
+ return -1;
+
+ for (len=0; *s; s++,len++);
+
+ return len;
+}
+
+/*******************************************************************
+ Strcpy for unicode strings. returns length (in num of wide chars)
+********************************************************************/
+
+int unistrcpy(uint16 *dst, uint16 *src)
+{
+ int num_wchars = 0;
+
+ while (*src) {
+ *dst++ = *src++;
+ num_wchars++;
+ }
+ *dst = 0;
+
+ return num_wchars;
+}
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 97e2020a3e..5c2dd6b48f 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -880,12 +880,12 @@ BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2
* called from spoolss_q_open_printer_ex (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
+BOOL spoolss_io_q_open_printer(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_ex");
+ prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
depth++;
if (!prs_align(ps))
@@ -902,35 +902,66 @@ BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_
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 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(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 (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
+
+ if (!prs_werror("status code", ps, depth, &(r_u->status)))
return False;
return True;
}
+
/*******************************************************************
- * init a structure.
+ * read a structure.
+ * called from spoolss_q_open_printer_ex (srv_spoolss.c)
********************************************************************/
-BOOL make_spoolss_q_deleteprinterdriver(
- TALLOC_CTX *mem_ctx,
- SPOOL_Q_DELETEPRINTERDRIVER *q_u,
- const char *server,
- const char* arch,
- const char* driver
-)
+
+BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
{
- DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
+ 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_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
+ return False;
+ if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
+ return False;
- q_u->server_ptr = (server!=NULL)?1:0;
+ if (!prs_align(ps))
+ return False;
- /* these must be NULL terminated or else NT4 will
- complain about invalid parameters --jerry */
- init_unistr2(&q_u->server, server, strlen(server)+1);
- init_unistr2(&q_u->arch, arch, strlen(arch)+1);
- init_unistr2(&q_u->driver, driver, strlen(driver)+1);
+ 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;
}
@@ -961,6 +992,32 @@ BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_
}
/*******************************************************************
+ * 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, strlen(server)+1);
+ init_unistr2(&q_u->arch, arch, strlen(arch)+1);
+ init_unistr2(&q_u->driver, driver, strlen(driver)+1);
+
+
+ return True;
+}
+
+
+/*******************************************************************
* make a structure.
********************************************************************/
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 3838632021..e6c152c668 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -24,6 +24,36 @@
#include "includes.h"
/********************************************************************
+ * api_spoolss_open_printer_ex (rarely seen - older call)
+ ********************************************************************/
+
+static BOOL api_spoolss_open_printer(pipes_struct *p)
+{
+ SPOOL_Q_OPEN_PRINTER q_u;
+ SPOOL_R_OPEN_PRINTER r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!spoolss_io_q_open_printer("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_open_printer: unable to unmarshall SPOOL_Q_OPEN_PRINTER.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_open_printer( p, &q_u, &r_u);
+
+ if (!spoolss_io_r_open_printer("",&r_u,rdata,0)){
+ DEBUG(0,("spoolss_io_r_open_printer: unable to marshall SPOOL_R_OPEN_PRINTER.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/********************************************************************
* api_spoolss_open_printer_ex
********************************************************************/
@@ -1375,6 +1405,7 @@ static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p)
struct api_struct api_spoolss_cmds[] =
{
+ {"SPOOLSS_OPENPRINTER", SPOOLSS_OPENPRINTER, api_spoolss_open_printer },
{"SPOOLSS_OPENPRINTEREX", SPOOLSS_OPENPRINTEREX, api_spoolss_open_printer_ex },
{"SPOOLSS_GETPRINTERDATA", SPOOLSS_GETPRINTERDATA, api_spoolss_getprinterdata },
{"SPOOLSS_CLOSEPRINTER", SPOOLSS_CLOSEPRINTER, api_spoolss_closeprinter },
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 717e51462b..e119825f31 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -758,17 +758,136 @@ static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low,
}
/********************************************************************
+ Copy routines used by convert_to_openprinterex()
+ *******************************************************************/
+
+static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
+{
+ DEVICEMODE *d;
+ int len;
+
+ if (!devmode)
+ return NULL;
+
+ DEBUG (8,("dup_devmode\n"));
+
+ /* bulk copy first */
+
+ d = talloc_memdup(ctx, devmode, sizeof(DEVICEMODE));
+ if (!d)
+ return NULL;
+
+ /* dup the pointer members separately */
+
+ len = unistrlen(devmode->devicename.buffer);
+ if (len != -1) {
+ d->devicename.buffer = talloc(ctx, len*2);
+ if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
+ return NULL;
+ }
+
+
+ len = unistrlen(devmode->formname.buffer);
+ if (len != -1) {
+ d->devicename.buffer = talloc(ctx, len*2);
+ if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
+ return NULL;
+ }
+
+ d->private = talloc_memdup(ctx, devmode->private, devmode->driverextra);
+
+ return d;
+}
+
+static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr)
+{
+ if (!new_ctr || !ctr)
+ return;
+
+ DEBUG(8,("copy_devmode_ctr\n"));
+
+ new_ctr->size = ctr->size;
+ new_ctr->devmode_ptr = ctr->devmode_ptr;
+
+ if(ctr->devmode_ptr)
+ new_ctr->devmode = dup_devicemode(ctx, ctr->devmode);
+}
+
+static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def)
+{
+ if (!new_def || !def)
+ return;
+
+ DEBUG(8,("copy_printer_defaults\n"));
+
+ new_def->datatype_ptr = def->datatype_ptr;
+
+ if (def->datatype_ptr)
+ copy_unistr2(&new_def->datatype, &def->datatype);
+
+ copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont);
+
+ new_def->access_required = def->access_required;
+}
+
+/********************************************************************
+ * Convert a SPOOL_Q_OPEN_PRINTER structure to a
+ * SPOOL_Q_OPEN_PRINTER_EX structure
+ ********************************************************************/
+
+static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
+{
+ if (!q_u_ex || !q_u)
+ return;
+
+ DEBUG(8,("convert_to_openprinterex\n"));
+
+ q_u_ex->printername_ptr = q_u->printername_ptr;
+
+ if (q_u->printername_ptr)
+ copy_unistr2(&q_u_ex->printername, &q_u->printername);
+
+ copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
+}
+
+/********************************************************************
* spoolss_open_printer
*
* called from the spoolss dispatcher
********************************************************************/
-WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
+WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u)
{
-#if 0
- WERROR result = WERR_OK;
-#endif
+ SPOOL_Q_OPEN_PRINTER_EX q_u_ex;
+ SPOOL_R_OPEN_PRINTER_EX r_u_ex;
+
+ if (!q_u || !r_u)
+ return WERR_NOMEM;
+
+ ZERO_STRUCT(q_u_ex);
+ ZERO_STRUCT(r_u_ex);
+
+ /* convert the OpenPrinter() call to OpenPrinterEx() */
+
+ convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
+
+ r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex);
+
+ /* convert back to OpenPrinter() */
+
+ memcpy(r_u, &r_u_ex, sizeof(*r_u));
+
+ return r_u->status;
+}
+
+/********************************************************************
+ * spoolss_open_printer
+ *
+ * called from the spoolss dispatcher
+ ********************************************************************/
+WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
+{
UNISTR2 *printername = NULL;
PRINTER_DEFAULT *printer_default = &q_u->printer_default;
/* uint32 user_switch = q_u->user_switch; - notused */
@@ -6254,13 +6373,12 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
return WERR_ACCESS_DENIED;
}
+ update_c_setprinter(False);
+
srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0);
free_a_printer(&printer,2);
- update_c_setprinter(False);
-
-
return WERR_OK;
}