sync 3.0 into HEAD for the last time
[kai/samba.git] / source3 / rpc_client / cli_spoolss.c
index bdd74070268977d814389643fc5132e9e40136aa..8f5f2413deec38d4daa829568fc433970912ddd7 100644 (file)
@@ -56,8 +56,9 @@ static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         PRINTER_INFO_0  *inf;
 
         inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
+       memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                 smb_io_printer_info_0("", buffer, &inf[i], 0);
@@ -75,8 +76,9 @@ static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         PRINTER_INFO_1  *inf;
 
         inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
+       memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                 smb_io_printer_info_1("", buffer, &inf[i], 0);
@@ -94,8 +96,9 @@ static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         PRINTER_INFO_2  *inf;
 
         inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
+       memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                /* a little initialization as we go */
@@ -115,8 +118,9 @@ static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         PRINTER_INFO_3  *inf;
 
         inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
+       memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                inf[i].secdesc = NULL;
@@ -135,6 +139,7 @@ static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         PORT_INFO_1 *inf;
 
         inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
+       memset(inf, 0, returned*sizeof(PORT_INFO_1));
 
         prs_set_offset(&buffer->prs, 0);
 
@@ -154,6 +159,7 @@ static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         PORT_INFO_2 *inf;
 
         inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
+       memset(inf, 0, returned*sizeof(PORT_INFO_2));
 
         prs_set_offset(&buffer->prs, 0);
 
@@ -173,8 +179,9 @@ static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         DRIVER_INFO_1 *inf;
 
         inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
+       memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                 smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
@@ -192,8 +199,9 @@ static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         DRIVER_INFO_2 *inf;
 
         inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
+       memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                 smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
@@ -211,8 +219,9 @@ static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
         DRIVER_INFO_3 *inf;
 
         inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
+       memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
 
-        buffer->prs.data_offset=0;
+       prs_set_offset(&buffer->prs,0);
 
         for (i=0; i<returned; i++) {
                 smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
@@ -230,6 +239,7 @@ static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
        DRIVER_DIRECTORY_1 *inf;
  
         inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
+       memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
 
         prs_set_offset(&buffer->prs, 0);
 
@@ -265,8 +275,8 @@ static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
  ********************************************************************************/
 
 WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                               char *printername, char *datatype, uint32 access_required,
-                               char *station, char *username, POLICY_HND *pol)
+                               const char *printername, const char *datatype, uint32 access_required,
+                               const char *station, const char *username, POLICY_HND *pol)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_OPEN_PRINTER_EX q;
@@ -489,7 +499,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                              uint32 offered, uint32 *needed,
-                             uint32 level, int *num_ports, PORT_INFO_CTR *ctr)
+                             uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_ENUMPORTS q;
@@ -501,8 +511,8 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-        slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (server);
+        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(server);
 
        /* Initialise input parameters */
        
@@ -661,7 +671,8 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
                
-       make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
+       if (!make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command))
+               goto done;
 
        /* Marshall data and send request */
 
@@ -709,7 +720,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
                                    TALLOC_CTX *mem_ctx, 
                                    uint32 offered, uint32 *needed,
                                    POLICY_HND *pol, uint32 level, 
-                                   char *env, PRINTER_DRIVER_CTR *ctr)
+                                   const char *env, int version, PRINTER_DRIVER_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_GETPRINTERDRIVER2 q;
@@ -721,8 +732,8 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-       fstrcpy (server, cli->desthost);
-       strupper (server);
+       fstrcpy(server, cli->desthost);
+       strupper_m(server);
 
        /* Initialise input parameters */
 
@@ -731,7 +742,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
 
-       make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2,
+       make_spoolss_q_getprinterdriver2(&q, pol, env, level, version, 2,
                                         &buffer, offered);
 
        /* Marshall data and send request */
@@ -767,6 +778,9 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
        case 3:
                decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
                break;
+       default:
+               DEBUG(10, ("cli_spoolss_getprinterdriver: unknown info level %d", level));
+               return WERR_UNKNOWN_LEVEL;
        }
 
  done:
@@ -785,7 +799,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
 WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, 
                                       TALLOC_CTX *mem_ctx,
                                       uint32 offered, uint32 *needed,
