Added client and server code for the GetPrintProcessorDirectory SPOOLSS
authorTim Potter <tpot@samba.org>
Mon, 10 Dec 2001 05:03:17 +0000 (05:03 +0000)
committerTim Potter <tpot@samba.org>
Mon, 10 Dec 2001 05:03:17 +0000 (05:03 +0000)
rpc.  This was supposed to fix a printer driver download bug but it didn't
but it seemed a shame to trash all this code so I'm commiting it #ifdef'ed
out in case someone needs it one day.

source/include/rpc_spoolss.h
source/libsmb/cli_spoolss.c
source/rpc_parse/parse_spoolss.c
source/rpc_server/srv_spoolss.c
source/rpc_server/srv_spoolss_nt.c
source/rpcclient/cmd_spoolss.c

index 0a8455ebbb159eab6db3c8d5370d0971fbc72223..bd9de92dcb7e156734307756e7a71a2dc53daed6 100755 (executable)
@@ -4,7 +4,8 @@
    SMB parameters and setup
    Copyright (C) Andrew Tridgell              1992-2000,
    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
-   Copyright (C) Jean Francois Micouleau      1998-2000.
+   Copyright (C) Jean Francois Micouleau      1998-2000,
+   Copyright (C) Tim Potter                  2001.
    
    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
@@ -30,7 +31,6 @@
 /* spoolss pipe: this are the calls which are not implemented ...
 #define SPOOLSS_OPENPRINTER                            0x01
 #define SPOOLSS_GETPRINTERDRIVER                       0x0b
-#define SPOOLSS_GETPRINTPROCESSORDIRECTORY             0x10
 #define SPOOLSS_READPRINTER                            0x16
 #define SPOOLSS_WAITFORPRINTERCHANGE                   0x1c
 #define SPOOLSS_ADDPORT                                        0x25
@@ -77,6 +77,7 @@
 #define SPOOLSS_DELETEPRINTERDRIVER                    0x0d
 #define SPOOLSS_ADDPRINTPROCESSOR                      0x0e
 #define SPOOLSS_ENUMPRINTPROCESSORS                    0x0f
+#define SPOOLSS_GETPRINTPROCESSORDIRECTORY             0x10
 #define SPOOLSS_STARTDOCPRINTER                                0x11
 #define SPOOLSS_STARTPAGEPRINTER                       0x12
 #define SPOOLSS_WRITEPRINTER                           0x13
@@ -1955,7 +1956,29 @@ typedef struct spool_r_enumprinterdataex
 }
 SPOOL_R_ENUMPRINTERDATAEX;
 
+typedef struct printprocessor_directory_1
+{
+       UNISTR name;
+}
+PRINTPROCESSOR_DIRECTORY_1;
+
+typedef struct spool_q_getprintprocessordirectory
+{
+       UNISTR2 name;
+       UNISTR2 environment;
+       uint32 level;
+       NEW_BUFFER *buffer;
+       uint32 offered;
+}
+SPOOL_Q_GETPRINTPROCESSORDIRECTORY;
 
+typedef struct spool_r_getprintprocessordirectory
+{
+       NEW_BUFFER *buffer;
+       uint32 needed;
+       WERROR status;
+}
+SPOOL_R_GETPRINTPROCESSORDIRECTORY;
 
 #define PRINTER_DRIVER_VERSION 2
 #define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86"
index 2663e311e02669f195d136e176bdb9a7f35649e4..d455bb719691679b835dced581dc643ee5d050ea 100644 (file)
@@ -1070,4 +1070,63 @@ done:
        return result;  
 }
 
+NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
+                                               TALLOC_CTX *mem_ctx,
+                                               char *name,
+                                               char *environment,
+                                               fstring procdir)
+{
+       prs_struct qbuf, rbuf;
+       SPOOL_Q_GETPRINTPROCESSORDIRECTORY q;
+       SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
+       NTSTATUS result;
+       int level = 1;
+       NEW_BUFFER buffer;
+       uint32 needed = 100;
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialise parse structures */
+
+
+       /* Initialise input parameters */
+
+       do {
+               init_buffer(&buffer, needed, mem_ctx);
+
+               prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+               prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+               
+               make_spoolss_q_getprintprocessordirectory(&q, name, 
+                                                         environment, level,
+                                                         &buffer, needed);
+
+               /* Marshall data and send request */
 
+               if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
+                   !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, &qbuf, &rbuf)) {
+                       result = NT_STATUS_UNSUCCESSFUL;
+                       goto done;
+               }
+               
+               /* Unmarshall response */
+               
+               if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) {
+                       result = NT_STATUS_UNSUCCESSFUL;
+                       goto done;
+               }
+
+               /* Return output parameters */
+               
+               result = werror_to_ntstatus(r.status);
+
+       } while (NT_STATUS_V(result) == 
+                NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
+
+ done:
+       prs_mem_free(&qbuf);
+       prs_mem_free(&rbuf);
+
+       return result;
+}
index a376b19c98e79161a389612e101ac0d711f267da..b4d6343946c3a445092508002957885ffcc47ea2 100644 (file)
@@ -4,8 +4,9 @@
  *  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
