diff options
-rwxr-xr-x | source3/include/rpc_spoolss.h | 4 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 28 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 101 |
3 files changed, 118 insertions, 15 deletions
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 75fe021a68..f2f789a49e 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -2185,8 +2185,8 @@ typedef struct spool_q_xcvdataport { typedef struct spool_r_xcvdataport { RPC_BUFFER outdata; - uint32 *unknown1; - uint32 *unknown2; + uint32 needed; + uint32 unknown; WERROR status; } SPOOL_R_XCVDATAPORT; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 6f3245243d..2bb8a7bbdd 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -7460,13 +7460,31 @@ BOOL spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_st if (!prs_align(ps)) return False; - if(!prs_pointer("unknown1", ps, depth, (void**)&r_u->unknown1, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_uint32)) - return False; - if(!prs_pointer("unknown2", ps, depth, (void**)&r_u->unknown2, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_uint32)) - return False; - if(!prs_werror("status", ps, depth, &r_u->status)) + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + if (!prs_uint32("unknown", ps, depth, &r_u->unknown)) + return False; + + if(!prs_werror("status", ps, depth, &r_u->status)) return False; return True; } +/******************************************************************* + ********************************************************************/ + +BOOL make_monitorui_buf( RPC_BUFFER *buf, const char *dllname ) +{ + UNISTR string; + + if ( !buf ) + return False; + + init_unistr( &string, dllname ); + + if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) ) + return False; + + return True; +} diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 98abd9d15e..126c2cc140 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -86,6 +86,15 @@ extern STANDARD_MAPPING printer_std_mapping, printserver_std_mapping; #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \ ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid()) + +/* API table for Xcv Monitor functions */ + +struct xcv_api_table { + const char *name; + WERROR(*fn) (RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed); +}; + + /* translate between internal status numbers and NT status numbers */ static int nt_printj_status(int v) { @@ -9388,23 +9397,94 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC } /******************************************************************* + Streams the monitor UI DLL name in UNICODE +*******************************************************************/ + +static WERROR xcvtcp_monitorui( RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed ) +{ + const char *dllname = "tcpmonui.dll"; + + *needed = (strlen(dllname)+1) * 2; + + if ( rpcbuf_get_size(out) < *needed ) { + return WERR_INSUFFICIENT_BUFFER; + } + + if ( !make_monitorui_buf( out, dllname ) ) { + return WERR_NOMEM; + } + + return WERR_OK; +} + +/******************************************************************* *******************************************************************/ -static WERROR process_xcvtcp_command( const char *command, RPC_BUFFER *inbuf, RPC_BUFFER *outbuf ) +struct xcv_api_table xcvtcp_cmds[] = { + { "MonitorUI", xcvtcp_monitorui }, + { NULL, NULL } +}; + +static WERROR process_xcvtcp_command( const char *command, RPC_BUFFER *inbuf, + RPC_BUFFER *outbuf, uint32 *needed ) { + int i; + DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command)); + for ( i=0; xcvtcp_cmds[i].name; i++ ) { + if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 ) + return xcvtcp_cmds[i].fn( inbuf, outbuf, needed ); + } + + return WERR_BADFUNC; +} + +/******************************************************************* +*******************************************************************/ + +static WERROR xcvlocal_monitorui( RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed ) +{ + const char *dllname = "localui.dll"; + + *needed = (strlen(dllname)+1) * 2; + + if ( rpcbuf_get_size(out) < *needed ) { + return WERR_INSUFFICIENT_BUFFER; + } + + if ( !make_monitorui_buf( out, dllname )) { + return WERR_NOMEM; + } + return WERR_OK; } /******************************************************************* *******************************************************************/ -static WERROR process_xcvlocal_command( const char *command, RPC_BUFFER *inbuf, RPC_BUFFER *outbuf ) +struct xcv_api_table xcvlocal_cmds[] = { + { "MonitorUI", xcvlocal_monitorui }, + { NULL, NULL } +}; + + +/******************************************************************* +*******************************************************************/ + +static WERROR process_xcvlocal_command( const char *command, RPC_BUFFER *inbuf, + RPC_BUFFER *outbuf, uint32 *needed ) { + int i; + DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command)); - return WERR_OK; + + for ( i=0; xcvlocal_cmds[i].name; i++ ) { + if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 ) + return xcvlocal_cmds[i].fn( inbuf, outbuf , needed ); + } + return WERR_BADFUNC; } /******************************************************************* @@ -9422,8 +9502,8 @@ WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_X /* Has to be a handle to the TCP/IP port monitor */ - if ( Printer->printer_type != SPLHND_PORTMON_TCP ) { - DEBUG(2,("_spoolss_xcvdataport: Call only valid for the TCP/IP Port Monitor\n")); + if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) { + DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n")); return WERR_BADFID; } @@ -9437,13 +9517,18 @@ WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_X /* Get the command name. There's numerous commands supported by the TCPMON interface. */ - rpcstr_pull(command, q_u->dataname.buffer, sizeof(command), q_u->dataname.uni_str_len*2, 0); + rpcstr_pull(command, q_u->dataname.buffer, sizeof(command), + q_u->dataname.uni_str_len*2, 0); + + /* Allocate the outgoing buffer */ + + rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx ); switch ( Printer->printer_type ) { case SPLHND_PORTMON_TCP: - return process_xcvtcp_command( command, &q_u->indata, &r_u->outdata ); + return process_xcvtcp_command( command, &q_u->indata, &r_u->outdata, &r_u->needed ); case SPLHND_PORTMON_LOCAL: - return process_xcvlocal_command( command, &q_u->indata, &r_u->outdata ); + return process_xcvlocal_command( command, &q_u->indata, &r_u->outdata, &r_u->needed ); } return WERR_INVALID_PRINT_MONITOR; |