s3-spoolss: cleanup _spoolss_SetPrinterDataEx a little.
[ira/wip.git] / source3 / rpc_server / srv_spoolss_nt.c
index 950dc013b2dd079df17ddd2e19a326b0f8fd3ecf..9cde7d2e010d7c8abe486e63d0a6e87cf7f0cde8 100644 (file)
@@ -2465,74 +2465,58 @@ WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, cons
  GetPrinterData on a printer server Handle.
 ********************************************************************/
 
-static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
+static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
+                                           const char *value,
+                                           enum winreg_Type *type,
+                                           union spoolss_PrinterData *data)
 {
-       int i;
-
        DEBUG(8,("getprinterdata_printer_server:%s\n", value));
 
        if (!StrCaseCmp(value, "W3SvcInstalled")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0x00);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "BeepEnabled")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0x00);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "EventLog")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
                /* formally was 0x1b */
-               SIVAL(*data, 0, 0x0);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "NetPopup")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0x00);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "MajorVersion")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
 
                /* Windows NT 4.0 seems to not allow uploading of drivers
                   to a server that reports 0x3 as the MajorVersion.
                   need to investigate more how Win2k gets around this .
                   -- jerry */
 
-               if ( RA_WINNT == get_remote_arch() )
-                       SIVAL(*data, 0, 2);
-               else
-                       SIVAL(*data, 0, 3);
+               if (RA_WINNT == get_remote_arch()) {
+                       data->value = 0x02;
+               } else {
+                       data->value = 0x03;
+               }
 
-               *needed = 0x4;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "MinorVersion")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
@@ -2544,109 +2528,88 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
         *  extra unicode string = e.g. "Service Pack 3"
         */
        if (!StrCaseCmp(value, "OSVersion")) {
-               *type = REG_BINARY;
-               *needed = 0x114;
-
-               if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
-                       return WERR_NOMEM;
-
-               SIVAL(*data, 0, *needed);       /* size */
-               SIVAL(*data, 4, 5);             /* Windows 2000 == 5.0 */
-               SIVAL(*data, 8, 0);
-               SIVAL(*data, 12, 2195);         /* build */
+               DATA_BLOB blob;
+               enum ndr_err_code ndr_err;
+               struct spoolss_OSVersion os;
+
+               os.major                = 5;    /* Windows 2000 == 5.0 */
+               os.minor                = 0;
+               os.build                = 2195; /* build */
+               os.extra_string         = "";   /* leave extra string empty */
+
+               ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
+                       (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       return WERR_GENERAL_FAILURE;
+               }
 
-               /* leave extra string empty */
+               *type = REG_BINARY;
+               data->binary = blob;
 
                return WERR_OK;
        }
 
 
        if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
-               const char *string="C:\\PRINTERS";
                *type = REG_SZ;
-               *needed = 2*(strlen(string)+1);
-               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
-                       return WERR_NOMEM;
-               memset(*data, 0, (*needed > in_size) ? *needed:in_size);
 
-               /* it's done by hand ready to go on the wire */
-               for (i=0; i<strlen(string); i++) {
-                       (*data)[2*i]=string[i];
-                       (*data)[2*i+1]='\0';
-               }
+               data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
+               W_ERROR_HAVE_NO_MEMORY(data->string);
+
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "Architecture")) {
-               const char *string="Windows NT x86";
                *type = REG_SZ;
-               *needed = 2*(strlen(string)+1);
-               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
-                       return WERR_NOMEM;
-               memset(*data, 0, (*needed > in_size) ? *needed:in_size);
-               for (i=0; i<strlen(string); i++) {
-                       (*data)[2*i]=string[i];
-                       (*data)[2*i+1]='\0';
-               }
+
+               data->string = talloc_strdup(mem_ctx, "Windows NT x86");
+               W_ERROR_HAVE_NO_MEMORY(data->string);
+
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "DsPresent")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
 
                /* only show the publish check box if we are a
-                  memeber of a AD domain */
+                  member of a AD domain */
 