-                                      uint32 level, char *env,
+                                      uint32 level, const char *env,
                                       uint32 *num_drivers,
                                       PRINTER_DRIVER_CTR *ctr)
 {
@@ -799,8 +813,8 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-        slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (server);
+        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(server);
 
        /* Initialise input parameters */
 
@@ -848,6 +862,10 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
                case 3:
                        decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
                        break;
+               default:
+                       DEBUG(10, ("cli_spoolss_enumprinterdrivers: unknown info level %d\n",
+                                  level));
+                       return WERR_UNKNOWN_LEVEL;
                }
        }
 
@@ -881,8 +899,8 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-        slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (server);
+        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(server);
 
        /* Initialise input parameters */
 
@@ -949,8 +967,8 @@ WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
        
-        slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (server);
+        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(server);
 
        /* Initialise input parameters */
 
@@ -1003,10 +1021,10 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-        slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (client);
-        slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (server);
+        slprintf(client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(client);
+        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(server);
        fstrcpy  (user, cli->user_name);
 
        /* Initialise input parameters */
@@ -1049,8 +1067,8 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
  * the driver files
  */
 WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, 
-                                       TALLOC_CTX *mem_ctx, char *arch,
-                                       char *driver)
+                                       TALLOC_CTX *mem_ctx, const char *arch,
+                                       const char *driver)
 {
        prs_struct                      qbuf, rbuf;
        SPOOL_Q_DELETEPRINTERDRIVER     q;
@@ -1066,8 +1084,8 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
 
-        slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper (server);
+        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+        strupper_m(server);
 
        /* Write the request */
 
@@ -1225,8 +1243,8 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
  */
 
 WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                          POLICY_HND *handle, uint32 level, char *form_name,
-                          FORM *form)
+                          POLICY_HND *handle, uint32 level, 
+                          const char *form_name, FORM *form)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_SETFORM q;
@@ -1287,8 +1305,8 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                           uint32 offered, uint32 *needed,
-                          POLICY_HND *handle, char *formname, uint32 level
-                          FORM_1 *form)
+                          POLICY_HND *handle, const char *formname
+                          uint32 level, FORM_1 *form)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_GETFORM q;
@@ -1328,8 +1346,16 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        if (needed)
                *needed = r.needed;
 
-       if (W_ERROR_IS_OK(result)) 
-               smb_io_form_1("", r.buffer, form, 0);
+       if (W_ERROR_IS_OK(result)) {
+               switch(level) {
+               case 1:
+                       smb_io_form_1("", r.buffer, form, 0);
+                       break;
+               default:
+                       DEBUG(10, ("cli_spoolss_getform: unknown info level %d", level));
+                       return WERR_UNKNOWN_LEVEL;
+               }
+       }
 
  done:
        prs_mem_free(&qbuf);
@@ -1351,7 +1377,7 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
  */
 
 WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                             POLICY_HND *handle, char *form_name)
+                             POLICY_HND *handle, const char *form_name)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_DELETEFORM q;
@@ -1398,7 +1424,7 @@ static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
        int i;
 
        *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
-       buffer->prs.data_offset = 0;
+       prs_set_offset(&buffer->prs,0);
 
        for (i = 0; i < num_forms; i++)
                smb_io_form_1("", buffer, &((*forms)[i]), 0);
@@ -1480,7 +1506,7 @@ static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
        uint32 i;
 
        *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1));
-       buffer->prs.data_offset = 0;
+       prs_set_offset(&buffer->prs,0);
 
        for (i = 0; i < num_jobs; i++) 
                smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
@@ -1492,7 +1518,7 @@ static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
        uint32 i;
 
        *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2));
-       buffer->prs.data_offset = 0;
+       prs_set_offset(&buffer->prs,0);
 
        for (i = 0; i < num_jobs; i++) 
                smb_io_job_info_2("", buffer, &((*jobs)[i]), 0);
@@ -1873,9 +1899,8 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                  uint32 offered, uint32 *needed,
-                                 POLICY_HND *hnd, char *valuename, 
-                                 uint32 *data_type, char **data, 
-                                 uint32 *data_size)
+                                 POLICY_HND *hnd, const char *valuename, 
+                                 REGISTRY_VALUE *value)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_GETPRINTERDATA q;
@@ -1915,16 +1940,9 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Return output parameters */
 