+ *  Copyright (C) Jean François Micouleau      1998-2000,
+ *  Copyright (C) Gerald Carter                2000,
+ *  Copyright (C) Tim Potter                  2001.
  *
  *  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
@@ -3171,6 +3172,21 @@ uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
 return the size required by a struct in the stream
 ********************************************************************/  
 
+uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
+{
+       int size=0;
+
+       size=str_len_uni(&info->name);  /* the string length       */
+       size=size+1;                    /* add the leading zero    */
+       size=size*2;                    /* convert in char         */
+
+       return size;
+}
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/  
+
 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
 {
        int size=0;
@@ -6433,3 +6449,124 @@ BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u,
 }
 
 
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/  
+
+/* 
+   uint32 GetPrintProcessorDirectory(
+       [in] unistr2 *name,
+       [in] unistr2 *environment,
+       [in] uint32 level,
+       [in,out] NEW_BUFFER buffer,
+       [in] uint32 offered,
+       [out] uint32 needed,
+       [out] uint32 returned
+   );
+
+*/
+
+BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
+{
+       DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
+
+       init_unistr2(&q_u->name, name, strlen(name)+1);
+       init_unistr2(&q_u->environment, environment, strlen(environment)+1);
+
+       q_u->level = level;
+
+       q_u->buffer = buffer;
+       q_u->offered = offered;
+
+       return True;
+}
+
+BOOL spoolss_io_q_getprintprocessordirectory(char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
+{
+       uint32 ptr;
+
+       prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;   
+
+       if (!prs_uint32("ptr", ps, depth, &ptr)) 
+               return False;
+
+       if (ptr) {
+               if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
+                       return False;
+       }
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr", ps, depth, &ptr))
+               return False;
+
+       if (ptr) {
+               if(!smb_io_unistr2("environment", &q_u->environment, True, 
+                                  ps, depth))
+                       return False;
+       }
+
+       if (!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("level",   ps, depth, &q_u->level))
+               return False;
+
+       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+               return False;
+       
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("offered", ps, depth, &q_u->offered))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/  
+
+BOOL spoolss_io_r_getprintprocessordirectory(char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
+{
+       prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+               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;
+}
+
+BOOL smb_io_printprocessordirectory_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
+{
+       prs_struct *ps=&buffer->prs;
+
+       prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
+       depth++;
+
+       buffer->struct_start=prs_offset(ps);
+
+       if (!smb_io_unistr(desc, &info->name, ps, depth))
+               return False;
+
+       return True;
+}
index 3a056dcb65bee741f299997d745aecfd5f473014..e71bcd36a9adec26ce14a76a0c75ddeb6e8abcfb 100755 (executable)
@@ -1316,6 +1316,40 @@ static BOOL api_spoolss_enumprinterdataex(pipes_struct *p)
        return True;
 }
 
+/****************************************************************************
+****************************************************************************/
+
+/* Disabled because it doesn't fix the bug I am looking at but it would be
+   a shame to throw away the code. -tpot */
+
+#if 0
+
+static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p)
+{
+       SPOOL_Q_GETPRINTPROCESSORDIRECTORY q_u;
+       SPOOL_R_GETPRINTPROCESSORDIRECTORY 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_getprintprocessordirectory("", &q_u, data, 0)) {
+               DEBUG(0,("spoolss_io_q_getprintprocessordirectory: unable to unmarshall SPOOL_Q_GETPRINTPROCESSORDIRECTORY.\n"));
+               return False;
+       }
+       
+       r_u.status = _spoolss_getprintprocessordirectory(p, &q_u, &r_u);
+                               
+       if(!spoolss_io_r_getprintprocessordirectory("", &r_u, rdata, 0)) {
+               DEBUG(0,("spoolss_io_r_getprintprocessordirectory: unable to marshall SPOOL_R_GETPRINTPROCESSORDIRECTORY.\n"));
+               return False;
+       }
+       
+       return True;
+}
+
+#endif
 
 /*******************************************************************
 \pipe\spoolss commands
@@ -1367,7 +1401,11 @@ struct api_struct api_spoolss_cmds[] =
  {"SPOOLSS_SETPRINTERDATAEX",          SPOOLSS_SETPRINTERDATAEX,          api_spoolss_setprinterdataex          },
  {"SPOOLSS_ENUMPRINTERKEY",            SPOOLSS_ENUMPRINTERKEY,            api_spoolss_enumprinterkey            },
  {"SPOOLSS_ENUMPRINTERDATAEX",         SPOOLSS_ENUMPRINTERDATAEX,         api_spoolss_enumprinterdataex         },
-
+#if 0
+ /* Disabled because it doesn't fix the bug I am looking at but it would be
+    a shame to throw away the code. -tpot */
+ {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory},
+#endif
  { NULL,                               0,                                 NULL                                  }
 };
 