-               if ( lp_security() == SEC_ADS )
-                       SIVAL(*data, 0, 0x01);
-               else
-                       SIVAL(*data, 0, 0x00);
-
-               *needed = 0x4;
+               if (lp_security() == SEC_ADS) {
+                       data->value = 0x01;
+               } else {
+                       data->value = 0x00;
+               }
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "DNSMachineName")) {
                const char *hostname = get_mydnsfullname();
 
-               if (!hostname)
+               if (!hostname) {
                        return WERR_BADFILE;
-               *type = REG_SZ;
-               *needed = 2*(strlen(hostname)+1);
-               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
-                       return WERR_NOMEM;
-               memset(*data, 0, (*needed > in_size) ? *needed:in_size);
-               for (i=0; i<strlen(hostname); i++) {
-                       (*data)[2*i]=hostname[i];
-                       (*data)[2*i+1]='\0';
                }
+
+               *type = REG_SZ;
+               data->string = talloc_strdup(mem_ctx, hostname);
+               W_ERROR_HAVE_NO_MEMORY(data->string);
+
                return WERR_OK;
        }
 
-
        return WERR_BADFILE;
 }
 
-/********************************************************************
* spoolss_getprinterdata
- ********************************************************************/
+/****************************************************************
_spoolss_GetPrinterData
+****************************************************************/
 
-WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
+WERROR _spoolss_GetPrinterData(pipes_struct *p,
+                              struct spoolss_GetPrinterData *r)
 {
-       POLICY_HND      *handle = &q_u->handle;
-       UNISTR2         *valuename = &q_u->valuename;
-       uint32          in_size = q_u->size;
-       uint32          *type = &r_u->type;
-       uint32          *out_size = &r_u->size;
-       uint8           **data = &r_u->data;
-       uint32          *needed = &r_u->needed;
-       WERROR          status;
-       fstring         value;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
-       NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       int             snum = 0;
+       WERROR result;
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       int snum = 0;
 
        /*
         * Reminder: when it's a string, the length is in BYTES
@@ -2655,79 +2618,80 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
         * JFM, 4/19/1999
         */
 
-       *out_size = in_size;
-
        /* in case of problem, return some default values */
 
-       *needed = 0;
-       *type   = 0;
+       *r->out.needed  = 0;
+       *r->out.type    = 0;
 
-       DEBUG(4,("_spoolss_getprinterdata\n"));
+       DEBUG(4,("_spoolss_GetPrinterData\n"));
 
-       if ( !Printer ) {
-               DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
-               status = WERR_BADFID;
+       if (!Printer) {
+               DEBUG(2,("_spoolss_GetPrinterData: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
+               result = WERR_BADFID;
                goto done;
        }
 
-       unistr2_to_ascii(value, valuename, sizeof(value));
-
-       if ( Printer->printer_type == SPLHND_SERVER )
-               status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
-       else
-       {
-               if ( !get_printer_snum(p,handle, &snum, NULL) ) {
-                       status = WERR_BADFID;
+       if (Printer->printer_type == SPLHND_SERVER) {
+               result = getprinterdata_printer_server(p->mem_ctx,
+                                                      r->in.value_name,
+                                                      r->out.type,
+                                                      r->out.data);
+       } else {
+               if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+                       result = WERR_BADFID;
                        goto done;
                }
 
-               status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
-               if ( !W_ERROR_IS_OK(status) )
+               result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+               if (!W_ERROR_IS_OK(result)) {
                        goto done;
+               }
 
                /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
 
-               if ( strequal(value, "ChangeId") ) {
-                       *type = REG_DWORD;
-                       *needed = sizeof(uint32);
-                       if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
-                               status = WERR_NOMEM;
+               if (strequal(r->in.value_name, "ChangeId")) {
+                       *r->out.type = REG_DWORD;
+                       r->out.data->value = printer->info_2->changeid;
+                       result = WERR_OK;
+               } else {
+                       REGISTRY_VALUE *v;
+                       DATA_BLOB blob;
+
+                       v = get_printer_data(printer->info_2,
+                                            SPOOL_PRINTERDATA_KEY,
+                                            r->in.value_name);
+                       if (!v) {
+                               result = WERR_BADFILE;
                                goto done;
                        }
-                       SIVAL( *data, 0, printer->info_2->changeid );
-                       status = WERR_OK;
-               }
-               else
-                       status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
-       }
 
-       if (*needed > *out_size)
-               status = WERR_MORE_DATA;
+                       *r->out.type = v->type;
 
-done:
-       if ( !W_ERROR_IS_OK(status) )
-       {
-               DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
+                       blob = data_blob_const(v->data_p, v->size);
 
-               /* reply this param doesn't exist */
-
-               if ( *out_size ) {
-                       if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
-                               if ( printer )
-                                       free_a_printer( &printer, 2 );
-                               return WERR_NOMEM;
-                       }
-               } else {
-                       *data = NULL;
+                       result = pull_spoolss_PrinterData(p->mem_ctx, &blob,
+                                                         r->out.data,
+                                                         *r->out.type);
                }
        }
 
+ done:
        /* cleanup & exit */
 
-       if ( printer )
-               free_a_printer( &printer, 2 );
+       if (printer) {
+               free_a_printer(&printer, 2);
+       }
 
-       return status;
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, NULL, 0);
+       *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
+       r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
+
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 }
 
 /*********************************************************
@@ -7949,29 +7913,15 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinterData
+****************************************************************/
 
-WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
+WERROR _spoolss_EnumPrinterData(pipes_struct *p,
+                               struct spoolss_EnumPrinterData *r)
 {
-       POLICY_HND *handle = &q_u->handle;
-       uint32 idx               = q_u->index;
-       uint32 in_value_len      = q_u->valuesize;
-       uint32 in_data_len       = q_u->datasize;
-       uint32 *out_max_value_len = &r_u->valuesize;
-       uint16 **out_value       = &r_u->value;
-       uint32 *out_value_len    = &r_u->realvaluesize;
-       uint32 *out_type         = &r_u->type;
-       uint32 *out_max_data_len = &r_u->datasize;
-       uint8  **data_out        = &r_u->data;
-       uint32 *out_data_len     = &r_u->realdatasize;
-
        NT_PRINTER_INFO_LEVEL *printer = NULL;
-
-       uint32          biggest_valuesize;
-       uint32          biggest_datasize;
-       uint32          data_len;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int             snum;
        WERROR          result;
        REGISTRY_VALUE  *val = NULL;
@@ -7979,25 +7929,26 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
        int             i, key_index, num_values;
        int             name_length;
 
-       *out_type = 0;
+       *r->out.value_needed    = 0;
+       *r->out.type            = REG_NONE;
+       *r->out.data_needed     = 0;
 
-       *out_max_data_len = 0;
-       *data_out         = NULL;
-       *out_data_len     = 0;
-
-       DEBUG(5,("spoolss_enumprinterdata\n"));
+       DEBUG(5,("_spoolss_EnumPrinterData\n"));
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p,handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                return result;
+       }
 
        p_data = printer->info_2->data;
        key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
@@ -8010,12 +7961,12 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
         * cf: MSDN EnumPrinterData remark section
         */
 
-       if ( !in_value_len && !in_data_len && (key_index != -1) )
-       {
-               DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
+       if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
 
-               biggest_valuesize = 0;
-               biggest_datasize  = 0;
+               uint32_t biggest_valuesize = 0;
+               uint32_t biggest_datasize = 0;
+
+               DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
                num_values = regval_ctr_numvals( p_data->keys[key_index].values );
 
@@ -8037,10 +7988,11 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                /* the value is an UNICODE string but real_value_size is the length
                   in bytes including the trailing 0 */
 
-               *out_value_len = 2 * (1+biggest_valuesize);
-               *out_data_len  = biggest_datasize;
+               *r->out.value_needed = 2 * (1 + biggest_valuesize);
+               *r->out.data_needed  = biggest_datasize;
 
-               DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
+               DEBUG(6,("final values: [%d], [%d]\n",
+                       *r->out.value_needed, *r->out.data_needed));
 
                goto done;
        }
@@ -8050,46 +8002,34 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
         * that's the number of bytes not the number of unicode chars
         */
 
-       if ( key_index != -1 )
-               val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
+       if (key_index != -1) {
+               val = regval_ctr_specific_value(p_data->keys[key_index].values,
+                                               r->in.enum_index);
+       }
 
-       if ( !val )
-       {
+       if (!val) {
 
                /* out_value should default to "" or else NT4 has
                   problems unmarshalling the response */
 
-               *out_max_value_len=(in_value_len/sizeof(uint16));
-
-               if (in_value_len) {
-                       if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
-                       {
+               if (r->in.value_offered) {
+                       *r->out.value_needed = 1;
+                       r->out.value_name = talloc_strdup(r, "");
+                       if (!r->out.value_name) {
                                result = WERR_NOMEM;
                                goto done;
                        }
-                       *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
                } else {
-                       *out_value=NULL;
-                       *out_value_len = 0;
+                       r->out.value_name = NULL;
+                       *r->out.value_needed = 0;
                }
 
                /* the data is counted in bytes */
 
-               *out_max_data_len = in_data_len;
-               *out_data_len     = in_data_len;
-
-               /* only allocate when given a non-zero data_len */
-
-               if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
-               {
-                       result = WERR_NOMEM;
-                       goto done;
-               }
+               *r->out.data_needed = r->in.data_offered;
 
                result = WERR_NO_MORE_ITEMS;
-       }
-       else
-       {
+       } else {
                /*
                 * the value is:
                 * - counted in bytes in the request
@@ -8100,36 +8040,29 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                 */
 
                /* name */
-               *out_max_value_len=(in_value_len/sizeof(uint16));
-               if (in_value_len) {
-                       if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
-                       {
+               if (r->in.value_offered) {
+                       r->out.value_name = talloc_strdup(r, regval_name(val));
+                       if (!r->out.value_name) {
                                result = WERR_NOMEM;
                                goto done;
                        }
-
-                       *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
+                       *r->out.value_needed = strlen_m(regval_name(val));
                } else {
-                       *out_value = NULL;
-                       *out_value_len = 0;
+                       r->out.value_name = NULL;
+                       *r->out.value_needed = 0;
                }
 
                /* type */
 
-               *out_type = regval_type( val );
+               *r->out.type = regval_type(val);
 
                /* data - counted in bytes */
 
-               *out_max_data_len = in_data_len;
-               if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
-               {
-                       result = WERR_NOMEM;
-                       goto done;
+               if (r->out.data && regval_size(val)) {
+                       memcpy(r->out.data, regval_data_p(val), regval_size(val));
                }
-               data_len = regval_size(val);
-               if ( *data_out && data_len )
-                       memcpy( *data_out, regval_data_p(val), data_len );
-               *out_data_len = data_len;
+
+               *r->out.data_needed = regval_size(val);
        }
 
 done:
@@ -8137,37 +8070,36 @@ done:
        return result;
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_SetPrinterData
+****************************************************************/
 
-WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
+WERROR _spoolss_SetPrinterData(pipes_struct *p,
+                              struct spoolss_SetPrinterData *r)
 {
-       POLICY_HND              *handle = &q_u->handle;
-       UNISTR2                 *value = &q_u->value;
-       uint32                  type = q_u->type;
-       uint8                   *data = q_u->data;
-       uint32                  real_len = q_u->real_len;
-
-       NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       int                     snum=0;
-       WERROR                  status = WERR_OK;
-       Printer_entry           *Printer=find_printer_index_by_hnd(p, handle);
-       fstring                 valuename;
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       int snum=0;
+       WERROR result = WERR_OK;
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       DATA_BLOB blob;
 
-       DEBUG(5,("spoolss_setprinterdata\n"));
+       DEBUG(5,("_spoolss_SetPrinterData\n"));
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_SetPrinterData: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if ( Printer->printer_type == SPLHND_SERVER ) {
-               DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
+       if (Printer->printer_type == SPLHND_SERVER) {
+               DEBUG(10,("_spoolss_SetPrinterData: "
+                       "Not implemented for server handles yet\n"));
                return WERR_INVALID_PARAM;
        }
 
-       if (!get_printer_snum(p,handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        /*
         * Access check : NT returns "access denied" if you make a
@@ -8177,43 +8109,49 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
         * when connecting to a printer  --jerry
         */
 
-       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
-       {
-               DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
-               status = WERR_ACCESS_DENIED;
+       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
+               DEBUG(3,("_spoolss_SetPrinterData: "
+                       "change denied by handle access permissions\n"));
+               result = WERR_ACCESS_DENIED;
                goto done;
        }
 
-       status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(status))
-               return status;
+       result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-       unistr2_to_ascii(valuename, value, sizeof(valuename));
+       result = push_spoolss_PrinterData(p->mem_ctx, &blob,
+                                         r->in.type, &r->in.data);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
 
        /*
         * When client side code sets a magic printer data key, detect it and save
         * the current printer data and the magic key's data (its the DEVMODE) for
         * future printer/driver initializations.
         */
-       if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
-       {
+       if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
                /* Set devmode and printer initialization info */
-               status = save_driver_init( printer, 2, data, real_len );
+               result = save_driver_init(printer, 2, blob.data, blob.length);
 
-               srv_spoolss_reset_printerdata( printer->info_2->drivername );
+               srv_spoolss_reset_printerdata(printer->info_2->drivername);
+
+               goto done;
        }
-       else
-       {
-       status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
-                                       type, data, real_len );
-               if ( W_ERROR_IS_OK(status) )
-                       status = mod_a_printer(printer, 2);
+
+       result = set_printer_dataex(printer, SPOOL_PRINTERDATA_KEY,
+                                   r->in.value_name, r->in.type,
+                                   blob.data, blob.length);
+       if (W_ERROR_IS_OK(result)) {
+               result = mod_a_printer(printer, 2);
        }
 
 done:
        free_a_printer(&printer, 2);
 
-       return status;
+       return result;
 }
 
 /****************************************************************
@@ -9040,31 +8978,27 @@ WERROR _spoolss_GetJob(pipes_struct *p,
 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
                                 struct spoolss_GetPrinterDataEx *r)
 {
-       POLICY_HND      *handle = r->in.handle;
-       uint8           *data = NULL;
-       const char      *keyname = r->in.key_name;
-       const char      *valuename = r->in.value_name;
-
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
 
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       REGISTRY_VALUE          *val = NULL;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int                     snum = 0;
-       WERROR                  status = WERR_OK;
+       WERROR result = WERR_OK;
 
        DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
 
        DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
-               keyname, valuename));
+               r->in.key_name, r->in.value_name));
 
        /* in case of problem, return some default values */
 
        *r->out.needed  = 0;
-       *r->out.type    = 0;
+       *r->out.type    = REG_NONE;
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_GetPrinterDataEx: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
-               status = WERR_BADFID;
+               DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
+               result = WERR_BADFID;
                goto done;
        }
 
@@ -9073,50 +9007,58 @@ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
        if (Printer->printer_type == SPLHND_SERVER) {
                DEBUG(10,("_spoolss_GetPrinterDataEx: "
                        "Not implemented for server handles yet\n"));
-               status = WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
                goto done;
        }
 
-       if ( !get_printer_snum(p,handle, &snum, NULL) )
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
-       status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
-       if ( !W_ERROR_IS_OK(status) )
+       result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* check to see if the keyname is valid */
-       if ( !strlen(keyname) ) {
-               status = WERR_INVALID_PARAM;
+       if (!strlen(r->in.key_name)) {
+               result = WERR_INVALID_PARAM;
                goto done;
        }
 
-       if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
+       if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
                DEBUG(4,("_spoolss_GetPrinterDataEx: "
-                       "Invalid keyname [%s]\n", keyname ));
-               free_a_printer( &printer, 2 );
-               status = WERR_BADFILE;
+                       "Invalid keyname [%s]\n", r->in.key_name ));
+               result = WERR_BADFILE;
                goto done;
        }
 
        /* When given a new keyname, we should just create it */
 
-       status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
-                                    r->out.type, &data, r->out.needed,
-                                    r->in.offered );
+       val = get_printer_data(printer->info_2,
+                              r->in.key_name, r->in.value_name);
+       if (!val) {
+               result = WERR_BADFILE;
+               goto done;
+       }
+
+       *r->out.needed = regval_size(val);
 
        if (*r->out.needed > r->in.offered) {
-               status = WERR_MORE_DATA;
+               result = WERR_MORE_DATA;
+               goto done;
        }
 
-       if (W_ERROR_IS_OK(status)) {
-               memcpy(r->out.buffer, data, r->in.offered);
-       }
+       *r->out.type = regval_type(val);
 
-done:
-       if ( printer )
-       free_a_printer( &printer, 2 );
+       memcpy(r->out.buffer, regval_data_p(val), regval_size(val));
 
-       return status;
+ done:
+       if (printer) {
+               free_a_printer(&printer, 2);
+       }
+
+       return result;
 }
 
 /****************************************************************
@@ -9126,11 +9068,10 @@ done:
 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
                                 struct spoolss_SetPrinterDataEx *r)
 {
-       POLICY_HND              *handle = r->in.handle;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int                     snum = 0;
-       WERROR                  status = WERR_OK;
-       Printer_entry           *Printer = find_printer_index_by_hnd(p, handle);
+       WERROR                  result = WERR_OK;
+       Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
        char                    *oid_string;
 
        DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
@@ -9139,19 +9080,20 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
            SetPrinterData if key is "PrinterDriverData" */
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_SetPrinterDataEx: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if ( Printer->printer_type == SPLHND_SERVER ) {
+       if (Printer->printer_type == SPLHND_SERVER) {
                DEBUG(10,("_spoolss_SetPrinterDataEx: "
                        "Not implemented for server handles yet\n"));
                return WERR_INVALID_PARAM;
        }
 
-       if ( !get_printer_snum(p,handle, &snum, NULL) )
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        /*
         * Access check : NT returns "access denied" if you make a
@@ -9161,38 +9103,38 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
         * when connecting to a printer  --jerry
         */
 
-       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
-       {
+       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
                DEBUG(3, ("_spoolss_SetPrinterDataEx: "
                        "change denied by handle access permissions\n"));
                return WERR_ACCESS_DENIED;
        }
 
-       status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
-       if (!W_ERROR_IS_OK(status))
-               return status;
+       result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        /* check for OID in valuename */
 
-       if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
-       {
+       oid_string = strchr(r->in.value_name, ',');
+       if (oid_string) {
                *oid_string = '\0';
                oid_string++;
        }
 
        /* save the registry data */
 
-       status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
-                                    r->in.type, r->in.buffer, r->in.offered );
+       result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
+                                   r->in.type, r->in.buffer, r->in.offered);
 
-       if ( W_ERROR_IS_OK(status) )
-       {
+       if (W_ERROR_IS_OK(result)) {
                /* save the OID if one was specified */
-               if ( oid_string ) {
+               if (oid_string) {
                        char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
                                r->in.key_name, SPOOL_OID_KEY);
                        if (!str) {
-                               return WERR_NOMEM;
+                               result = WERR_NOMEM;
+                               goto done;
                        }
 
                        /*
@@ -9202,17 +9144,18 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
                         * this is right.    --jerry
                         */
 
-                       set_printer_dataex( printer, str, r->in.value_name,
-                                           REG_SZ, (uint8 *)oid_string,
-                                           strlen(oid_string)+1 );
+                       set_printer_dataex(printer, str, r->in.value_name,
+                                          REG_SZ, (uint8_t *)oid_string,
+                                          strlen(oid_string)+1);
                }
 
-               status = mod_a_printer(printer, 2);
+               result = mod_a_printer(printer, 2);
        }
 
+ done:
        free_a_printer(&printer, 2);
 
-       return status;
+       return result;
 }
 
 /****************************************************************
@@ -9974,28 +9917,6 @@ WERROR _spoolss_ReadPrinter(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_GetPrinterData
-****************************************************************/
-
-WERROR _spoolss_GetPrinterData(pipes_struct *p,
-                              struct spoolss_GetPrinterData *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_SetPrinterData
-****************************************************************/
-
-WERROR _spoolss_SetPrinterData(pipes_struct *p,
-                              struct spoolss_SetPrinterData *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_WaitForPrinterChange
 ****************************************************************/
@@ -10304,17 +10225,6 @@ WERROR _spoolss_47(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_EnumPrinterData
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterData(pipes_struct *p,
-                               struct spoolss_EnumPrinterData *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_4a
 ****************************************************************/