-       if (data_type)
-               *data_type = r.type;
-
-       if (data) {
-               *data = (char *)talloc(mem_ctx, r.needed);
-               memcpy(*data, r.data, r.needed);
-       }
-
-       if (data_size) 
-               *data_size = r.needed;
+       value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
+       value->type = r.type;
+       value->size = r.size;
 
  done:
        prs_mem_free(&qbuf);
@@ -1935,9 +1953,9 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                    uint32 offered, uint32 *needed,
-                                   POLICY_HND *hnd, char *keyname, 
-                                   char *valuename, uint32 *data_type, 
-                                   char **data, uint32 *data_size)
+                                   POLICY_HND *hnd, const char *keyname, 
+                                   const char *valuename, 
+                                   REGISTRY_VALUE *value)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_GETPRINTERDATAEX q;
@@ -1977,16 +1995,9 @@ WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Return output parameters */
 
-       if (data_type)
-               *data_type = r.type;
-
-       if (data) {
-               *data = (char *)talloc(mem_ctx, r.needed);
-               memcpy(*data, r.data, r.needed);
-       }
-
-       if (data_size) 
-               *data_size = r.needed;
+       value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
+       value->type = r.type;
+       value->size = r.needed;
 
  done:
        prs_mem_free(&qbuf);
@@ -1998,9 +2009,7 @@ WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /* Set printer data */
 
 WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, char *value, 
-                                 uint32 data_type, char *data, 
-                                 uint32 data_size)
+                                 POLICY_HND *hnd, REGISTRY_VALUE *value)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_SETPRINTERDATA q;
@@ -2017,7 +2026,8 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Initialise input parameters */
 
-        make_spoolss_q_setprinterdata(&q, hnd, value, data_type, data, data_size);
+        make_spoolss_q_setprinterdata(
+               &q, hnd, value->valuename, value->type, (char *)value->data_p, value->size);
 
        /* Marshall data and send request */
 
@@ -2043,9 +2053,8 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 }
 
 WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                   POLICY_HND *hnd, char * key, char *value, 
-                                   uint32 data_type, char *data, 
-                                   uint32 data_size)
+                                   POLICY_HND *hnd, char *keyname, 
+                                   REGISTRY_VALUE *value)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_SETPRINTERDATAEX q;
@@ -2062,7 +2071,9 @@ WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Initialise input parameters */
 
-        make_spoolss_q_setprinterdataex(&q, hnd, key, value, data_type, data, data_size);
+        make_spoolss_q_setprinterdataex(
+               &q, hnd, keyname, value->valuename, value->type, (char *)value->data_p, 
+               value->size);
 
        /* Marshall data and send request */
 
@@ -2093,8 +2104,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                   POLICY_HND *hnd, uint32 ndx,
                                   uint32 value_offered, uint32 data_offered,
                                   uint32 *value_needed, uint32 *data_needed,
-                                  char **value, uint32 *data_type, char **data, 
-                                  uint32 *data_size)
+                                  REGISTRY_VALUE *value)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_ENUMPRINTERDATA q;
@@ -2130,31 +2140,21 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                goto done;
 
        /* Return data */
-
+       
        if (value_needed)
                *value_needed = r.realvaluesize;
 
        if (data_needed)
                *data_needed = r.realdatasize;
 
-       if (data_type) 
-               *data_type = r.type;
-
        if (value) {
-               fstring the_value;
-
-               rpcstr_pull(the_value, r.value, sizeof(the_value), -1, 
+               rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1,
                            STR_TERMINATE);
-               
-               *value = talloc_strdup(mem_ctx, the_value);
+               value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize);
+               value->type = r.type;
+               value->size = r.realdatasize;
        }
 
-       if (data)
-               *data = talloc_memdup(mem_ctx, r.data, r.realdatasize);
-
-       if (data_size)
-               *data_size = r.realdatasize;
-
  done:
        prs_mem_free(&qbuf);
        prs_mem_free(&rbuf);
@@ -2164,8 +2164,8 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                     uint32 offered, uint32 *needed,
-                                    POLICY_HND *hnd, char *key,
-                                    uint32 *returned, PRINTER_ENUM_VALUES **values)
+                                    POLICY_HND *hnd, const char *keyname, 
+                                    REGVAL_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_ENUMPRINTERDATAEX q;
@@ -2183,7 +2183,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Initialise input parameters */
 
-        make_spoolss_q_enumprinterdataex(&q, hnd, key, offered);
+        make_spoolss_q_enumprinterdataex(&q, hnd, keyname, offered);
 
        /* Marshall data and send request */
 