index 0e98498fe3091919130194f3e6c5aa483ea5eb0a..dae3aa09c9ff2b6847f2ee98cd4738bee45c82f5 100644 (file)
@@ -7,6 +7,7 @@
  *  Copyright (C) Jean François Micouleau      1998-2000.
  *  Copyright (C) Jeremy Allison                   2001.
  *  Copyright (C) Gerald Carter                       2000-2001.
+ *  Copyright (C) Tim Potter                       2001.
  *
  *  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
@@ -7073,4 +7074,89 @@ done:
        return result;
 }
 
+/****************************************************************************
+****************************************************************************/
+
+/* Disabled because it doesn't fix the bug I am looking at but it would be
+   a shame to throw away the code. -tpot */
+
+#if 0
+
+static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
+{
+       init_unistr(&info->name, name);
+}
+
+static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, 
+                                                UNISTR2 *environment, 
+                                                NEW_BUFFER *buffer, 
+                                                uint32 offered, 
+                                                uint32 *needed)
+{
+       pstring path;
+       pstring long_archi;
+       pstring short_archi;
+       PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
+
+       unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
+
+       if (get_short_archi(short_archi, long_archi)==FALSE)
+               return WERR_INVALID_ENVIRONMENT;
+
+       if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
+               return WERR_NOMEM;
+
+       /* Not sure what to return here - are UNC names valid here?.
+          Windows returns the string: C:\WINNT\System32\spool\PRTPROCS\W32X86
+          which is pretty bogus for a RPC. */
+
+       slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
+
+       DEBUG(4,("print processor directory: [%s]\n", path));
+
+       fill_printprocessordirectory_1(info, path);
+       
+       *needed += spoolss_size_printprocessordirectory_info_1(info);
+
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(info);
+               return WERR_INSUFFICIENT_BUFFER;
+       }
+
+       smb_io_printprocessordirectory_1("", buffer, info, 0);
 
+       safe_free(info);
+       
+       if (*needed > offered)
+               return WERR_INSUFFICIENT_BUFFER;
+       else
+               return WERR_OK;
+}
+
+WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
+{
+       uint32 level = q_u->level;
+       NEW_BUFFER *buffer = NULL;
+       uint32 offered = q_u->offered;
+       uint32 *needed = &r_u->needed;
+
+       /* that's an [in out] buffer */
+       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
+       buffer = r_u->buffer;
+
+       DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
+       
+       *needed=0;
+
+       switch(level) {
+       case 1:
+               return getprintprocessordirectory_level_1
+                 (&q_u->name, &q_u->environment, buffer, offered, needed);
+       default:
+               return WERR_UNKNOWN_LEVEL;
+       }
+
+       return WERR_ACCESS_DENIED;
+}
+
+#endif
index bc003284da03d3702d287be90daccb046b9b0a36..2f80295a5344d8b09453bdc8f0adb75631441aba 100644 (file)
@@ -1149,6 +1149,37 @@ static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli,
        return NT_STATUS_OK;            
 }
 
+static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli, 
+                                           TALLOC_CTX *mem_ctx,
+                                           int argc, char **argv)
+{
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       char *servername = NULL, *environment = NULL;
+       fstring procdir;
+       
+       /* parse the command arguements */
+       if (argc < 2 || argc > 3) {
+               printf ("Usage: %s <server> [environment]\n", argv[0]);
+               return NT_STATUS_OK;
+        }
+
+       asprintf(&servername, "\\\\%s", cli->desthost);
+       strupper(servername);
+
+       asprintf(&environment, "%s", (argc == 3) ? argv[2] : 
+                PRINTER_DRIVER_ARCHITECTURE);
+
+       result = cli_spoolss_getprintprocessordirectory(
+               cli, mem_ctx, servername, environment, procdir);
+
+       if (NT_STATUS_IS_OK(result))
+               printf("%s", procdir);
+
+       SAFE_FREE(servername);
+       SAFE_FREE(environment);
+
+       return result;
+}
 
 /* List of commands exported by this module */
 struct cmd_set spoolss_commands[] = {
@@ -1169,6 +1200,7 @@ struct cmd_set spoolss_commands[] = {
        { "getprinter",         cmd_spoolss_getprinter,         PIPE_SPOOLSS, "Get printer info",                    "" },
        { "openprinter",        cmd_spoolss_open_printer_ex,    PIPE_SPOOLSS, "Open printer handle",                 "" },
        { "setdriver",          cmd_spoolss_setdriver,          PIPE_SPOOLSS, "Set printer driver",                  "" },
+       { "getprintprocdir",    cmd_spoolss_getprintprocdir, PIPE_SPOOLSS, "Get print processor directory",          "" },
 
        { NULL }
 };