From 8688933c7feb87179c178a30e4fc42970fe1da8f Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 15 Feb 2000 18:07:45 +0000 Subject: fix the reply of rpc_alter_context OpenPrinterEx is now decoding correctly the query most of the EnumXXX use the new_buffer struct. check the (un)marshalling return code. conclusion: still a long way to go. all the client code has to be rewritten, and I still wonder how to implement correctly the notify stuff. (This used to be commit 3d6d3863751787b08d40268c83221add1487a5c9) --- source3/rpc_server/srv_pipe_srv.c | 2 +- source3/rpc_server/srv_spoolss.c | 526 +++++++++++---- source3/rpc_server/srv_spoolss_nt.c | 1229 +++++++++++++++++++++++------------ 3 files changed, 1218 insertions(+), 539 deletions(-) (limited to 'source3/rpc_server') diff --git a/source3/rpc_server/srv_pipe_srv.c b/source3/rpc_server/srv_pipe_srv.c index 2cebc8148b..6e8b306760 100644 --- a/source3/rpc_server/srv_pipe_srv.c +++ b/source3/rpc_server/srv_pipe_srv.c @@ -796,7 +796,7 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ * Create the header, now we know the length. */ - init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + init_rpc_hdr(&p->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), auth_len); diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 60333e1f3b..50b6dd3846 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -107,10 +107,18 @@ static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_closeprinter("", &q_u, data, 0); + if (!spoolss_io_q_closeprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_closeprinter: unable to unmarshall SPOOL_Q_CLOSEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_closeprinter(&q_u.handle); memcpy(&r_u.handle, &q_u.handle, sizeof(r_u.handle)); - spoolss_io_r_closeprinter("",&r_u,rdata,0); + + if (!spoolss_io_r_closeprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_closeprinter: unable to marshall SPOOL_R_CLOSEPRINTER.\n")); + return False; + } } /******************************************************************** @@ -125,12 +133,19 @@ static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_rffpcnex("", &q_u, data, 0); + if (!spoolss_io_q_rffpcnex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_rffpcnex: unable to unmarshall SPOOL_Q_RFFPCNEX.\n")); + return False; + } r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags, q_u.options, &q_u.localmachine, q_u.printerlocal, &q_u.option); - spoolss_io_r_rffpcnex("",&r_u,rdata,0); + + if (!spoolss_io_r_rffpcnex("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n")); + return False; + } } @@ -148,11 +163,18 @@ static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_rfnpcnex("", &q_u, data, 0); + if (!spoolss_io_q_rfnpcnex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_rfnpcnex: unable to unmarshall SPOOL_Q_RFNPCNEX.\n")); + return False; + } r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change, &q_u.option, &r_u.count, &r_u.info); - spoolss_io_r_rfnpcnex("", &r_u, rdata, 0); + + if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n")); + return False; + } } @@ -169,32 +191,33 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprinters("", &q_u, data, 0); + DEBUG(5,("api_spoolss_enumprinters\n")); - /* lkclXXX DAMN DAMN DAMN! MICROSOFT @#$%S IT UP, AGAIN, AND WE - HAVE TO DEAL WITH IT! AGH! - */ - r_u.level = q_u.level; - r_u.status = _spoolss_enumprinters( - q_u.flags, - &q_u.servername, - q_u.level, - &q_u.buffer, - q_u.buf_size, - &r_u.offered, - &r_u.needed, - &r_u.ctr, - &r_u.returned); + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprinters: unable to unmarshall SPOOL_Q_ENUMPRINTERS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprinters( q_u.flags, &q_u.servername, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); - memcpy(r_u.servername.buffer,q_u.servername.buffer, - 2*q_u.servername.uni_str_len); - r_u.servername.buffer[q_u.servername.uni_str_len] = 0; + if (!new_spoolss_io_r_enumprinters("", &r_u, rdata, 0)) { + DEBUG(0,("new_spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } - spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_enumprinters("",&r_u,rdata,0); + new_spoolss_free_buffer(q_u.buffer); + + return True; } - /******************************************************************** * api_spoolss_getprinter * called from the spoolss dispatcher @@ -208,7 +231,10 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_getprinter("", &q_u, data, 0); + if(!spoolss_io_q_getprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n")); + return False; + } r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level, &r_u.ctr, &q_u.offered, &r_u.needed); @@ -218,7 +244,12 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd r_u.level = q_u.level; safe_free(q_u.buffer); - spoolss_io_r_getprinter("",&r_u,rdata,0); + if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n")); + return False; + } + + return True; } @@ -235,7 +266,10 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_getprinterdriver2("", &q_u, data, 0); + if(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n")); + return False; + } r_u.status = _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture, q_u.level, @@ -246,7 +280,12 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str r_u.level = q_u.level; spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_getprinterdriver2("",&r_u,rdata,0); + if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n")); + return False; + } + + return True; } /******************************************************************** @@ -262,9 +301,19 @@ static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_stru ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_startpageprinter("", &q_u, data, 0); + if(!spoolss_io_q_startpageprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_startpageprinter: unable to unmarshall SPOOL_Q_STARTPAGEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_startpageprinter(&q_u.handle); - spoolss_io_r_startpageprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_startpageprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_startpageprinter: unable to marshall SPOOL_R_STARTPAGEPRINTER.\n")); + return False; + } + + return True; } @@ -281,9 +330,19 @@ static BOOL api_spoolss_endpageprinter(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_endpageprinter("", &q_u, data, 0); + if(!spoolss_io_q_endpageprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_endpageprinter: unable to unmarshall SPOOL_Q_ENDPAGEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_endpageprinter(&q_u.handle); - spoolss_io_r_endpageprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_endpageprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_endpageprinter: unable to marshall SPOOL_R_ENDPAGEPRINTER.\n")); + return False; + } + + return True; } /******************************************************************** @@ -299,12 +358,22 @@ static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struc ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_startdocprinter("", &q_u, data, 0); + if(!spoolss_io_q_startdocprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_startdocprinter: unable to unmarshall SPOOL_Q_STARTDOCPRINTER.\n")); + return False; + } + r_u.status = _spoolss_startdocprinter(&q_u.handle, q_u.doc_info_container.level, &q_u.doc_info_container.docinfo, &r_u.jobid); - spoolss_io_r_startdocprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_startdocprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_startdocprinter: unable to marshall SPOOL_R_STARTDOCPRINTER.\n")); + return False; + } + + return True; } /******************************************************************** @@ -320,9 +389,19 @@ static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enddocprinter("", &q_u, data, 0); + if(!spoolss_io_q_enddocprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enddocprinter: unable to unmarshall SPOOL_Q_ENDDOCPRINTER.\n")); + return False; + } + r_u.status = _spoolss_enddocprinter(&q_u.handle); - spoolss_io_r_enddocprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_enddocprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_enddocprinter: unable to marshall SPOOL_R_ENDDOCPRINTER.\n")); + return False; + } + + return True; } @@ -339,14 +418,24 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_writeprinter("", &q_u, data, 0); + if(!spoolss_io_q_writeprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_writeprinter: unable to unmarshall SPOOL_Q_WRITEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_writeprinter(&q_u.handle, q_u.buffer_size, q_u.buffer, &q_u.buffer_size2); r_u.buffer_written = q_u.buffer_size2; safe_free(q_u.buffer); - spoolss_io_r_writeprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_writeprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_writeprinter: unable to marshall SPOOL_R_WRITEPRINTER.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -359,7 +448,11 @@ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rd ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setprinter("", &q_u, data, 0); + if(!spoolss_io_q_setprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setprinter: unable to unmarshall SPOOL_Q_SETPRINTER.\n")); + return False; + } + DEBUG(0,("api_spoolss_setprinter: typecast sec_des to uint8*!\n")); r_u.status = _spoolss_setprinter(&q_u.handle, q_u.level, &q_u.info, @@ -367,7 +460,13 @@ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rd q_u.security.size_of_buffer, (const uint8*)q_u.security.data, q_u.command); - spoolss_io_r_setprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_setprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_setprinter: unable to marshall SPOOL_R_SETPRINTER.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -380,9 +479,19 @@ static BOOL api_spoolss_fcpn(uint16 vuid, prs_struct *data, prs_struct *rdata) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_fcpn("", &q_u, data, 0); + if(!spoolss_io_q_fcpn("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_fcpn: unable to unmarshall SPOOL_Q_FCPN.\n")); + return False; + } + r_u.status = _spoolss_fcpn(&q_u.handle); - spoolss_io_r_fcpn("",&r_u,rdata,0); + + if(!spoolss_io_r_fcpn("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_fcpn: unable to marshall SPOOL_R_FCPN.\n")); + return False; + } + + return True; } @@ -396,13 +505,22 @@ static BOOL api_spoolss_addjob(uint16 vuid, prs_struct *data, prs_struct *rdata) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addjob("", &q_u, data, 0); + if(!spoolss_io_q_addjob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addjob: unable to unmarshall SPOOL_Q_ADDJOB.\n")); + return False; + } r_u.status = _spoolss_addjob(&q_u.handle, q_u.level, &q_u.buffer, q_u.buf_size); spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_addjob("",&r_u,rdata,0); + + if(!spoolss_io_r_addjob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_addjob: unable to marshall SPOOL_R_ADDJOB.\n")); + return False; + } + + return True; } @@ -415,15 +533,30 @@ static BOOL api_spoolss_enumjobs(uint16 vuid, prs_struct *data, prs_struct *rdat ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); + + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumjobs("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumjobs: unable to unmarshall SPOOL_Q_ENUMJOBS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumjobs(&q_u.handle, q_u.firstjob, q_u.numofjobs, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!spoolss_io_r_enumjobs("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_enumjobs: unable to marshall SPOOL_R_ENUMJOBS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); - spoolss_io_q_enumjobs("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumjobs(&q_u.handle, - q_u.firstjob, q_u.numofjobs, q_u.level, - &r_u.ctr, &r_u.offered, &r_u.numofjobs); - spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_enumjobs("",&r_u,rdata,0); + return True; } @@ -437,9 +570,19 @@ static BOOL api_spoolss_schedulejob(uint16 vuid, prs_struct *data, prs_struct *r ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_schedulejob("", &q_u, data, 0); + if(!spoolss_io_q_schedulejob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_schedulejob: unable to unmarshall SPOOL_Q_SCHEDULEJOB.\n")); + return False; + } + r_u.status = _spoolss_schedulejob(&q_u.handle, q_u.jobid); - spoolss_io_r_schedulejob("",&r_u,rdata,0); + + if(!spoolss_io_r_schedulejob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_schedulejob: unable to marshall SPOOL_R_SCHEDULEJOB.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -452,10 +595,20 @@ static BOOL api_spoolss_setjob(uint16 vuid, prs_struct *data, prs_struct *rdata) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setjob("", &q_u, data, 0); + if(!spoolss_io_q_setjob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setjob: unable to unmarshall SPOOL_Q_SETJOB.\n")); + return False; + } + r_u.status = _spoolss_setjob(&q_u.handle, q_u.jobid, q_u.level, &q_u.ctr, q_u.command); - spoolss_io_r_setjob("",&r_u,rdata,0); + + if(!spoolss_io_r_setjob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_setjob: unable to marshall SPOOL_R_SETJOB.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -468,18 +621,30 @@ static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_st ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - - spoolss_io_q_enumprinterdrivers("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumprinterdrivers(&q_u.name, - &q_u.environment, q_u. level, - &r_u.ctr, &r_u.offered, &r_u.numofdrivers); + new_spoolss_allocate_buffer(&q_u.buffer); - spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_enumdrivers("",&r_u,rdata,0); - free_spoolss_r_enumdrivers(&r_u); + if (!spoolss_io_q_enumprinterdrivers("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprinterdrivers: unable to unmarshall SPOOL_Q_ENUMPRINTERDRIVERS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprinterdrivers(&q_u.name, &q_u.environment, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!new_spoolss_io_r_enumprinterdrivers("",&r_u,rdata,0)) { + DEBUG(0,("new_spoolss_io_r_enumprinterdrivers: unable to marshall SPOOL_R_ENUMPRINTERDRIVERS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } @@ -493,12 +658,12 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - DEBUG(5,("spoolss_io_q_enumforms\n")); - new_spoolss_allocate_buffer(&q_u.buffer); - if (!spoolss_io_q_enumforms("", &q_u, data, 0)) + if (!spoolss_io_q_enumforms("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumforms: unable to unmarshall SPOOL_Q_ENUMFORMS.\n")); return False; + } /* that's an [in out] buffer */ new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); @@ -508,6 +673,7 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda &r_u.needed, &r_u.numofforms); if (!new_spoolss_io_r_enumforms("",&r_u,rdata,0)) { + DEBUG(0,("new_spoolss_io_r_enumforms: unable to marshall SPOOL_R_ENUMFORMS.\n")); new_spoolss_free_buffer(q_u.buffer); return False; } @@ -527,20 +693,30 @@ static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rda ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - - spoolss_io_q_enumports("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumports(&q_u.name, - q_u.level, - &r_u.ctr, - &r_u.offered, - &r_u.numofports); + new_spoolss_allocate_buffer(&q_u.buffer); + + if(!spoolss_io_q_enumports("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumports: unable to unmarshall SPOOL_Q_ENUMPORTS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); - spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_enumports("",&r_u,rdata,0); - spoolss_free_r_enumports(&r_u); + r_u.status = _spoolss_enumports(&q_u.name, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!new_spoolss_io_r_enumports("",&r_u,rdata,0)) { + DEBUG(0,("new_spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } @@ -554,13 +730,23 @@ static BOOL api_spoolss_addprinterex(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addprinterex("", &q_u, data, 0); + if(!spoolss_io_q_addprinterex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addprinterex: unable to unmarshall SPOOL_Q_ADDPRINTEREX.\n")); + return False; + } + r_u.status = _spoolss_addprinterex(&q_u.server_name, q_u.level, &q_u.info, q_u.unk0, q_u.unk1, q_u.unk2, q_u.unk3, q_u.user_level, &q_u.user, &r_u.handle); - spoolss_io_r_addprinterex("", &r_u, rdata, 0); + + if(!spoolss_io_r_addprinterex("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addprinterex: unable to marshall SPOOL_R_ADDPRINTEREX.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -573,10 +759,20 @@ static BOOL api_spoolss_addprinterdriver(uint16 vuid, prs_struct *data, prs_stru ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addprinterdriver("", &q_u, data, 0); + if(!spoolss_io_q_addprinterdriver("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addprinterdriver: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVER.\n")); + return False; + } + r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info); - spoolss_io_r_addprinterdriver("", &r_u, rdata, 0); + + if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -586,7 +782,10 @@ static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, SPOOL_Q_GETPRINTERDRIVERDIR q_u; SPOOL_R_GETPRINTERDRIVERDIR r_u; - spoolss_io_q_getprinterdriverdir("", &q_u, data, 0); + if(!spoolss_io_q_getprinterdriverdir("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinterdriverdir: unable to unmarshall SPOOL_Q_GETPRINTERDRIVERDIR.\n")); + return False; + } r_u.offered = q_u.buf_size; r_u.level = q_u.level; @@ -596,7 +795,13 @@ static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, &r_u.ctr, &r_u.offered); spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0); + + if(!spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_getprinterdriverdir: unable to marshall SPOOL_R_GETPRINTERDRIVERDIR.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -609,7 +814,11 @@ static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struc ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprinterdata("", &q_u, data, 0); + if(!spoolss_io_q_enumprinterdata("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprinterdata: unable to unmarshall SPOOL_Q_ENUMPRINTERDATA.\n")); + return False; + } + r_u.valuesize = q_u.valuesize; r_u.datasize = q_u.datasize; @@ -622,8 +831,15 @@ static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struc &r_u.datasize,/* in out */ &r_u.data,/* out */ &r_u.realdatasize);/* out */ - spoolss_io_r_enumprinterdata("", &r_u, rdata, 0); + + if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n")); + return False; + } + safe_free(r_u.data); + + return True; } /**************************************************************************** @@ -636,12 +852,21 @@ static BOOL api_spoolss_setprinterdata(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setprinterdata("", &q_u, data, 0); + if(!spoolss_io_q_setprinterdata("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n")); + return False; + } + r_u.status = _spoolss_setprinterdata(&q_u.handle, &q_u.value, q_u.type, q_u.max_len, q_u.data, q_u.real_len, q_u.numeric_data); - spoolss_io_r_setprinterdata("", &r_u, rdata, 0); - safe_free(q_u.data); + + if(!spoolss_io_r_setprinterdata("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_SETPRINTERDATA.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -654,9 +879,19 @@ static BOOL api_spoolss_addform(uint16 vuid, prs_struct *data, prs_struct *rdata ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addform("", &q_u, data, 0); + if(!spoolss_io_q_addform("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addform: unable to unmarshall SPOOL_Q_ADDFORM.\n")); + return False; + } + r_u.status = _spoolss_addform(&q_u.handle, q_u.level, &q_u.form); - spoolss_io_r_addform("", &r_u, rdata, 0); + + if(!spoolss_io_r_addform("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addform: unable to marshall SPOOL_R_ADDFORM.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -669,10 +904,20 @@ static BOOL api_spoolss_setform(uint16 vuid, prs_struct *data, prs_struct *rdata ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setform("", &q_u, data, 0); + if(!spoolss_io_q_setform("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setform: unable to unmarshall SPOOL_Q_SETFORM.\n")); + return False; + } + r_u.status = _spoolss_setform(&q_u.handle, &q_u.name, q_u.level, &q_u.form); - spoolss_io_r_setform("", &r_u, rdata, 0); + + if(!spoolss_io_r_setform("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_setform: unable to marshall SPOOL_R_SETFORM.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -685,18 +930,29 @@ static BOOL api_spoolss_enumprintprocessors(uint16 vuid, prs_struct *data, prs_s ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprintprocessors("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumprintprocessors(&q_u.name, - &q_u.environment, - q_u.level, - &r_u.info_1, - &r_u.offered, - &r_u.numofprintprocessors); - spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0); - safe_free(r_u.info_1); + new_spoolss_allocate_buffer(&q_u.buffer); + + if(!spoolss_io_q_enumprintprocessors("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprintprocessors: unable to unmarshall SPOOL_Q_ENUMPRINTPROCESSORS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprintprocessors(&q_u.name, &q_u.environment, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if(!spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprintprocessors: unable to marshall SPOOL_R_ENUMPRINTPROCESSORS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } /**************************************************************************** @@ -709,17 +965,29 @@ static BOOL api_spoolss_enumprintmonitors(uint16 vuid, prs_struct *data, prs_str ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprintmonitors("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumprintmonitors(&q_u.name, - q_u.level, - &r_u.info_1, - &r_u.offered, - &r_u.numofprintmonitors); - spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0); - safe_free(r_u.info_1); + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumprintmonitors("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprintmonitors: unable to unmarshall SPOOL_Q_ENUMPRINTMONITORS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprintmonitors(&q_u.name, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprintmonitors: unable to marshall SPOOL_R_ENUMPRINTMONITORS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } /**************************************************************************** @@ -729,7 +997,10 @@ static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata) SPOOL_Q_GETJOB q_u; SPOOL_R_GETJOB r_u; - spoolss_io_q_getjob("", &q_u, data, 0); + if(!spoolss_io_q_getjob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n")); + return False; + } r_u.offered = q_u.buf_size; r_u.level = q_u.level; @@ -739,8 +1010,15 @@ static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata) &r_u.ctr, &r_u.offered); spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_getjob("",&r_u,rdata,0); + + if(!spoolss_io_r_getjob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n")); + return False; + } + free_spoolss_r_getjob(&r_u); + + return True; } /******************************************************************* diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index d25281cea5..2e80cbdbf6 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -200,11 +200,8 @@ static BOOL open_printer_hnd(POLICY_HND *hnd) { if (!Printer[i].open) { - Printer[i].open = True; - Printer[i].ok = True; - + Printer[i].open = True; memcpy(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)); - DEBUG(4,("Opened printer handle[%x] ", i)); dump_data(4, hnd->data, sizeof(hnd->data)); return True; @@ -221,32 +218,14 @@ static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required) { int pnum = find_printer_index_by_hnd(hnd); - if (OPEN_HANDLE(pnum)) { - DEBUG(4,("Setting printer access=%x (pnum=%x)\n", access_required, pnum)); - Printer[pnum].access = access_required; - return True; - } - else { + if (!OPEN_HANDLE(pnum)) { DEBUG(4,("Error setting printer type=%x (pnum=%x)", access_required, pnum)); return False; } - return False; -} - -/**************************************************************************** - . -****************************************************************************/ -static BOOL printer_entry_is_valid(POLICY_HND *hnd) -{ - int pnum = find_printer_index_by_hnd(hnd); - if (!OPEN_HANDLE(pnum)) - return False; - - if (Printer[pnum].ok == False) - return False; - - return True; + DEBUG(4,("Setting printer access=%x (pnum=%x)\n", access_required, pnum)); + Printer[pnum].access = access_required; + return True; } /**************************************************************************** @@ -266,23 +245,19 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) if ( strlen(printername) < 3 ) { DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername)); - Printer[pnum].ok=False; return False; } /* it's a print server */ if (!strchr(printername+2, '\\')) { DEBUGADD(4,("Printer is a print server\n")); - Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER; - Printer[pnum].ok=True; - + Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER; return True; } /* it's a printer */ else { DEBUGADD(4,("Printer is a printer\n")); Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTER; - Printer[pnum].ok=True; return True; } @@ -295,11 +270,11 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) { int pnum = find_printer_index_by_hnd(hnd); - char *back; NT_PRINTER_INFO_LEVEL printer; int snum; int n_services=lp_numservices(); - uint32 marche; + char *aprinter; + BOOL found=False; if (!OPEN_HANDLE(pnum)) { @@ -309,54 +284,66 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) DEBUG(4,("Setting printer name=%s (len=%d) (pnum=%x)\n", printername, strlen(printername), pnum)); - switch (Printer[pnum].printer_type) { - case PRINTER_HANDLE_IS_PRINTSERVER: + if (Printer[pnum].printer_type==PRINTER_HANDLE_IS_PRINTSERVER) { ZERO_STRUCT(Printer[pnum].dev.printerservername); strncpy(Printer[pnum].dev.printerservername, printername, strlen(printername)); return True; - break; + } - case PRINTER_HANDLE_IS_PRINTER: - back=strchr(printername+2, '\\'); - back=back+1; - DEBUGADD(5,("searching for %s (len=%d)\n", back,strlen(back))); - /* - * store the Samba share name in it - * in back we have the long printer name - * need to iterate all the snum and do a - * get_a_printer each time to find the printer - * faster to do it here than later. - */ - for (snum=0;snumprintername) == strlen(back) ) - && ( !strncasecmp(printer.info_2->printername, back, strlen(back))) - ) { - DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); - ZERO_STRUCT(Printer[pnum].dev.printername); - strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); - free_a_printer(printer, 2); - return True; - break; - } - free_a_printer(printer, 2); - } - } + if (Printer[pnum].printer_type!=PRINTER_HANDLE_IS_PRINTER) return False; - break; - - default: + + aprinter=strchr(printername+2, '\\'); + aprinter++; + + DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter))); + /* + * store the Samba share name in it + * in back we have the long printer name + * need to iterate all the snum and do a + * get_a_printer each time to find the printer + * faster to do it here than later. + */ + + for (snum=0;snumprintername) != strlen(aprinter) ) { + free_a_printer(printer, 2); + continue; + } + + if ( strncasecmp(printer.info_2->printername, aprinter, strlen(aprinter))) { + free_a_printer(printer, 2); + continue; + } + + found=True; + } + + if (found==False) + { + DEBUGADD(4,("Printer not found\n")); return False; - break; - } + } + + DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); + ZERO_STRUCT(Printer[pnum].dev.printername); + strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); + free_a_printer(printer, 2); + + return True; } /******************************************************************** + Return True is the handle is a print server. ********************************************************************/ static BOOL handle_is_printserver(const POLICY_HND *handle) { @@ -371,6 +358,30 @@ static BOOL handle_is_printserver(const POLICY_HND *handle) return True; } +/**************************************************************************** + allocate more memory for a BUFFER. +****************************************************************************/ +static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) +{ + prs_struct *ps; + uint32 extra_space; + + ps=&(buffer->prs); + + /* damn, I'm doing the reverse operation of prs_grow() :) */ + if (buffer_size < prs_data_size(ps)) + extra_space=0; + else + extra_space = buffer_size - prs_data_size(ps); + + if (!prs_grow(ps, extra_space)) + return False; + + buffer->string_at_end=prs_data_size(ps); + + return True; +} + /******************************************************************** * spoolss_open_printer * @@ -400,9 +411,15 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, open_printer_hnd(handle); - set_printer_hnd_printertype(handle, name); + if (!set_printer_hnd_printertype(handle, name)) { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } - set_printer_hnd_printername(handle, name); + if (!set_printer_hnd_printername(handle, name)) { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } /* if (printer_default->datatype_ptr != NULL) @@ -414,14 +431,11 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, set_printer_hnd_datatype(handle, ""); */ - set_printer_hnd_accesstype(handle, printer_default->access_required); - - if (!printer_entry_is_valid(handle)) - { + if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) { close_printer_handle(handle); return NT_STATUS_ACCESS_DENIED; } - + return NT_STATUS_NO_PROBLEMO; } @@ -536,7 +550,8 @@ uint32 _spoolss_closeprinter(POLICY_HND *handle) } /******************************************************************** - ********************************************************************/ + GetPrinterData on a printer server Handle. +********************************************************************/ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) { int i; @@ -585,7 +600,7 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d *type = 0x1; *needed = 2*(strlen(string)+1); *data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8)); - ZERO_STRUCTP(*data); + memset(*data, 0, (*needed > in_size) ? *needed:in_size); /* it's done by hand ready to go on the wire */ for (i=0; i in_size) ? *needed:in_size) *sizeof(uint8)); - ZERO_STRUCTP(*data); + memset(*data, 0, (*needed > in_size) ? *needed:in_size); for (i=0; iflags=PRINTER_ENUM_NAME; + printer->flags=PRINTER_ENUM_ICON8; /* the description and the name are of the form \\server\share */ - slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername, + + snprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername, ntprinter.info_2->printername, ntprinter.info_2->drivername, lp_comment(snum)); init_unistr(&(printer->description), chaine); - slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername); - init_unistr(&(printer->name), chaine); + snprintf(chaine2,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername); + init_unistr(&(printer->name), chaine2); init_unistr(&(printer->comment), lp_comment(snum)); free_a_printer(ntprinter, 2); + return (True); } @@ -1648,29 +1668,26 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring * enum_printer_info_1 * glue between spoolss_enumprinters and construct_printer_info_1 ********************************************************************/ -static BOOL enum_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number) +static BOOL get_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number) { pstring servername; *printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1)); DEBUG(4,("Allocated memory for ONE PRINTER_INFO_1 at [%p]\n", *printer)); pstrcpy(servername, global_myname); - if (!construct_printer_info_1(*printer, snum, servername)) - { + if (!construct_printer_info_1(*printer, snum, servername)) { free(*printer); - return (False); + return False; } else - { - return (True); - } + return True; } /******************************************************************** * enum_printer_info_2 * glue between spoolss_enumprinters and construct_printer_info_2 ********************************************************************/ -static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) +static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) { pstring servername; @@ -1693,26 +1710,100 @@ static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number) +static BOOL enum_printer_info_1(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; + int i; int n_services=lp_numservices(); - *printers=NULL; - *number=0; + PRINTER_INFO_1 *printer=NULL; +DEBUG(1,("enum_printer_info_1\n")); + for (snum=0; snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************** + Spoolss_enumprinters. +********************************************************************/ +static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int snum; + int i; + int n_services=lp_numservices(); + PRINTER_INFO_1 *printers=NULL; + PRINTER_INFO_1 current_prt; + pstring servername; + + DEBUG(4,("enum_all_printers_info_1\n")); + + pstrcpy(servername, global_myname); + + for (snum=0; snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** @@ -1720,26 +1811,90 @@ static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number) * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number) +static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; + int i; int n_services=lp_numservices(); - *printers=NULL; - *number=0; + PRINTER_INFO_2 **printers=NULL; - for (snum=0;snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************** + * handle enumeration of printers at level 1 + ********************************************************************/ +static uint32 enumprinters_level1( uint32 flags, fstring name, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + if (flags && PRINTER_ENUM_NETWORK) + return enum_all_printers_info_1(buffer, offered, needed, returned); + + if (flags && PRINTER_ENUM_NAME) { + if (*name=='\0') + return enum_all_printers_info_1(buffer, offered, needed, returned); + else + return enum_printer_info_1(name, buffer, offered, needed, returned); + } + + if (flags && PRINTER_ENUM_REMOTE) + return enum_all_printers_info_1(buffer, offered, needed, returned); + + +} + +/******************************************************************** + * handle enumeration of printers at level 2 + ********************************************************************/ +static uint32 enumprinters_level2( uint32 flags, fstring servername, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + return enum_all_printers_info_2(buffer, offered, needed, returned); +} + +/******************************************************************** + * handle enumeration of printers at level 5 + ********************************************************************/ +static uint32 enumprinters_level5( uint32 flags, fstring servername, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ +/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/ + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** @@ -1747,55 +1902,48 @@ static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number) * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -uint32 _spoolss_enumprinters( - uint32 flags, - const UNISTR2 *servername, - uint32 level, - const BUFFER *buffer, - uint32 buf_size, - uint32 *offered, - uint32 *needed, - PRINTER_INFO_CTR *ctr, - uint32 *returned) +uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { - DEBUG(4,("Enumerating printers\n")); + fstring name; + + DEBUG(4,("_spoolss_enumprinters\n")); - (*returned)=0; + *needed=0; + *returned=0; + + /* + * Level 1: + * flags==PRINTER_ENUM_NAME + * if name=="" then enumerates all printers + * if name!="" then enumerate the printer + * flags==PRINTER_ENUM_REMOTE + * name is NULL, enumerate printers + * Level 2: name!="" enumerates printers, name can't be NULL + * Level 3: doesn't exist + * Level 4: does a local registry lookup + * Level 5: same as Level 2 + */ - switch (level) - { - case 1: - if (flags == PRINTER_ENUM_NAME || - flags == PRINTER_ENUM_NETWORK ) - { - /*if (is_a_printerserver(servername))*/ - enum_all_printers_info_1(&ctr->printer.printers_1, returned ); - /*else - enum_one_printer_info_1(&r_u);*/ - break; - } - case 2: - if (flags == PRINTER_ENUM_NAME || - flags == PRINTER_ENUM_NETWORK ) - { - /*if (is_a_printerserver(servername))*/ - enum_all_printers_info_2(&ctr->printer.printers_2, returned ); - /*else - enum_one_printer_info_2(&r_u);*/ - break; - } - case 3: /* doesn't exist */ - return NT_STATUS_INVALID_INFO_CLASS; - case 4: /* can't, always on local machine */ - break; - case 5: - return NT_STATUS_INVALID_INFO_CLASS; - - } - DEBUG(4,("%d printers enumerated\n", *returned)); - (*offered) = buffer->size; + unistr2_to_ascii(name, servername, sizeof(name)-1); - return 0x0; + switch (level) { + case 1: + return enumprinters_level1(flags, name, buffer, offered, needed, returned); + break; + case 2: + return enumprinters_level2(flags, name, buffer, offered, needed, returned); + break; + case 5: + return enumprinters_level5(flags, name, buffer, offered, needed, returned); + break; + case 3: + case 4: + default: + return NT_STATUS_INVALID_LEVEL; + break; + } } /**************************************************************************** @@ -2562,86 +2710,135 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, } /**************************************************************************** + Enumjobs at level 1. ****************************************************************************/ -uint32 _spoolss_enumjobs( const POLICY_HND *handle, - uint32 reqfirstjob, - uint32 reqnumofjobs, - uint32 level, - JOB_INFO_CTR *ctr, - uint32 *buf_size, - uint32 *numofjobs) +static uint32 enumjobs_level1(print_queue_struct *queue, int snum, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { - int snum; - int count; + JOB_INFO_1 *info; int i; - print_queue_struct *queue=NULL; - print_status_struct prt_status; - - DEBUG(4,("spoolss_enumjobs\n")); - - ZERO_STRUCT(prt_status); - - if (!get_printer_snum(handle, &snum)) - { - return NT_STATUS_INVALID_HANDLE; - } - - count = get_printqueue(snum, NULL, &queue, &prt_status); - (*numofjobs) = 0; - DEBUG(4,("count:[%d], status:[%d], [%s]\n", - count, prt_status.status, prt_status.message)); + info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1)); - switch (level) + for (i=0; i<*returned; i++) { - case 1: - { - for (i=0; ijob.job_info_1, - job_info_1); - - fill_job_info_1(ctr->job.job_info_1[i], - &(queue[i]), i, snum); - } - safe_free(queue); - return 0x0; - } - case 2: - { - for (i=0; ijob.job_info_2, - job_info_2); - - fill_job_info_2(ctr->job.job_info_2[i], - &(queue[i]), i, snum); - } - safe_free(queue); - return 0x0; - } + fill_job_info_1(&(info[i]), &(queue[i]), i, snum); } + /* check the required size. */ + for (i=0; i<*returned; i++) + (*needed) += spoolss_size_job_info_1(&(info[i])); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + for (i=0; i<*returned; i++) + new_smb_io_job_info_1("", buffer, &(info[i]), 0); + + /* clear memory */ safe_free(queue); + safe_free(info); - return NT_STATUS_INVALID_INFO_CLASS; + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** + Enumjobs at level 2. ****************************************************************************/ -uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid) +static uint32 enumjobs_level2(print_queue_struct *queue, int snum, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { - return 0x0; -} - -/**************************************************************************** -****************************************************************************/ + JOB_INFO_2 *info; + int i; + + info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2)); + + for (i=0; i<*returned; i++) + { + fill_job_info_2(&(info[i]), &(queue[i]), i, snum); + } + + /* check the required size. */ + for (i=0; i<*returned; i++) + (*needed) += spoolss_size_job_info_2(&(info[i])); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + for (i=0; i<*returned; i++) + new_smb_io_job_info_2("", buffer, &(info[i]), 0); + + /* clear memory */ + safe_free(queue); + safe_free(info); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumjobs. +****************************************************************************/ +uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + int snum; + print_queue_struct *queue=NULL; + print_status_struct prt_status; + + DEBUG(4,("_spoolss_enumjobs\n")); + + ZERO_STRUCT(prt_status); + + *needed=0; + *returned=0; + + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + *returned = get_printqueue(snum, NULL, &queue, &prt_status); + DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); + + switch (level) { + case 1: + return enumjobs_level1(queue, snum, buffer, offered, needed, returned); + break; + case 2: + return enumjobs_level2(queue, snum, buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_LEVEL; + break; + } +} + + + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid) +{ + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ uint32 _spoolss_setjob( const POLICY_HND *handle, uint32 jobid, uint32 level, @@ -2705,86 +2902,166 @@ uint32 _spoolss_setjob( const POLICY_HND *handle, } /**************************************************************************** + Enumerates all printer drivers at level 1. ****************************************************************************/ -uint32 _spoolss_enumprinterdrivers( const UNISTR2 *name, - const UNISTR2 *environment, - uint32 level, - DRIVER_INFO *ctr, - uint32 *offered, - uint32 *numofdrivers) +static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - NT_PRINTER_DRIVER_INFO_LEVEL driver; - int count; int i; - fstring *list; - fstring servername; - fstring architecture; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + DRIVER_INFO_1 *driver_info_1=NULL; + driver_info_1=(DRIVER_INFO_1 *)malloc(*returned * sizeof(DRIVER_INFO_1)); - DEBUG(4,("spoolss_enumdrivers\n")); - fstrcpy(servername, global_myname); + for (i=0; i<*returned; i++) { + get_a_printer_driver(&driver, 3, list[i], architecture); + fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture ); + free_a_printer_driver(driver, 3); + } + + /* check the required size. */ + 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])); + } - unistr2_to_ascii(architecture, environment, sizeof(architecture)); - count=get_ntdrivers(&list, architecture); + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; - DEBUGADD(4,("we have: [%d] drivers on archi [%s]\n",count, architecture)); - for (i=0; i offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumerates all printer drivers at level 2. +****************************************************************************/ +static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int i; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + DRIVER_INFO_2 *driver_info_2=NULL; + driver_info_2=(DRIVER_INFO_2 *)malloc(*returned * sizeof(DRIVER_INFO_2)); + + for (i=0; i<*returned; i++) { + get_a_printer_driver(&driver, 3, list[i], architecture); + fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture ); + free_a_printer_driver(driver, 3); } - (*numofdrivers)=count; + /* check the required size. */ + 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])); + } + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the form structures */ + for (i=0; i<*returned; i++) + { + DEBUGADD(6,("adding form [%d] to buffer\n",i)); + new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); + } + + safe_free(list); + + if (*needed > offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumerates all printer drivers at level 3. +****************************************************************************/ +static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int i; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + DRIVER_INFO_3 *driver_info_3=NULL; + driver_info_3=(DRIVER_INFO_3 *)malloc((*returned)*sizeof(DRIVER_INFO_3)); + + for (i=0; i<*returned; i++) { + get_a_printer_driver(&driver, 3, list[i], architecture); + fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture ); + free_a_printer_driver(driver, 3); + } - switch (level) + /* check the required size. */ + for (i=0; i<*returned; i++) { - case 1: - { - DRIVER_INFO_1 *driver_info_1=NULL; - driver_info_1=(DRIVER_INFO_1 *)malloc(count*sizeof(DRIVER_INFO_1)); + DEBUGADD(6,("adding driver [%d]'s size\n",i)); + *needed += spoolss_size_printer_driver_info_3(&(driver_info_3[i])); + } - for (i=0; idriver.info1=driver_info_1; - break; - } - case 2: - { - DRIVER_INFO_2 *driver_info_2=NULL; - driver_info_2=(DRIVER_INFO_2 *)malloc(count*sizeof(DRIVER_INFO_2)); - - for (i=0; idriver.info2=driver_info_2; - break; - } - case 3: - { - DRIVER_INFO_3 *driver_info_3=NULL; - driver_info_3=(DRIVER_INFO_3 *)malloc(count*sizeof(DRIVER_INFO_3)); - - for (i=0; idriver.info3=driver_info_3; - break; - } - default: - { - return NT_STATUS_INVALID_INFO_CLASS; - } + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the form structures */ + 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); } - return 0x0; + safe_free(list); + + if (*needed > offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumerates all printer drivers. +****************************************************************************/ +uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + int i; + fstring *list; + fstring servername; + fstring architecture; + + DEBUG(4,("_spoolss_enumprinterdrivers\n")); + fstrcpy(servername, global_myname); + *needed=0; + *returned=0; + + unistr2_to_ascii(architecture, environment, sizeof(architecture)-1); + *returned=get_ntdrivers(&list, architecture); + + DEBUGADD(4,("we have: [%d] drivers in environment [%s]\n", *returned, architecture)); + for (i=0; i<*returned; i++) + DEBUGADD(5,("driver: [%s]\n", list[i])); + + switch (level) { + case 1: + return enumprinterdrivers_level1(list, servername, architecture, buffer, offered, needed, returned); + break; + case 2: + return enumprinterdrivers_level2(list, servername, architecture, buffer, offered, needed, returned); + break; + case 3: + return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** @@ -2801,26 +3078,6 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position) form->bottom=list->bottom; } -/**************************************************************************** -****************************************************************************/ -static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) -{ - prs_struct *ps; - uint32 extra_space; - - ps=&(buffer->prs); - - /* damn, I'm doing the reverse operation of prs_grow() :) */ - extra_space = buffer_size - prs_data_size(ps); - - if (!prs_grow(ps, extra_space)) - return False; - - buffer->string_at_end=buffer_size; - - return True; -} - /**************************************************************************** ****************************************************************************/ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, @@ -2832,7 +3089,6 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, int buffer_size=0; int i; - DEBUG(4,("_new_spoolss_enumforms\n")); DEBUGADD(5,("Offered buffer size [%d]\n", offered)); DEBUGADD(5,("Info level [%d]\n", level)); @@ -2886,43 +3142,9 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_enumforms( const POLICY_HND *handle, - uint32 level, - FORM_1 **forms_1, - uint32 *offered, - uint32 *numofforms) +static void fill_port_1(PORT_INFO_1 *port, char *name) { - int count; - int i; - nt_forms_struct *list=NULL; - (*forms_1)=NULL; - - DEBUG(4,("spoolss_enumforms\n")); - - count = get_ntforms(&list); - (*numofforms) = count; - - DEBUGADD(5,("Offered buffer size [%d]\n", *offered)); - DEBUGADD(5,("Number of forms [%d]\n", *numofforms)); - DEBUGADD(5,("Info level [%d]\n", level)); - - switch (level) - { - case 1: - { - (*forms_1)=(FORM_1 *)malloc(count*sizeof(FORM_1)); - for (i=0; iport_name), name); } /**************************************************************************** @@ -2938,45 +3160,135 @@ static void fill_port_2(PORT_INFO_2 *port, char *name) } /**************************************************************************** + enumports level 1. ****************************************************************************/ -uint32 _spoolss_enumports( const UNISTR2 *name, - uint32 level, - PORT_INFO_CTR *ctr, - uint32 *offered, - uint32 *numofports) +static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int n_services=lp_numservices(); int snum; + int i=0; + + PORT_INFO_1 *ports=NULL; - DEBUG(4,("spoolss_enumports\n")); + for (snum=0; snumport.info_2=ports_2; - return 0x0; - } + DEBUGADD(6,("adding port [%d]'s size\n", i)); + *needed += spoolss_size_port_info_1(&(ports[i])); + } + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the ports structures */ + for (i=0; i<*returned; i++) + { + DEBUGADD(6,("adding port [%d] to buffer\n", i)); + new_smb_io_port_1("", buffer, &(ports[i]), 0); + } + + safe_free(ports); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + + +/**************************************************************************** + enumports level 2. +****************************************************************************/ +static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int n_services=lp_numservices(); + int snum; + int i=0; + + PORT_INFO_2 *ports=NULL; + + for (snum=0; snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + enumports. +****************************************************************************/ +uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + DEBUG(4,("spoolss_enumports\n")); + + *returned=0; + *needed=0; + + switch (level) { + case 1: + return enumports_level_1(buffer, offered, needed, returned); + break; + case 2: + return enumports_level_2(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** @@ -3293,13 +3605,39 @@ uint32 _spoolss_setform( const POLICY_HND *handle, } /**************************************************************************** + enumprintprocessors level 1. ****************************************************************************/ -uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, - const UNISTR2 *environment, - uint32 level, - PRINTPROCESSOR_1 **info_1, - uint32 *offered, - uint32 *numofprintprocessors) +static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTPROCESSOR_1 *info_1=NULL; + + info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1)); + (*returned) = 0x1; + + init_unistr(&(info_1->name), "winprint"); + + *needed += spoolss_size_printprocessor_info_1(info_1); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printprocessor_info_1("", buffer, info_1, 0); + + safe_free(info_1); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { DEBUG(5,("spoolss_enumprintprocessors\n")); @@ -3310,26 +3648,85 @@ uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, * and I can use my nice printer checker. */ - (*numofprintprocessors) = 0x1; - (*info_1) = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1)); + *returned=0; + *needed=0; - if ((*info_1) == NULL) - { - return NT_STATUS_NO_MEMORY; + switch (level) { + case 1: + return enumprintprocessors_level_1(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; } - init_unistr(&((*info_1)->name), "winprint"); +} - return 0x0; +/**************************************************************************** + enumprintmonitors level 1. +****************************************************************************/ +static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTMONITOR_1 *info_1=NULL; + + info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1)); + (*returned) = 0x1; + + init_unistr(&(info_1->name), "Local Port"); + + *needed += spoolss_size_printmonitor_info_1(info_1); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printmonitor_info_1("", buffer, info_1, 0); + + safe_free(info_1); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** + enumprintmonitors level 2. ****************************************************************************/ -uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, - uint32 level, - PRINTMONITOR_1 **info_1, - uint32 *offered, - uint32 *numofprintmonitors) +static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTMONITOR_2 *info_2=NULL; + + info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2)); + (*returned) = 0x1; + + init_unistr(&(info_2->name), "Local Port"); + init_unistr(&(info_2->environment), "Windows NT X86"); + init_unistr(&(info_2->dll_name), "localmon.dll"); + + *needed += spoolss_size_printmonitor_info_2(info_2); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printmonitor_info_2("", buffer, info_2, 0); + + safe_free(info_2); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { DEBUG(5,("spoolss_enumprintmonitors\n")); @@ -3340,16 +3737,20 @@ uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, * and I can use my nice printer checker. */ - (*numofprintmonitors) = 0x1; - (*info_1) = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1)); - if ((*info_1) == NULL) - { - return NT_STATUS_NO_MEMORY; - } + *returned=0; + *needed=0; - init_unistr(&((*info_1)->name), "Local Port"); - - return 0x0; + switch (level) { + case 1: + return enumprintmonitors_level_1(buffer, offered, needed, returned); + break; + case 2: + return enumprintmonitors_level_2(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** -- cgit