@@ -2206,23 +2206,16 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Return data */
 
-       *returned = r.returned;
-
-       /* Again, we have to deep copy the results on the passed in
-          tdb context as they will disappear after the prs_free at
-          the end of this function. */
-
-       *values = talloc(mem_ctx, sizeof(PRINTER_ENUM_VALUES) * r.returned);
+       ZERO_STRUCTP(ctr);
+       regval_ctr_init(ctr);
 
        for (i = 0; i < r.returned; i++) {
                PRINTER_ENUM_VALUES *v = &r.ctr.values[i];
+               fstring name;
 
-               (*values)[i].valuename.buffer = talloc(mem_ctx, v->value_len * 2);
-               unistrcpy((*values)[i].valuename.buffer, v->valuename.buffer);
-               (*values)[i].type = v->type;
-               (*values)[i].data = talloc(mem_ctx, v->data_len);
-               memcpy((*values)[i].data, v->data, v->data_len);
-               (*values)[i].data_len = v->data_len;
+               rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, 
+                           STR_TERMINATE);
+               regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
        }
 
  done:
@@ -2327,7 +2320,8 @@ WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 }
 
 WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                      POLICY_HND *hnd, char *key, char *value)
+                                      POLICY_HND *hnd, char *keyname, 
+                                      char *valuename)
 {
        prs_struct qbuf, rbuf;
        SPOOL_Q_DELETEPRINTERDATAEX q;
@@ -2344,7 +2338,7 @@ WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ct
 
        /* Initialise input parameters */
 
-        make_spoolss_q_deleteprinterdataex(&q, hnd, key, value);
+        make_spoolss_q_deleteprinterdataex(&q, hnd, keyname, valuename);
 
        /* Marshall data and send request */
 
@@ -2369,4 +2363,104 @@ WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ct
        return result;
 }
 
+WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                 uint32 offered, uint32 *needed,
+                                 POLICY_HND *hnd, const char *keyname,
+                                 uint16 **keylist, uint32 *len)
+{
+       prs_struct qbuf, rbuf;
+       SPOOL_Q_ENUMPRINTERKEY q;
+       SPOOL_R_ENUMPRINTERKEY r;
+       WERROR result = W_ERROR(ERRgeneral);
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialise parse structures */
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Initialise input parameters */
+
+        make_spoolss_q_enumprinterkey(&q, hnd, keyname, offered);
+
+       /* Marshall data and send request */
+
+       if (!spoolss_io_q_enumprinterkey("", &q, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERKEY, &qbuf, &rbuf))
+               goto done;
+
+       /* Unmarshall response */
+
+       if (!spoolss_io_r_enumprinterkey("", &r, &rbuf, 0))
+               goto done;
+       
+       result = r.status;
+
+       if (needed)
+               *needed = r.needed;
+
+       if (!W_ERROR_IS_OK(r.status))
+               goto done;      
+
+       /* Copy results */
+       
+       if (keylist) {
+               *keylist = (uint16 *)malloc(r.keys.buf_len * 2);
+               memcpy(*keylist, r.keys.buffer, r.keys.buf_len * 2);
+               if (len)
+                       *len = r.keys.buf_len * 2;
+       }
+
+ done:
+       prs_mem_free(&qbuf);
+       prs_mem_free(&rbuf);
+
+       return result;  
+}
+
+WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                   POLICY_HND *hnd, char *keyname)
+{
+       prs_struct qbuf, rbuf;
+       SPOOL_Q_DELETEPRINTERKEY q;
+       SPOOL_R_DELETEPRINTERKEY r;
+       WERROR result = W_ERROR(ERRgeneral);
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialise parse structures */
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Initialise input parameters */
+
+        make_spoolss_q_deleteprinterkey(&q, hnd, keyname);
+
+       /* Marshall data and send request */
+
+       if (!spoolss_io_q_deleteprinterkey("", &q, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERKEY, &qbuf, &rbuf))
+               goto done;
+
+       /* Unmarshall response */
+
+       if (!spoolss_io_r_deleteprinterkey("", &r, &rbuf, 0))
+               goto done;
+       
+       result = r.status;
+
+       if (!W_ERROR_IS_OK(r.status))
+               goto done;      
+
+ done:
+       prs_mem_free(&qbuf);
+       prs_mem_free(&rbuf);
+
+       return result;          
+}
+
 /** @} **/