diff options
-rw-r--r-- | source3/include/proto.h | 6 | ||||
-rwxr-xr-x | source3/include/rpc_spoolss.h | 16 | ||||
-rw-r--r-- | source3/rpc_parse/parse_misc.c | 2 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 277 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 169 |
5 files changed, 279 insertions, 191 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 19ad9b6f33..7f40ac8fcd 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2395,6 +2395,10 @@ uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info); uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info); uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); +BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, + const POLICY_HND *hnd, fstring architecture, + uint32 level, uint32 clientmajor, uint32 clientminor, + NEW_BUFFER *buffer, uint32 offered); BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, @@ -2404,6 +2408,8 @@ BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); +BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, + NEW_BUFFER *buffer, uint32 offered); BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 0777a602b1..0100fb007e 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -804,6 +804,7 @@ SPOOL_Q_ENUMPRINTERS; typedef struct printer_info_ctr_info { + PRINTER_INFO_0 *printers_0; PRINTER_INFO_1 *printers_1; PRINTER_INFO_2 *printers_2; } @@ -881,7 +882,7 @@ typedef struct driver_info_3 UNISTR datafile; UNISTR configfile; UNISTR helpfile; - UNISTR **dependentfiles; + uint16 *dependentfiles; UNISTR monitorname; UNISTR defaultdatatype; } @@ -889,16 +890,11 @@ DRIVER_INFO_3; typedef struct driver_info_info { - union - { - DRIVER_INFO_1 *info1; - DRIVER_INFO_2 *info2; - DRIVER_INFO_3 *info3; - } - driver; - + DRIVER_INFO_1 *info1; + DRIVER_INFO_2 *info2; + DRIVER_INFO_3 *info3; } -DRIVER_INFO; +PRINTER_DRIVER_CTR; typedef struct spool_q_getprinterdriver2 { diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 21d97b444c..d19fe47a0d 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -598,7 +598,7 @@ the buf_len member tells you how large the buffer is. ********************************************************************/ BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, "smb_io_buffer4"); + prs_debug(ps, depth, desc, "smb_io_buffer5"); depth++; if (buf5 == NULL) return False; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index d88761e081..0450ebd243 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -32,6 +32,7 @@ #define prs_uint16s _prs_uint16s #define prs_unistr _prs_unistr #define init_unistr2 make_unistr2 + #define init_buf_unistr2 make_buf_unistr2 #endif @@ -1255,7 +1256,7 @@ static uint32 size_of_device_mode(DEVICEMODE *devmode) if (devmode==NULL) return (4); else - return (0xDC+4); + return (4+devmode->size+devmode->driverextra); } /******************************************************************* @@ -1349,39 +1350,49 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR /******************************************************************* - * write a array UNICODE strings and its relative pointer. + * write a array of UNICODE strings and its relative pointer. * used by 2 RPC structs ********************************************************************/ -static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR ***string) +static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string) { + UNISTR chaine; + prs_struct *ps=&(buffer->prs); if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; - int i=0; - - while ( (*string)[i]!=0x0000 ) - i++; - i--; - - /* count the ending NULL of the array */ + uint16 *p; + uint16 *q; + uint16 zero=0; + p=*string; + q=*string; + + /* first write the last 0 */ buffer->string_at_end -= 2; + prs_set_offset(ps, buffer->string_at_end); + + if(!prs_uint16("leading zero", ps, depth, &zero)) + return False; - /* jfm: FIXME: write a (uint16) 0 for the ending NULL */ - do - { - buffer->string_at_end -= 2*(str_len_uni((*string)[i])+1); + { + while (*q!=0) + q++; + + memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); + + buffer->string_at_end -= (q-p+1)*sizeof(uint16); + prs_set_offset(ps, buffer->string_at_end); /* write the string */ - if (!spoolss_smb_io_unistr(desc, (*string)[i], ps, depth)) + if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth)) return False; - - i--; - } - while (i>=0); + q++; + p=q; + + } while (*p!=0); /* end on the last leading 0 */ prs_set_offset(ps, struct_offset); @@ -1392,22 +1403,32 @@ static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UN } else { uint32 old_offset; + uint16 *chaine2=NULL; + int l_chaine=0; + int l_chaine2=0; + *string=NULL; + /* read the offset */ if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end))) return False; old_offset = prs_offset(ps); - prs_set_offset(ps, buffer->string_at_end); - - /* read the string */ - - /* jfm: FIXME: alloc memory and read all the strings until the string is NULL */ + prs_set_offset(ps, buffer->string_at_end + buffer->struct_start); + + do { + if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth)) + return False; + + l_chaine=str_len_uni(&chaine); + chaine2=(uint16 *)Realloc(chaine2, (l_chaine2+l_chaine+1)*sizeof(uint16)); + memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); + l_chaine2+=l_chaine+1; + + } while(l_chaine!=0); + + *string=chaine2; -/* - if (!spoolss_smb_io_unistr(desc, string, ps, depth)) - return False; -*/ prs_set_offset(ps, old_offset); } return True; @@ -2207,30 +2228,30 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) int size=0; size+=4; /* the security descriptor */ - size+=info->devmode->size+4; /* size of the devmode and the ptr */ - size+=info->devmode->driverextra; /* if a devmode->private section exists, add its size */ - size+=size_of_relative_string( &(info->servername) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->sharename) ); - size+=size_of_relative_string( &(info->portname) ); - size+=size_of_relative_string( &(info->drivername) ); - size+=size_of_relative_string( &(info->comment) ); - size+=size_of_relative_string( &(info->location) ); + size+=size_of_device_mode( info->devmode ); - size+=size_of_relative_string( &(info->sepfile) ); - size+=size_of_relative_string( &(info->printprocessor) ); - size+=size_of_relative_string( &(info->datatype) ); - size+=size_of_relative_string( &(info->parameters) ); - - size+=size_of_uint32( &(info->attributes) ); - size+=size_of_uint32( &(info->priority) ); - size+=size_of_uint32( &(info->defaultpriority) ); - size+=size_of_uint32( &(info->starttime) ); - size+=size_of_uint32( &(info->untiltime) ); - size+=size_of_uint32( &(info->status) ); - size+=size_of_uint32( &(info->cjobs) ); - size+=size_of_uint32( &(info->averageppm) ); + size+=size_of_relative_string( &info->servername ); + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->sharename ); + size+=size_of_relative_string( &info->portname ); + size+=size_of_relative_string( &info->drivername ); + size+=size_of_relative_string( &info->comment ); + size+=size_of_relative_string( &info->location ); + + size+=size_of_relative_string( &info->sepfile ); + size+=size_of_relative_string( &info->printprocessor ); + size+=size_of_relative_string( &info->datatype ); + size+=size_of_relative_string( &info->parameters ); + + size+=size_of_uint32( &info->attributes ); + size+=size_of_uint32( &info->priority ); + size+=size_of_uint32( &info->defaultpriority ); + size+=size_of_uint32( &info->starttime ); + size+=size_of_uint32( &info->untiltime ); + size+=size_of_uint32( &info->status ); + size+=size_of_uint32( &info->cjobs ); + size+=size_of_uint32( &info->averageppm ); return size; } @@ -2240,7 +2261,7 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) { int size=0; - size+=size_of_relative_string( &(info->name) ); + size+=size_of_relative_string( &info->name ); return size; } @@ -2251,12 +2272,12 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) { int size=0; - size+=size_of_uint32( &(info->version) ); - size+=size_of_relative_string( &(info->name) ); - size+=size_of_relative_string( &(info->architecture) ); - size+=size_of_relative_string( &(info->driverpath) ); - size+=size_of_relative_string( &(info->datafile) ); - size+=size_of_relative_string( &(info->configfile) ); + size+=size_of_uint32( &info->version ); + size+=size_of_relative_string( &info->name ); + size+=size_of_relative_string( &info->architecture ); + size+=size_of_relative_string( &info->driverpath ); + size+=size_of_relative_string( &info->datafile ); + size+=size_of_relative_string( &info->configfile ); return size; } @@ -2267,26 +2288,24 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) { int size=0; - UNISTR **string; + uint16 *string; int i=0; - size+=size_of_uint32( &(info->version) ); - size+=size_of_relative_string( &(info->name) ); - size+=size_of_relative_string( &(info->architecture) ); - size+=size_of_relative_string( &(info->driverpath) ); - size+=size_of_relative_string( &(info->datafile) ); - size+=size_of_relative_string( &(info->configfile) ); - size+=size_of_relative_string( &(info->helpfile) ); - size+=size_of_relative_string( &(info->monitorname) ); - size+=size_of_relative_string( &(info->defaultdatatype) ); + size+=size_of_uint32( &info->version ); + size+=size_of_relative_string( &info->name ); + size+=size_of_relative_string( &info->architecture ); + size+=size_of_relative_string( &info->driverpath ); + size+=size_of_relative_string( &info->datafile ); + size+=size_of_relative_string( &info->configfile ); + size+=size_of_relative_string( &info->helpfile ); + size+=size_of_relative_string( &info->monitorname ); + size+=size_of_relative_string( &info->defaultdatatype ); string=info->dependentfiles; - while ( (string)[i]!=0x0000 ) - { - size+=2*(1+ str_len_uni( string[i] ) ); - i++; - } + for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++); + + size+=2*i; size+=6; return size; @@ -2298,19 +2317,19 @@ return the size required by a struct in the stream uint32 spoolss_size_job_info_1(JOB_INFO_1 *info) { int size=0; - size+=size_of_uint32( &(info->jobid) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->machinename) ); - size+=size_of_relative_string( &(info->username) ); - size+=size_of_relative_string( &(info->document) ); - size+=size_of_relative_string( &(info->datatype) ); - size+=size_of_relative_string( &(info->text_status) ); - size+=size_of_uint32( &(info->status) ); - size+=size_of_uint32( &(info->priority) ); - size+=size_of_uint32( &(info->position) ); - size+=size_of_uint32( &(info->totalpages) ); - size+=size_of_uint32( &(info->pagesprinted) ); - size+=size_of_systemtime( &(info->submitted) ); + size+=size_of_uint32( &info->jobid ); + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->machinename ); + size+=size_of_relative_string( &info->username ); + size+=size_of_relative_string( &info->document ); + size+=size_of_relative_string( &info->datatype ); + size+=size_of_relative_string( &info->text_status ); + size+=size_of_uint32( &info->status ); + size+=size_of_uint32( &info->priority ); + size+=size_of_uint32( &info->position ); + size+=size_of_uint32( &info->totalpages ); + size+=size_of_uint32( &info->pagesprinted ); + size+=size_of_systemtime( &info->submitted ); return size; } @@ -2324,29 +2343,29 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) size+=4; /* size of sec desc ptr */ - size+=size_of_uint32( &(info->jobid) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->machinename) ); - size+=size_of_relative_string( &(info->username) ); - size+=size_of_relative_string( &(info->document) ); - size+=size_of_relative_string( &(info->notifyname) ); - size+=size_of_relative_string( &(info->datatype) ); - size+=size_of_relative_string( &(info->printprocessor) ); - size+=size_of_relative_string( &(info->parameters) ); - size+=size_of_relative_string( &(info->drivername) ); + size+=size_of_uint32( &info->jobid ); + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->machinename ); + size+=size_of_relative_string( &info->username ); + size+=size_of_relative_string( &info->document ); + size+=size_of_relative_string( &info->notifyname ); + size+=size_of_relative_string( &info->datatype ); + size+=size_of_relative_string( &info->printprocessor ); + size+=size_of_relative_string( &info->parameters ); + size+=size_of_relative_string( &info->drivername ); size+=size_of_device_mode( info->devmode ); - size+=size_of_relative_string( &(info->text_status) ); + size+=size_of_relative_string( &info->text_status ); /* SEC_DESC sec_desc;*/ - size+=size_of_uint32( &(info->status) ); - size+=size_of_uint32( &(info->priority) ); - size+=size_of_uint32( &(info->position) ); - size+=size_of_uint32( &(info->starttime) ); - size+=size_of_uint32( &(info->untiltime) ); - size+=size_of_uint32( &(info->totalpages) ); - size+=size_of_uint32( &(info->size) ); - size+=size_of_systemtime( &(info->submitted) ); - size+=size_of_uint32( &(info->timeelapsed) ); - size+=size_of_uint32( &(info->pagesprinted) ); + size+=size_of_uint32( &info->status ); + size+=size_of_uint32( &info->priority ); + size+=size_of_uint32( &info->position ); + size+=size_of_uint32( &info->starttime ); + size+=size_of_uint32( &info->untiltime ); + size+=size_of_uint32( &info->totalpages ); + size+=size_of_uint32( &info->size ); + size+=size_of_systemtime( &info->submitted ); + size+=size_of_uint32( &info->timeelapsed ); + size+=size_of_uint32( &info->pagesprinted ); return size; } @@ -2460,6 +2479,33 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) } /******************************************************************* + * init a structure. + ********************************************************************/ +BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, + const POLICY_HND *hnd, fstring architecture, + uint32 level, uint32 clientmajor, uint32 clientminor, + NEW_BUFFER *buffer, uint32 offered) +{ + if (q_u == NULL) + { + return False; + } + + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + + init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture); + + q_u->level=level; + q_u->clientmajorversion=clientmajor; + q_u->clientminorversion=clientminor; + + q_u->buffer=buffer; + q_u->offered=offered; + + return True; +} + +/******************************************************************* * read a structure. * called from spoolss_getprinterdriver2 (srv_spoolss.c) ********************************************************************/ @@ -2670,6 +2716,25 @@ BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps } /******************************************************************* + * init a structure. + ********************************************************************/ +BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, + NEW_BUFFER *buffer, uint32 offered) +{ + if (q_u == NULL) + { + return False; + } + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + + q_u->level=level; + q_u->buffer=buffer; + q_u->offered=offered; + + return True; +} + +/******************************************************************* ********************************************************************/ BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth) { diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 8f1bcef9f3..d08571b80b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -305,8 +305,7 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) char *aprinter; BOOL found=False; - if (!OPEN_HANDLE(Printer)) - { + if (!OPEN_HANDLE(Printer)) { DEBUG(0,("Error setting printer name=%s\n", printername)); return False; } @@ -437,7 +436,7 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, clear_handle(handle); if (printername == NULL) - return NT_STATUS_ACCESS_DENIED; + return ERROR_INVALID_PRINTER_NAME; /* some sanity check because you can open a printer or a print server */ /* aka: \\server\printer or \\server */ @@ -451,12 +450,12 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, if (!set_printer_hnd_printertype(handle, name)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_INVALID_PRINTER_NAME; } if (!set_printer_hnd_printername(handle, name)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_INVALID_PRINTER_NAME; } /* @@ -471,7 +470,7 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_ACCESS_DENIED; } return NT_STATUS_NO_PROBLEMO; @@ -665,25 +664,32 @@ static BOOL getprinterdata_printer(const POLICY_HND *handle, DEBUG(5,("getprinterdata_printer\n")); - if (OPEN_HANDLE(Printer)) - { - get_printer_snum(handle, &snum); - get_a_printer(&printer, 2, lp_servicename(snum)); - - if (get_specific_param(printer, 2, value, &idata, type, &len)) - { - *data = (uint8 *)malloc( (len>in_size)?len:in_size *sizeof(uint8) ); - memset(*data, 0, sizeof(uint8)*len); - memcpy(*data, idata, (len>in_size)?len:in_size); - *needed = len; - - if (idata) free(idata); - return (True); - } + if (!OPEN_HANDLE(Printer)) + return False; + + get_printer_snum(handle, &snum); + get_a_printer(&printer, 2, lp_servicename(snum)); + + if (!get_specific_param(printer, 2, value, &idata, type, &len)) { free_a_printer(printer, 2); + return False; } - return (False); + DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size)); + + *data = (uint8 *)malloc( in_size *sizeof(uint8) ); + memset(*data, 0, in_size *sizeof(uint8)); + /* copy the min(in_size, len) */ + memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8)); + + *needed = len; + + DEBUG(5,("getprinterdata_printer:copy done\n")); + + free_a_printer(printer, 2); + safe_free(idata); + + return True; } /******************************************************************** @@ -728,9 +734,10 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, found=getprinterdata_printer(handle, value, type, data, needed, *out_size); if (found==False) { + DEBUG(5, ("value not found, allocating %d\n", *out_size)); /* reply this param doesn't exist */ - *data=(uint8 *)malloc(4*sizeof(uint8)); - memset(*data, 0x0, 4); + *data=(uint8 *)malloc(*out_size*sizeof(uint8)); + memset(*data, 0x0, *out_size*sizeof(uint8)); return ERROR_INVALID_PARAMETER; } @@ -984,7 +991,7 @@ static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_ memset(&status, 0, sizeof(status)); count=get_printqueue(snum, NULL, &q, &status); data->notify_data.value[0]=(uint32) status.status; - if (q) free(q); + safe_free(q); } /******************************************************************* @@ -997,7 +1004,7 @@ static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_q memset(&status, 0, sizeof(status)); data->notify_data.value[0]=get_printqueue(snum, NULL, &q, &status); - if (q) free(q); + safe_free(q); } /******************************************************************* @@ -1936,14 +1943,24 @@ static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uin for (i=0; i<*returned; i++) (*needed) += spoolss_size_printer_info_2(&(printers[i])); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + for (i=0; i<*returned; i++) { + safe_free(printers[i].devmode->private); + safe_free(printers[i].devmode); + } + safe_free(printers); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ for (i=0; i<*returned; i++) new_smb_io_printer_info_2("", buffer, &(printers[i]), 0); /* clear memory */ + for (i=0; i<*returned; i++) { + safe_free(printers[i].devmode->private); + safe_free(printers[i].devmode); + } safe_free(printers); if (*needed > offered) { @@ -2157,6 +2174,8 @@ static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffe new_smb_io_printer_info_2("", buffer, printer, 0); /* clear memory */ + safe_free(printer->devmode->private); + safe_free(printer->devmode); safe_free(printer); if (*needed > offered) { @@ -2263,8 +2282,7 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, * construct_printer_driver_info_2 * fill a printer_info_2 struct ********************************************************************/ -static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, - pstring servername, fstring architecture) +static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, pstring servername, fstring architecture) { NT_PRINTER_INFO_LEVEL printer; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -2280,36 +2298,30 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, /******************************************************************** * copy a strings array and convert to UNICODE + * + * convert an array of ascii string to a UNICODE string ********************************************************************/ -static void init_unistr_array(UNISTR ***uni_array, char **char_array, char *where) +static void init_unistr_array(uint16 **uni_array, char **char_array, char *where) { int i=0; + int j=0; char *v; pstring line; DEBUG(6,("init_unistr_array\n")); + *uni_array=NULL; - for (v=char_array[i]; *v!='\0'; v=char_array[i]) - { - DEBUGADD(6,("i:%d:", i)); - DEBUGADD(6,("%s:%d:", v, strlen(v))); - - *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1)); - DEBUGADD(7,("realloc:[%p],", *uni_array)); - - (*uni_array)[i]=(UNISTR *)malloc( sizeof(UNISTR) ); - DEBUGADD(7,("alloc:[%p],", (*uni_array)[i])); - + for (v=char_array[i]; *v!='\0'; v=char_array[i]) { snprintf(line, sizeof(line)-1, "%s%s", where, v); - init_unistr( (*uni_array)[i], line ); - DEBUGADD(7,("copy\n")); - + DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line))); + *uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16)); + ascii_to_unistr( *uni_array+j, line , strlen(line)); + j+=strlen(line)+1; i++; } - DEBUGADD(7,("last one\n")); - *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1)); - (*uni_array)[i]=0x0000; + (*uni_array)[j]=0x0000; + DEBUGADD(6,("last one:done\n")); } @@ -2457,6 +2469,7 @@ static uint32 getprinterdriver2_level3(pstring servername, pstring architecture, new_smb_io_printer_driver_info_3("", buffer, info, 0); /* clear memory */ + safe_free(info->dependentfiles); safe_free(info); if (*needed > offered) @@ -3182,9 +3195,10 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri free_a_printer_driver(driver, 3); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i])); } @@ -3195,8 +3209,7 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri } /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d] to buffer\n",i)); new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0); } @@ -3227,9 +3240,10 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri free_a_printer_driver(driver, 3); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); } @@ -3240,8 +3254,7 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri } /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d] to buffer\n",i)); new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); } @@ -3272,27 +3285,34 @@ static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstri free_a_printer_driver(driver, 3); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); *needed += spoolss_size_printer_driver_info_3(&(driver_info_3[i])); } - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(driver_info_3); return ERROR_INSUFFICIENT_BUFFER; - + } + /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding form [%d] to buffer\n",i)); new_smb_io_printer_driver_info_3("", buffer, &(driver_info_3[i]), 0); } - safe_free(list); - - if (*needed > offered) + for (i=0; i<*returned; i++) + safe_free(driver_info_3[i].dependentfiles); + + safe_free(driver_info_3); + + if (*needed > offered) { + *returned=0; return ERROR_INSUFFICIENT_BUFFER; + } else return NT_STATUS_NO_PROBLEMO; } @@ -3332,7 +3352,7 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned); break; default: - return NT_STATUS_INVALID_INFO_CLASS; + return ERROR_INVALID_LEVEL; break; } } @@ -3374,15 +3394,15 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1)); /* construct the list of form structures */ - for (i=0; i<*numofforms; i++) - { + for (i=0; i<*numofforms; i++) { DEBUGADD(6,("Filling form number [%d]\n",i)); fill_form_1(&(forms_1[i]), &(list[i]), i); } + + safe_free(list); /* check the required size. */ - for (i=0; i<*numofforms; i++) - { + for (i=0; i<*numofforms; i++) { DEBUGADD(6,("adding form [%d]'s size\n",i)); buffer_size += spoolss_size_form_1(&(forms_1[i])); } @@ -3390,21 +3410,22 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, *needed=buffer_size; if (!alloc_buffer_size(buffer, buffer_size)){ - safe_free(list); + safe_free(forms_1); return ERROR_INSUFFICIENT_BUFFER; } /* fill the buffer with the form structures */ - for (i=0; i<*numofforms; i++) - { + for (i=0; i<*numofforms; i++) { DEBUGADD(6,("adding form [%d] to buffer\n",i)); new_smb_io_form_1("", buffer, &(forms_1[i]), 0); } - safe_free(list); + safe_free(forms_1); - if (*needed > offered) + if (*needed > offered) { + *numofforms=0; return ERROR_INSUFFICIENT_BUFFER; + } else return NT_STATUS_NO_PROBLEMO; |