2000-11-18 02:10:56 +03:00
/*
2002-03-22 09:24:38 +03:00
* Unix SMB / CIFS implementation .
2000-02-07 19:17:59 +03:00
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 2000 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 2000 ,
2002-03-12 03:16:03 +03:00
* Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998 - 2000 ,
2002-09-25 19:19:00 +04:00
* Copyright ( C ) Jeremy Allison 2001 - 2002 ,
2002-07-15 14:35:28 +04:00
* Copyright ( C ) Gerald Carter 2000 - 2002 ,
2002-03-12 03:16:03 +03:00
* Copyright ( C ) Tim Potter 2001 - 2002.
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2001-08-10 09:41:53 +04:00
/* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
up , all the errors returned are DOS errors , not NT status codes . */
2000-02-07 19:17:59 +03:00
# include "includes.h"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
/* #define EMULATE_WIN2K_HACK 1 */
2000-02-07 19:17:59 +03:00
# ifndef MAX_OPEN_PRINTER_EXS
# define MAX_OPEN_PRINTER_EXS 50
# endif
2002-02-09 07:10:24 +03:00
# define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
2001-08-10 23:38:53 +04:00
# define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
2000-02-07 19:17:59 +03:00
# define PRINTER_HANDLE_IS_PRINTER 0
# define PRINTER_HANDLE_IS_PRINTSERVER 1
2002-07-15 14:35:28 +04:00
/* Table to map the driver version */
/* to OS */
char * drv_ver_to_os [ ] = {
" WIN9X " , /* driver version/cversion 0 */
" " , /* unused ? */
" WINNT " , /* driver version/cversion 2 */
" WIN2K " , /* driver version/cversion 3 */
} ;
2001-05-18 08:11:17 +04:00
struct table_node {
char * long_archi ;
char * short_archi ;
int version ;
} ;
2000-02-07 19:17:59 +03:00
/* structure to store the printer handles */
/* and a reference to what it's pointing to */
/* and the notify info asked about */
/* that's the central struct */
2000-02-25 02:01:24 +03:00
typedef struct _Printer {
2002-02-09 07:10:24 +03:00
struct _Printer * prev , * next ;
2000-02-24 19:27:06 +03:00
BOOL document_started ;
BOOL page_started ;
2002-08-17 19:34:15 +04:00
uint32 jobid ; /* jobid in printing backend */
2000-02-24 19:27:06 +03:00
BOOL printer_type ;
union {
2000-07-22 04:48:29 +04:00
fstring handlename ;
2000-02-24 19:27:06 +03:00
fstring printerservername ;
} dev ;
uint32 type ;
2002-03-07 04:02:48 +03:00
uint32 access_granted ;
2000-02-24 19:27:06 +03:00
struct {
uint32 flags ;
uint32 options ;
2000-11-18 02:10:56 +03:00
fstring localmachine ;
2000-02-24 19:27:06 +03:00
uint32 printerlocal ;
SPOOL_NOTIFY_OPTION * option ;
2000-09-26 01:05:18 +04:00
POLICY_HND client_hnd ;
uint32 client_connected ;
2002-07-15 14:35:28 +04:00
uint32 change ;
2000-02-24 19:27:06 +03:00
} notify ;
2000-02-27 01:22:24 +03:00
struct {
fstring machine ;
fstring user ;
} client ;
2002-09-25 19:19:00 +04:00
/* devmode sent in the OpenPrinter() call */
NT_DEVICEMODE * nt_devmode ;
2000-02-25 02:01:24 +03:00
} Printer_entry ;
2002-02-09 07:10:24 +03:00
static Printer_entry * printers_list ;
2000-03-10 20:12:24 +03:00
typedef struct _counter_printer_0 {
ubi_dlNode Next ;
ubi_dlNode Prev ;
int snum ;
uint32 counter ;
} counter_printer_0 ;
static ubi_dlList counter_list ;
2002-08-17 19:34:15 +04:00
static struct cli_state notify_cli ; /* print notify back-channel */
2000-09-26 01:05:18 +04:00
static uint32 smb_connections = 0 ;
2000-02-07 19:17:59 +03:00
2002-03-15 11:14:10 +03:00
/* in printing/nt_printing.c */
2002-04-15 07:49:53 +04:00
extern STANDARD_MAPPING printer_std_mapping , printserver_std_mapping ;
2002-03-15 11:14:10 +03:00
2002-02-09 07:10:24 +03:00
# 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 ( ) )
2000-02-07 19:17:59 +03:00
2000-04-16 11:28:06 +04:00
/* translate between internal status numbers and NT status numbers */
static int nt_printj_status ( int v )
{
switch ( v ) {
case LPQ_QUEUED :
2001-02-23 06:59:37 +03:00
return 0 ;
case LPQ_PAUSED :
return JOB_STATUS_PAUSED ;
2000-04-16 11:28:06 +04:00
case LPQ_SPOOLING :
2001-02-23 06:59:37 +03:00
return JOB_STATUS_SPOOLING ;
2000-04-16 11:28:06 +04:00
case LPQ_PRINTING :
2001-02-23 06:59:37 +03:00
return JOB_STATUS_PRINTING ;
case LPQ_ERROR :
return JOB_STATUS_ERROR ;
case LPQ_DELETING :
return JOB_STATUS_DELETING ;
case LPQ_OFFLINE :
return JOB_STATUS_OFFLINE ;
case LPQ_PAPEROUT :
return JOB_STATUS_PAPEROUT ;
case LPQ_PRINTED :
return JOB_STATUS_PRINTED ;
case LPQ_DELETED :
return JOB_STATUS_DELETED ;
case LPQ_BLOCKED :
return JOB_STATUS_BLOCKED ;
case LPQ_USER_INTERVENTION :
return JOB_STATUS_USER_INTERVENTION ;
2000-04-16 11:28:06 +04:00
}
return 0 ;
}
static int nt_printq_status ( int v )
{
switch ( v ) {
case LPQ_PAUSED :
2000-09-13 01:45:42 +04:00
return PRINTER_STATUS_PAUSED ;
2000-04-16 11:28:06 +04:00
case LPQ_QUEUED :
case LPQ_SPOOLING :
case LPQ_PRINTING :
return 0 ;
}
return 0 ;
}
2001-03-01 03:14:45 +03:00
/****************************************************************************
Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_spool_notify_option ( SPOOL_NOTIFY_OPTION * * pp )
{
2001-09-17 14:26:23 +04:00
if ( * pp = = NULL )
2001-03-01 03:14:45 +03:00
return ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( ( * pp ) - > ctr . type ) ;
SAFE_FREE ( * pp ) ;
2001-03-01 03:14:45 +03:00
}
2001-03-11 03:32:10 +03:00
/***************************************************************************
Disconnect from the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void srv_spoolss_replycloseprinter ( POLICY_HND * handle )
{
2002-04-11 05:50:18 +04:00
WERROR result ;
2001-03-11 03:32:10 +03:00
/* weird if the test succeds !!! */
if ( smb_connections = = 0 ) {
DEBUG ( 0 , ( " srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel ! \n " ) ) ;
return ;
}
2002-08-17 19:34:15 +04:00
result = cli_spoolss_reply_close_printer ( & notify_cli , notify_cli . mem_ctx , handle ) ;
2002-03-15 11:14:10 +03:00
2002-04-11 05:50:18 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
DEBUG ( 0 , ( " srv_spoolss_replycloseprinter: reply_close_printer failed [%s]. \n " ,
2002-04-11 06:13:56 +04:00
dos_errstr ( result ) ) ) ;
2001-03-11 03:32:10 +03:00
/* if it's the last connection, deconnect the IPC$ share */
if ( smb_connections = = 1 ) {
2002-08-17 19:34:15 +04:00
cli_nt_session_close ( & notify_cli ) ;
cli_ulogoff ( & notify_cli ) ;
cli_shutdown ( & notify_cli ) ;
2002-07-15 14:35:28 +04:00
message_deregister ( MSG_PRINTER_NOTIFY2 ) ;
2002-09-25 19:19:00 +04:00
/* Tell the connections db we're no longer interested in
* printer notify messages . */
register_message_flags ( False , FLAG_MSG_PRINTING ) ;
2001-03-11 03:32:10 +03:00
}
smb_connections - - ;
}
/****************************************************************************
Functions to free a printer entry datastruct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_printer_entry ( void * ptr )
{
Printer_entry * Printer = ( Printer_entry * ) ptr ;
if ( Printer - > notify . client_connected = = True )
srv_spoolss_replycloseprinter ( & Printer - > notify . client_hnd ) ;
Printer - > notify . flags = 0 ;
Printer - > notify . options = 0 ;
Printer - > notify . localmachine [ 0 ] = ' \0 ' ;
Printer - > notify . printerlocal = 0 ;
free_spool_notify_option ( & Printer - > notify . option ) ;
Printer - > notify . option = NULL ;
Printer - > notify . client_connected = False ;
2002-09-25 19:19:00 +04:00
free_nt_devicemode ( & Printer - > nt_devmode ) ;
2001-03-11 03:32:10 +03:00
2002-02-09 07:10:24 +03:00
/* Remove from the internal list. */
DLIST_REMOVE ( printers_list , Printer ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( Printer ) ;
2001-03-11 03:32:10 +03:00
}
2001-03-01 03:14:45 +03:00
/****************************************************************************
Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
SPOOL_NOTIFY_OPTION * dup_spool_notify_option ( SPOOL_NOTIFY_OPTION * sp )
{
2001-03-01 06:04:13 +03:00
SPOOL_NOTIFY_OPTION * new_sp = NULL ;
2001-03-01 03:14:45 +03:00
if ( ! sp )
return NULL ;
new_sp = ( SPOOL_NOTIFY_OPTION * ) malloc ( sizeof ( SPOOL_NOTIFY_OPTION ) ) ;
if ( ! new_sp )
return NULL ;
* new_sp = * sp ;
if ( sp - > ctr . count ) {
new_sp - > ctr . type = ( SPOOL_NOTIFY_OPTION_TYPE * ) memdup ( sp - > ctr . type , sizeof ( SPOOL_NOTIFY_OPTION_TYPE ) * sp - > ctr . count ) ;
if ( ! new_sp - > ctr . type ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( new_sp ) ;
2001-03-01 03:14:45 +03:00
return NULL ;
}
}
return new_sp ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
find printer index by handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static Printer_entry * find_printer_index_by_hnd ( pipes_struct * p , POLICY_HND * hnd )
2000-09-26 01:05:18 +04:00
{
2001-03-11 03:32:10 +03:00
Printer_entry * find_printer = NULL ;
2000-09-26 01:05:18 +04:00
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , hnd , ( void * * ) & find_printer ) ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " find_printer_index_by_hnd: Printer handle not found: " ) ) ;
2001-03-11 03:32:10 +03:00
return NULL ;
2000-09-26 14:15:12 +04:00
}
2001-03-11 03:32:10 +03:00
return find_printer ;
2000-09-26 01:05:18 +04:00
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
2002-02-09 07:10:24 +03:00
Close printer index by handle .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL close_printer_handle ( pipes_struct * p , POLICY_HND * hnd )
2000-02-07 19:17:59 +03:00
{
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , hnd ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " close_printer_handle: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( hnd ) ) ) ;
2000-02-07 19:17:59 +03:00
return False ;
}
2001-03-11 03:32:10 +03:00
close_policy_hnd ( p , hnd ) ;
2000-02-25 02:01:24 +03:00
2000-02-07 19:17:59 +03:00
return True ;
}
2000-05-02 19:31:55 +04:00
/****************************************************************************
2002-02-09 07:10:24 +03:00
Delete a printer given a handle .
2000-05-02 19:31:55 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-02-09 07:10:24 +03:00
2001-09-04 11:13:01 +04:00
static WERROR delete_printer_handle ( pipes_struct * p , POLICY_HND * hnd )
2000-05-02 19:31:55 +04:00
{
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , hnd ) ;
2000-05-02 19:31:55 +04:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " delete_printer_handle: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( hnd ) ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-05-02 19:31:55 +04:00
}
2002-09-28 02:51:44 +04:00
/*
* It turns out that Windows allows delete printer on a handle
* opened by an admin user , then used on a pipe handle created
* by an anonymous user . . . . . but they ' re working on security . . . . riiight !
* JRA .
*/
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER ) {
DEBUG ( 3 , ( " delete_printer_handle: denied by handle \n " ) ) ;
return WERR_ACCESS_DENIED ;
}
#if 0
2001-01-23 23:25:25 +03:00
/* Check calling user has permission to delete printer. Note that
since we set the snum parameter to - 1 only administrators can
delete the printer . This stops people with the Full Control
permission from deleting the printer . */
if ( ! print_access_check ( NULL , - 1 , PRINTER_ACCESS_ADMINISTER ) ) {
DEBUG ( 3 , ( " printer delete denied by security descriptor \n " ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_ACCESS_DENIED ;
2000-05-02 19:31:55 +04:00
}
2002-09-28 02:51:44 +04:00
# endif
2000-05-02 19:31:55 +04:00
2002-10-01 22:26:00 +04:00
if ( del_a_printer ( Printer - > dev . handlename ) ! = 0 ) {
DEBUG ( 3 , ( " Error deleting printer %s \n " , Printer - > dev . handlename ) ) ;
return WERR_BADFID ;
}
2000-08-01 00:41:51 +04:00
if ( * lp_deleteprinter_cmd ( ) ) {
char * cmd = lp_deleteprinter_cmd ( ) ;
pstring command ;
int ret ;
int i ;
/* Printer->dev.handlename equals portname equals sharename */
2001-02-16 22:21:18 +03:00
slprintf ( command , sizeof ( command ) - 1 , " %s \" %s \" " , cmd ,
2000-08-01 00:41:51 +04:00
Printer - > dev . handlename ) ;
2001-04-13 04:37:00 +04:00
DEBUG ( 10 , ( " Running [%s] \n " , command ) ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( command , NULL ) ;
2000-08-01 00:41:51 +04:00
if ( ret ! = 0 ) {
2001-09-04 11:13:01 +04:00
return WERR_BADFID ; /* What to return here? */
2000-08-01 00:41:51 +04:00
}
DEBUGADD ( 10 , ( " returned [%d] \n " , ret ) ) ;
2000-09-26 04:54:18 +04:00
/* Send SIGHUP to process group... is there a better way? */
2000-09-13 22:50:38 +04:00
kill ( 0 , SIGHUP ) ;
2000-08-01 00:41:51 +04:00
if ( ( i = lp_servicenumber ( Printer - > dev . handlename ) ) > = 0 ) {
lp_killservice ( i ) ;
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-08-01 00:41:51 +04:00
} else
2001-09-04 11:13:01 +04:00
return WERR_ACCESS_DENIED ;
2000-08-01 00:41:51 +04:00
}
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2002-01-22 22:45:17 +03:00
}
2000-05-02 19:31:55 +04:00
2000-02-07 19:17:59 +03:00
/****************************************************************************
2002-03-07 04:02:48 +03:00
Return the snum of a printer corresponding to an handle .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-03-11 03:32:10 +03:00
static BOOL get_printer_snum ( pipes_struct * p , POLICY_HND * hnd , int * number )
2000-02-07 19:17:59 +03:00
{
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , hnd ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " get_printer_snum: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( hnd ) ) ) ;
2000-02-07 19:17:59 +03:00
return False ;
}
2000-02-25 02:01:24 +03:00
switch ( Printer - > printer_type ) {
2000-11-18 02:10:56 +03:00
case PRINTER_HANDLE_IS_PRINTER :
2000-07-22 04:48:29 +04:00
DEBUG ( 4 , ( " short name:%s \n " , Printer - > dev . handlename ) ) ;
* number = print_queue_snum ( Printer - > dev . handlename ) ;
2000-04-16 10:20:43 +04:00
return ( * number ! = - 1 ) ;
2000-02-07 19:17:59 +03:00
case PRINTER_HANDLE_IS_PRINTSERVER :
return False ;
default :
return False ;
}
}
/****************************************************************************
2000-07-22 04:48:29 +04:00
Set printer handle type .
Check if it ' s \ \ server or \ \ server \ printer
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static BOOL set_printer_hnd_printertype ( Printer_entry * Printer , char * handlename )
2000-02-07 19:17:59 +03:00
{
2000-07-22 04:48:29 +04:00
DEBUG ( 3 , ( " Setting printer type=%s \n " , handlename ) ) ;
2000-02-07 19:17:59 +03:00
2000-07-22 04:48:29 +04:00
if ( strlen ( handlename ) < 3 ) {
DEBUGADD ( 4 , ( " A print server must have at least 1 char ! %s \n " , handlename ) ) ;
2000-02-07 19:17:59 +03:00
return False ;
}
/* it's a print server */
2001-07-04 11:36:09 +04:00
if ( * handlename = = ' \\ ' & & * ( handlename + 1 ) = = ' \\ ' & & ! strchr_m ( handlename + 2 , ' \\ ' ) ) {
2000-02-07 19:17:59 +03:00
DEBUGADD ( 4 , ( " Printer is a print server \n " ) ) ;
2000-02-25 02:01:24 +03:00
Printer - > printer_type = PRINTER_HANDLE_IS_PRINTSERVER ;
2000-02-07 19:17:59 +03:00
}
/* it's a printer */
else {
DEBUGADD ( 4 , ( " Printer is a printer \n " ) ) ;
2000-02-25 02:01:24 +03:00
Printer - > printer_type = PRINTER_HANDLE_IS_PRINTER ;
2000-02-07 19:17:59 +03:00
}
2000-10-06 22:13:52 +04:00
return True ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
2000-07-22 04:48:29 +04:00
Set printer handle name .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static BOOL set_printer_hnd_name ( Printer_entry * Printer , char * handlename )
2000-02-07 19:17:59 +03:00
{
int snum ;
int n_services = lp_numservices ( ) ;
2000-02-15 21:07:45 +03:00
char * aprinter ;
2002-02-15 21:59:34 +03:00
fstring sname ;
2000-02-15 21:07:45 +03:00
BOOL found = False ;
2000-02-07 19:17:59 +03:00
2000-07-22 04:48:29 +04:00
DEBUG ( 4 , ( " Setting printer name=%s (len=%d) \n " , handlename , strlen ( handlename ) ) ) ;
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTSERVER ) {
ZERO_STRUCT ( Printer - > dev . printerservername ) ;
2000-07-22 04:48:29 +04:00
strncpy ( Printer - > dev . printerservername , handlename , strlen ( handlename ) ) ;
2000-02-07 19:17:59 +03:00
return True ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
if ( Printer - > printer_type ! = PRINTER_HANDLE_IS_PRINTER )
2000-02-07 19:17:59 +03:00
return False ;
2000-02-15 21:07:45 +03:00
2001-04-27 21:08:33 +04:00
if ( * handlename = = ' \\ ' ) {
2001-07-04 11:36:09 +04:00
aprinter = strchr_m ( handlename + 2 , ' \\ ' ) ;
2001-04-27 21:08:33 +04:00
aprinter + + ;
}
else {
aprinter = handlename ;
}
2000-02-15 21:07:45 +03:00
DEBUGADD ( 5 , ( " searching for [%s] (len=%d) \n " , aprinter , strlen ( aprinter ) ) ) ;
2000-04-11 01:47:46 +04:00
2000-02-15 21:07:45 +03:00
/*
2002-02-15 21:59:34 +03:00
* The original code allowed smbd to store a printer name that
* was different from the share name . This is not possible
* anymore , so I ' ve simplified this loop greatly . Here
* we are just verifying that the printer name is a valid
* printer service defined in smb . conf
2002-07-15 14:35:28 +04:00
* - - jerry [ Fri Feb 15 11 : 17 : 46 CST 2002 ]
2000-02-15 21:07:45 +03:00
*/
2002-02-15 21:59:34 +03:00
for ( snum = 0 ; snum < n_services ; snum + + ) {
2000-04-16 10:20:43 +04:00
if ( ! ( lp_snum_ok ( snum ) & & lp_print_ok ( snum ) ) )
2000-02-15 21:07:45 +03:00
continue ;
2002-02-15 21:59:34 +03:00
fstrcpy ( sname , lp_servicename ( snum ) ) ;
2000-02-15 21:07:45 +03:00
2002-02-15 21:59:34 +03:00
DEBUGADD ( 5 , ( " share:%s \n " , sname ) ) ;
2000-02-15 21:07:45 +03:00
2002-02-15 21:59:34 +03:00
if ( ! StrCaseCmp ( sname , aprinter ) ) {
found = True ;
break ;
2000-02-15 21:07:45 +03:00
}
2000-04-11 01:47:46 +04:00
}
2002-02-15 21:59:34 +03:00
2000-04-11 01:47:46 +04:00
2002-02-15 21:59:34 +03:00
if ( ! found ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 4 , ( " Printer not found \n " ) ) ;
2000-02-07 19:17:59 +03:00
return False ;
2000-02-15 21:07:45 +03:00
}
2002-02-15 21:59:34 +03:00
DEBUGADD ( 4 , ( " set_printer_hnd_name: Printer found: %s -> %s \n " , aprinter , sname ) ) ;
2000-06-24 04:15:08 +04:00
2000-07-22 04:48:29 +04:00
ZERO_STRUCT ( Printer - > dev . handlename ) ;
2002-02-15 21:59:34 +03:00
fstrcpy ( Printer - > dev . handlename , sname ) ;
2000-06-01 06:35:30 +04:00
2000-02-15 21:07:45 +03:00
return True ;
2000-02-07 19:17:59 +03:00
}
2000-07-22 04:48:29 +04:00
/****************************************************************************
2002-03-07 04:02:48 +03:00
Find first available printer slot . creates a printer handle for you .
2000-07-22 04:48:29 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
static BOOL open_printer_hnd ( pipes_struct * p , POLICY_HND * hnd , char * name , uint32 access_granted )
2000-07-22 04:48:29 +04:00
{
Printer_entry * new_printer ;
2000-09-26 04:54:18 +04:00
DEBUG ( 10 , ( " open_printer_hnd: name [%s] \n " , name ) ) ;
2000-07-22 04:48:29 +04:00
if ( ( new_printer = ( Printer_entry * ) malloc ( sizeof ( Printer_entry ) ) ) = = NULL )
return False ;
ZERO_STRUCTP ( new_printer ) ;
new_printer - > notify . option = NULL ;
2002-02-09 07:10:24 +03:00
/* Add to the internal list. */
DLIST_ADD ( printers_list , new_printer ) ;
2001-03-11 03:32:10 +03:00
if ( ! create_policy_hnd ( p , hnd , free_printer_entry , new_printer ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( new_printer ) ;
2001-03-11 03:32:10 +03:00
return False ;
}
2000-07-22 04:48:29 +04:00
if ( ! set_printer_hnd_printertype ( new_printer , name ) ) {
2001-03-11 03:32:10 +03:00
close_printer_handle ( p , hnd ) ;
2000-07-22 04:48:29 +04:00
return False ;
}
if ( ! set_printer_hnd_name ( new_printer , name ) ) {
2001-03-11 03:32:10 +03:00
close_printer_handle ( p , hnd ) ;
2000-07-22 04:48:29 +04:00
return False ;
}
2002-03-07 04:02:48 +03:00
new_printer - > access_granted = access_granted ;
2001-01-15 21:36:50 +03:00
2002-03-07 04:02:48 +03:00
DEBUG ( 5 , ( " %d printer handles active \n " , ( int ) p - > pipe_handles - > count ) ) ;
2000-02-07 19:17:59 +03:00
return True ;
}
2000-02-15 21:07:45 +03:00
/****************************************************************************
2002-03-07 04:02:48 +03:00
Allocate more memory for a BUFFER .
2000-02-15 21:07:45 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-15 21:07:45 +03:00
static BOOL alloc_buffer_size ( NEW_BUFFER * buffer , uint32 buffer_size )
{
prs_struct * ps ;
uint32 extra_space ;
2000-03-06 14:13:40 +03:00
uint32 old_offset ;
2000-02-15 21:07:45 +03:00
2000-06-03 01:16:39 +04:00
ps = & buffer - > prs ;
2000-02-15 21:07:45 +03:00
/* 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 ) ;
2000-03-06 14:13:40 +03:00
2000-11-18 02:10:56 +03:00
/*
2000-03-06 14:13:40 +03:00
* save the offset and move to the end of the buffer
2000-11-18 02:10:56 +03:00
* prs_grow ( ) checks the extra_space against the offset
2000-03-06 14:13:40 +03:00
*/
old_offset = prs_offset ( ps ) ;
prs_set_offset ( ps , prs_data_size ( ps ) ) ;
2000-02-15 21:07:45 +03:00
if ( ! prs_grow ( ps , extra_space ) )
return False ;
2000-03-06 14:13:40 +03:00
prs_set_offset ( ps , old_offset ) ;
2000-02-15 21:07:45 +03:00
buffer - > string_at_end = prs_data_size ( ps ) ;
return True ;
}
2002-07-15 14:35:28 +04:00
2002-03-15 11:14:10 +03:00
/***************************************************************************
2002-07-15 14:35:28 +04:00
check to see if the client motify handle is monitoring the notification
given by ( notify_type , notify_field ) .
2002-03-15 11:14:10 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
static BOOL is_monitoring_event_flags ( uint32 flags , uint16 notify_type ,
uint16 notify_field )
2002-03-15 11:14:10 +03:00
{
return True ;
}
2000-02-15 21:07:45 +03:00
2002-07-15 14:35:28 +04:00
static BOOL is_monitoring_event ( Printer_entry * p , uint16 notify_type ,
uint16 notify_field )
2002-03-15 11:14:10 +03:00
{
2002-07-15 14:35:28 +04:00
SPOOL_NOTIFY_OPTION * option = p - > notify . option ;
uint32 i , j ;
2002-09-25 19:19:00 +04:00
/*
* Flags should always be zero when the change notify
* is registered by the cliebnt ' s spooler . A user Win32 app
* might use the flags though instead of the NOTIFY_OPTION_INFO
* - - jerry
*/
2002-07-15 14:35:28 +04:00
if ( p - > notify . flags )
return is_monitoring_event_flags (
p - > notify . flags , notify_type , notify_field ) ;
2001-03-11 03:32:10 +03:00
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < option - > count ; i + + ) {
/* Check match for notify_type */
if ( option - > ctr . type [ i ] . type ! = notify_type )
continue ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
/* Check match for field */
for ( j = 0 ; j < option - > ctr . type [ i ] . count ; j + + ) {
if ( option - > ctr . type [ i ] . fields [ j ] = = notify_field ) {
return True ;
}
}
}
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
DEBUG ( 10 , ( " %s is not monitoring 0x%02x/0x%02x \n " ,
( p - > printer_type = = PRINTER_HANDLE_IS_PRINTER ) ?
p - > dev . handlename : p - > dev . printerservername ,
notify_type , notify_field ) ) ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
return False ;
}
2000-09-26 14:15:12 +04:00
2002-07-15 14:35:28 +04:00
/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
static void notify_one_value ( struct spoolss_notify_msg * msg ,
SPOOL_NOTIFY_INFO_DATA * data ,
TALLOC_CTX * mem_ctx )
{
data - > notify_data . value [ 0 ] = msg - > notify . value [ 0 ] ;
data - > notify_data . value [ 1 ] = 0 ;
2002-03-15 11:14:10 +03:00
}
2002-07-15 14:35:28 +04:00
static void notify_string ( struct spoolss_notify_msg * msg ,
SPOOL_NOTIFY_INFO_DATA * data ,
TALLOC_CTX * mem_ctx )
2002-03-15 11:14:10 +03:00
{
2002-07-15 14:35:28 +04:00
UNISTR2 unistr ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
/* The length of the message includes the trailing \0 */
2002-04-11 05:50:18 +04:00
2002-07-15 14:35:28 +04:00
init_unistr2 ( & unistr , msg - > notify . data , msg - > len ) ;
data - > notify_data . data . length = msg - > len * 2 ;
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , msg - > len * 2 ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
2002-03-15 11:14:10 +03:00
}
2002-07-15 14:35:28 +04:00
memcpy ( data - > notify_data . data . string , unistr . buffer , msg - > len * 2 ) ;
2002-03-15 11:14:10 +03:00
}
2000-10-02 23:28:26 +04:00
2002-07-15 14:35:28 +04:00
static void notify_system_time ( struct spoolss_notify_msg * msg ,
SPOOL_NOTIFY_INFO_DATA * data ,
TALLOC_CTX * mem_ctx )
{
SYSTEMTIME systime ;
prs_struct ps ;
if ( msg - > len ! = sizeof ( time_t ) ) {
DEBUG ( 5 , ( " notify_system_time: received wrong sized message (%d) \n " ,
msg - > len ) ) ;
return ;
}
if ( ! prs_init ( & ps , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ) {
DEBUG ( 5 , ( " notify_system_time: prs_init() failed \n " ) ) ;
return ;
}
if ( ! make_systemtime ( & systime , localtime ( ( time_t * ) msg - > notify . data ) ) ) {
DEBUG ( 5 , ( " notify_system_time: unable to make systemtime \n " ) ) ;
return ;
}
if ( ! spoolss_io_system_time ( " " , & ps , 0 , & systime ) )
return ;
data - > notify_data . data . length = prs_offset ( & ps ) ;
data - > notify_data . data . string =
talloc ( mem_ctx , prs_offset ( & ps ) ) ;
memcpy ( data - > notify_data . data . string , prs_data_p ( & ps ) , prs_offset ( & ps ) ) ;
prs_mem_free ( & ps ) ;
}
struct notify2_message_table {
char * name ;
void ( * fn ) ( struct spoolss_notify_msg * msg ,
SPOOL_NOTIFY_INFO_DATA * data , TALLOC_CTX * mem_ctx ) ;
} ;
static struct notify2_message_table printer_notify_table [ ] = {
2002-08-17 19:34:15 +04:00
/* 0x00 */ { " PRINTER_NOTIFY_SERVER_NAME " , notify_string } ,
/* 0x01 */ { " PRINTER_NOTIFY_PRINTER_NAME " , notify_string } ,
/* 0x02 */ { " PRINTER_NOTIFY_SHARE_NAME " , notify_string } ,
/* 0x03 */ { " PRINTER_NOTIFY_PORT_NAME " , notify_string } ,
/* 0x04 */ { " PRINTER_NOTIFY_DRIVER_NAME " , notify_string } ,
/* 0x05 */ { " PRINTER_NOTIFY_COMMENT " , notify_string } ,
/* 0x06 */ { " PRINTER_NOTIFY_LOCATION " , notify_string } ,
2002-07-15 14:35:28 +04:00
/* 0x07 */ { " PRINTER_NOTIFY_DEVMODE " , NULL } ,
2002-08-17 19:34:15 +04:00
/* 0x08 */ { " PRINTER_NOTIFY_SEPFILE " , notify_string } ,
/* 0x09 */ { " PRINTER_NOTIFY_PRINT_PROCESSOR " , notify_string } ,
2002-07-15 14:35:28 +04:00
/* 0x0a */ { " PRINTER_NOTIFY_PARAMETERS " , NULL } ,
2002-08-17 19:34:15 +04:00
/* 0x0b */ { " PRINTER_NOTIFY_DATATYPE " , notify_string } ,
2002-07-15 14:35:28 +04:00
/* 0x0c */ { " PRINTER_NOTIFY_SECURITY_DESCRIPTOR " , NULL } ,
2002-08-17 19:34:15 +04:00
/* 0x0d */ { " PRINTER_NOTIFY_ATTRIBUTES " , notify_one_value } ,
/* 0x0e */ { " PRINTER_NOTIFY_PRIORITY " , notify_one_value } ,
2002-07-15 14:35:28 +04:00
/* 0x0f */ { " PRINTER_NOTIFY_DEFAULT_PRIORITY " , NULL } ,
/* 0x10 */ { " PRINTER_NOTIFY_START_TIME " , NULL } ,
/* 0x11 */ { " PRINTER_NOTIFY_UNTIL_TIME " , NULL } ,
/* 0x12 */ { " PRINTER_NOTIFY_STATUS " , notify_one_value } ,
} ;
static struct notify2_message_table job_notify_table [ ] = {
/* 0x00 */ { " JOB_NOTIFY_PRINTER_NAME " , NULL } ,
/* 0x01 */ { " JOB_NOTIFY_MACHINE_NAME " , NULL } ,
/* 0x02 */ { " JOB_NOTIFY_PORT_NAME " , NULL } ,
/* 0x03 */ { " JOB_NOTIFY_USER_NAME " , notify_string } ,
/* 0x04 */ { " JOB_NOTIFY_NOTIFY_NAME " , NULL } ,
/* 0x05 */ { " JOB_NOTIFY_DATATYPE " , NULL } ,
/* 0x06 */ { " JOB_NOTIFY_PRINT_PROCESSOR " , NULL } ,
/* 0x07 */ { " JOB_NOTIFY_PARAMETERS " , NULL } ,
/* 0x08 */ { " JOB_NOTIFY_DRIVER_NAME " , NULL } ,
/* 0x09 */ { " JOB_NOTIFY_DEVMODE " , NULL } ,
/* 0x0a */ { " JOB_NOTIFY_STATUS " , notify_one_value } ,
/* 0x0b */ { " JOB_NOTIFY_STATUS_STRING " , NULL } ,
/* 0x0c */ { " JOB_NOTIFY_SECURITY_DESCRIPTOR " , NULL } ,
/* 0x0d */ { " JOB_NOTIFY_DOCUMENT " , notify_string } ,
/* 0x0e */ { " JOB_NOTIFY_PRIORITY " , NULL } ,
/* 0x0f */ { " JOB_NOTIFY_POSITION " , NULL } ,
/* 0x10 */ { " JOB_NOTIFY_SUBMITTED " , notify_system_time } ,
/* 0x11 */ { " JOB_NOTIFY_START_TIME " , NULL } ,
/* 0x12 */ { " JOB_NOTIFY_UNTIL_TIME " , NULL } ,
/* 0x13 */ { " JOB_NOTIFY_TIME " , NULL } ,
/* 0x14 */ { " JOB_NOTIFY_TOTAL_PAGES " , notify_one_value } ,
/* 0x15 */ { " JOB_NOTIFY_PAGES_PRINTED " , NULL } ,
/* 0x16 */ { " JOB_NOTIFY_TOTAL_BYTES " , notify_one_value } ,
/* 0x17 */ { " JOB_NOTIFY_BYTES_PRINTED " , NULL } ,
} ;
2000-09-26 01:05:18 +04:00
2002-09-25 19:19:00 +04:00
/***********************************************************************
Allocate talloc context for container object
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void notify_msg_ctr_init ( SPOOLSS_NOTIFY_MSG_CTR * ctr )
{
if ( ! ctr )
return ;
ctr - > ctx = talloc_init ( ) ;
return ;
}
/***********************************************************************
release all allocated memory and zero out structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void notify_msg_ctr_destroy ( SPOOLSS_NOTIFY_MSG_CTR * ctr )
{
if ( ! ctr )
return ;
if ( ctr - > ctx )
talloc_destroy ( ctr - > ctx ) ;
ZERO_STRUCTP ( ctr ) ;
return ;
}
/***********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static TALLOC_CTX * notify_ctr_getctx ( SPOOLSS_NOTIFY_MSG_CTR * ctr )
{
if ( ! ctr )
return NULL ;
return ctr - > ctx ;
}
/***********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static SPOOLSS_NOTIFY_MSG_GROUP * notify_ctr_getgroup ( SPOOLSS_NOTIFY_MSG_CTR * ctr , uint32 idx )
{
if ( ! ctr | | ! ctr - > msg_groups )
return NULL ;
if ( idx > = ctr - > num_groups )
return NULL ;
return & ctr - > msg_groups [ idx ] ;
}
/***********************************************************************
How many groups of change messages do we have ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int notify_msg_ctr_numgroups ( SPOOLSS_NOTIFY_MSG_CTR * ctr )
{
if ( ! ctr )
return 0 ;
return ctr - > num_groups ;
}
/***********************************************************************
Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int notify_msg_ctr_addmsg ( SPOOLSS_NOTIFY_MSG_CTR * ctr , SPOOLSS_NOTIFY_MSG * msg )
{
SPOOLSS_NOTIFY_MSG_GROUP * groups = NULL ;
SPOOLSS_NOTIFY_MSG_GROUP * msg_grp = NULL ;
SPOOLSS_NOTIFY_MSG * msg_list = NULL ;
int i , new_slot ;
if ( ! ctr | | ! msg )
return 0 ;
/* loop over all groups looking for a matching printer name */
for ( i = 0 ; i < ctr - > num_groups ; i + + ) {
if ( strcmp ( ctr - > msg_groups [ i ] . printername , msg - > printer ) = = 0 )
break ;
}
/* add a new group? */
if ( i = = ctr - > num_groups )
{
ctr - > num_groups + + ;
if ( ! ( groups = talloc_realloc ( ctr - > ctx , ctr - > msg_groups , sizeof ( SPOOLSS_NOTIFY_MSG_GROUP ) * ctr - > num_groups ) ) ) {
DEBUG ( 0 , ( " notify_msg_ctr_addmsg: talloc_realloc() failed! \n " ) ) ;
return 0 ;
}
ctr - > msg_groups = groups ;
/* clear the new entry and set the printer name */
ZERO_STRUCT ( ctr - > msg_groups [ ctr - > num_groups - 1 ] ) ;
fstrcpy ( ctr - > msg_groups [ ctr - > num_groups - 1 ] . printername , msg - > printer ) ;
}
/* add the change messages; 'i' is the correct index now regardless */
msg_grp = & ctr - > msg_groups [ i ] ;
msg_grp - > num_msgs + + ;
if ( ! ( msg_list = talloc_realloc ( ctr - > ctx , msg_grp - > msgs , sizeof ( SPOOLSS_NOTIFY_MSG ) * msg_grp - > num_msgs ) ) ) {
DEBUG ( 0 , ( " notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]! \n " , msg_grp - > num_msgs ) ) ;
return 0 ;
}
msg_grp - > msgs = msg_list ;
new_slot = msg_grp - > num_msgs - 1 ;
memcpy ( & msg_grp - > msgs [ new_slot ] , msg , sizeof ( SPOOLSS_NOTIFY_MSG ) ) ;
/* need to allocate own copy of data */
if ( msg - > len ! = 0 )
msg_grp - > msgs [ new_slot ] . notify . data = talloc_memdup ( ctr - > ctx , msg - > notify . data , msg - > len ) ;
return ctr - > num_groups ;
}
2002-03-15 11:14:10 +03:00
/***********************************************************************
Send a change notication message on all handles which have a call
back registered
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
static void send_notify2_changes ( SPOOLSS_NOTIFY_MSG_CTR * ctr , uint32 idx )
2002-03-15 11:14:10 +03:00
{
2002-09-25 19:19:00 +04:00
Printer_entry * p ;
TALLOC_CTX * mem_ctx = notify_ctr_getctx ( ctr ) ;
SPOOLSS_NOTIFY_MSG_GROUP * msg_group = notify_ctr_getgroup ( ctr , idx ) ;
SPOOLSS_NOTIFY_MSG * messages ;
if ( ! msg_group ) {
DEBUG ( 5 , ( " send_notify2_changes() called with no msg group! \n " ) ) ;
return ;
}
messages = msg_group - > msgs ;
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
if ( ! messages ) {
DEBUG ( 5 , ( " send_notify2_changes() called with no messages! \n " ) ) ;
return ;
}
DEBUG ( 8 , ( " send_notify2_changes: Enter...[%s] \n " , msg_group - > printername ) ) ;
/* loop over all printers */
for ( p = printers_list ; p ; p = p - > next )
{
2002-07-15 14:35:28 +04:00
SPOOL_NOTIFY_INFO_DATA * data ;
2002-09-25 19:19:00 +04:00
uint32 data_len = 0 ;
uint32 id ;
int i ;
2000-09-26 01:05:18 +04:00
2002-07-15 14:35:28 +04:00
/* Is there notification on this handle? */
2000-09-26 01:05:18 +04:00
2002-09-25 19:19:00 +04:00
if ( ! p - > notify . client_connected )
2002-07-15 14:35:28 +04:00
continue ;
2001-03-11 03:32:10 +03:00
2002-08-17 19:34:15 +04:00
DEBUG ( 10 , ( " Client connected! [%s] \n " , p - > dev . handlename ) ) ;
2002-07-15 14:35:28 +04:00
/* For this printer? Print servers always receive
notifications . */
2002-03-15 11:14:10 +03:00
2002-08-17 19:34:15 +04:00
if ( ( p - > printer_type = = PRINTER_HANDLE_IS_PRINTER ) & &
2002-09-25 19:19:00 +04:00
( ! strequal ( msg_group - > printername , p - > dev . handlename ) ) )
2002-07-15 14:35:28 +04:00
continue ;
2002-02-26 06:12:09 +03:00
2002-08-17 19:34:15 +04:00
DEBUG ( 10 , ( " Our printer \n " ) ) ;
2002-09-25 19:19:00 +04:00
/* allocate the max entries possible */
data = talloc ( mem_ctx , msg_group - > num_msgs * sizeof ( SPOOL_NOTIFY_INFO_DATA ) ) ;
ZERO_STRUCTP ( data ) ;
/* build the array of change notifications */
for ( i = 0 ; i < msg_group - > num_msgs ; i + + )
{
SPOOLSS_NOTIFY_MSG * msg = & messages [ i ] ;
2002-07-15 14:35:28 +04:00
/* Are we monitoring this event? */
if ( ! is_monitoring_event ( p , msg - > type , msg - > field ) )
continue ;
2002-03-15 11:14:10 +03:00
2002-09-25 19:19:00 +04:00
2002-08-17 19:34:15 +04:00
DEBUG ( 10 , ( " process_notify2_message: Sending message type [%x] field [%x] for printer [%s] \n " ,
msg - > type , msg - > field , p - > dev . handlename ) ) ;
/*
* if the is a printer notification handle and not a job notification
* type , then set the id to 0. Other wise just use what was specified
* in the message .
*
* When registering change notification on a print server handle
* we always need to send back the id ( snum ) matching the printer
* for which the change took place . For change notify registered
* on a printer handle , this does not matter and the id should be 0.
*
* - - jerry
*/
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
if ( ( p - > printer_type = = PRINTER_HANDLE_IS_PRINTER ) & & ( msg - > type = = PRINTER_NOTIFY_TYPE ) )
id = 0 ;
else
2002-07-15 14:35:28 +04:00
id = msg - > id ;
2002-08-17 19:34:15 +04:00
/* Convert unix jobid to smb jobid */
2002-09-25 19:19:00 +04:00
if ( msg - > flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID )
{
2002-07-15 14:35:28 +04:00
id = sysjob_to_jobid ( msg - > id ) ;
if ( id = = - 1 ) {
DEBUG ( 3 , ( " no such unix jobid %d \n " , msg - > id ) ) ;
goto done ;
2002-03-15 11:14:10 +03:00
}
2002-07-15 14:35:28 +04:00
}
2002-03-15 11:14:10 +03:00
2002-09-25 19:19:00 +04:00
construct_info_data ( & data [ data_len ] , msg - > type , msg - > field , id ) ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
switch ( msg - > type ) {
case PRINTER_NOTIFY_TYPE :
2002-08-17 19:34:15 +04:00
if ( ! printer_notify_table [ msg - > field ] . fn )
2002-07-15 14:35:28 +04:00
goto done ;
2002-09-25 19:19:00 +04:00
printer_notify_table [ msg - > field ] . fn ( msg , & data [ data_len ] , mem_ctx ) ;
2002-08-17 19:34:15 +04:00
2002-07-15 14:35:28 +04:00
break ;
2002-08-17 19:34:15 +04:00
2002-07-15 14:35:28 +04:00
case JOB_NOTIFY_TYPE :
2002-08-17 19:34:15 +04:00
if ( ! job_notify_table [ msg - > field ] . fn )
2002-07-15 14:35:28 +04:00
goto done ;
2002-09-25 19:19:00 +04:00
job_notify_table [ msg - > field ] . fn ( msg , & data [ data_len ] , mem_ctx ) ;
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
break ;
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
default :
DEBUG ( 5 , ( " Unknown notification type %d \n " , msg - > type ) ) ;
2002-07-15 14:35:28 +04:00
goto done ;
2002-03-15 11:14:10 +03:00
}
2002-09-25 19:19:00 +04:00
data_len + + ;
}
2002-08-17 19:34:15 +04:00
cli_spoolss_rrpcn ( & notify_cli , mem_ctx , & p - > notify . client_hnd ,
data_len , data , p - > notify . change , 0 ) ;
2000-09-26 01:05:18 +04:00
}
2002-09-25 19:19:00 +04:00
2002-07-15 14:35:28 +04:00
done :
2002-09-25 19:19:00 +04:00
DEBUG ( 8 , ( " send_notify2_changes: Exit... \n " ) ) ;
2002-03-15 11:14:10 +03:00
return ;
}
2002-09-25 19:19:00 +04:00
/***********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
static BOOL notify2_unpack_msg ( SPOOLSS_NOTIFY_MSG * msg , void * buf , size_t len )
2002-03-15 11:14:10 +03:00
{
2002-09-25 19:19:00 +04:00
2002-07-15 14:35:28 +04:00
int offset = 0 ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
/* Unpack message */
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
offset + = tdb_unpack ( ( char * ) buf + offset , len - offset , " f " ,
2002-09-25 19:19:00 +04:00
msg - > printer ) ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
offset + = tdb_unpack ( ( char * ) buf + offset , len - offset , " ddddd " ,
2002-09-25 19:19:00 +04:00
& msg - > type , & msg - > field , & msg - > id , & msg - > len , & msg - > flags ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( msg - > len = = 0 )
2002-07-15 14:35:28 +04:00
tdb_unpack ( ( char * ) buf + offset , len - offset , " dd " ,
2002-09-25 19:19:00 +04:00
& msg - > notify . value [ 0 ] , & msg - > notify . value [ 1 ] ) ;
2002-07-15 14:35:28 +04:00
else
tdb_unpack ( ( char * ) buf + offset , len - offset , " B " ,
2002-09-25 19:19:00 +04:00
& msg - > len , & msg - > notify . data ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
DEBUG ( 3 , ( " notify2_unpack_msg: got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x \n " ,
msg - > type , msg - > field , msg - > flags ) ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( msg - > len = = 0 )
DEBUG ( 3 , ( " notify2_unpack_msg: value1 = %d, value2 = %d \n " , msg - > notify . value [ 0 ] ,
msg - > notify . value [ 1 ] ) ) ;
2002-07-15 14:35:28 +04:00
else
2002-09-25 19:19:00 +04:00
dump_data ( 3 , msg - > notify . data , msg - > len ) ;
return True ;
}
/********************************************************************
Receive a notify2 message list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void receive_notify2_message_list ( int msg_type , pid_t src , void * msg , size_t len )
{
size_t msg_count , i ;
char * buf = ( char * ) msg ;
char * msg_ptr ;
size_t msg_len ;
SPOOLSS_NOTIFY_MSG notify ;
SPOOLSS_NOTIFY_MSG_CTR messages ;
int num_groups ;
if ( len < 4 ) {
DEBUG ( 0 , ( " receive_notify2_message_list: bad message format (len < 4)! \n " ) ) ;
return ;
}
msg_count = IVAL ( buf , 0 ) ;
msg_ptr = buf + 4 ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
DEBUG ( 5 , ( " receive_notify2_message_list: got %d messages in list \n " , msg_count ) ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( msg_count = = 0 ) {
DEBUG ( 0 , ( " receive_notify2_message_list: bad message format (msg_count == 0) ! \n " ) ) ;
return ;
}
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
/* initialize the container */
ZERO_STRUCT ( messages ) ;
notify_msg_ctr_init ( & messages ) ;
/*
* build message groups for each printer identified
* in a change_notify msg . Remember that a PCN message
* includes the handle returned for the srv_spoolss_replyopenprinter ( )
* call . Therefore messages are grouped according to printer handle .
*/
for ( i = 0 ; i < msg_count ; i + + )
{
if ( msg_ptr + 4 - buf > len ) {
DEBUG ( 0 , ( " receive_notify2_message_list: bad message format (len > buf_size) ! \n " ) ) ;
return ;
}
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
msg_len = IVAL ( msg_ptr , 0 ) ;
msg_ptr + = 4 ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( msg_ptr + msg_len - buf > len ) {
DEBUG ( 0 , ( " receive_notify2_message_list: bad message format (bad len) ! \n " ) ) ;
return ;
}
/* unpack messages */
ZERO_STRUCT ( notify ) ;
notify2_unpack_msg ( & notify , msg_ptr , msg_len ) ;
msg_ptr + = msg_len ;
/* add to correct list in container */
notify_msg_ctr_addmsg ( & messages , & notify ) ;
/* free memory that might have been allocated by notify2_unpack_msg() */
if ( notify . len ! = 0 )
SAFE_FREE ( notify . notify . data ) ;
}
/* process each group of messages */
num_groups = notify_msg_ctr_numgroups ( & messages ) ;
for ( i = 0 ; i < num_groups ; i + + )
send_notify2_changes ( & messages , i ) ;
/* cleanup */
DEBUG ( 10 , ( " receive_notify2_message_list: processed %u messages \n " , ( uint32 ) msg_count ) ) ;
notify_msg_ctr_destroy ( & messages ) ;
return ;
2002-03-15 11:14:10 +03:00
}
2002-07-15 14:35:28 +04:00
/********************************************************************
Send a message to ourself about new driver being installed
so we can upgrade the information for each printer bound to this
driver
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL srv_spoolss_drv_upgrade_printer ( char * drivername )
{
int len = strlen ( drivername ) ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
if ( ! len )
return False ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
DEBUG ( 10 , ( " srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s] \n " ,
drivername ) ) ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
message_send_pid ( sys_getpid ( ) , MSG_PRINTER_DRVUPGRADE , drivername , len + 1 , False ) ;
2000-09-26 04:54:18 +04:00
return True ;
2002-07-15 14:35:28 +04:00
}
/**********************************************************************
callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
over all printers , upgrading ones as neessary
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void do_drv_upgrade_printer ( int msg_type , pid_t src , void * buf , size_t len )
{
fstring drivername ;
int snum ;
int n_services = lp_numservices ( ) ;
len = MIN ( len , sizeof ( drivername ) - 1 ) ;
strncpy ( drivername , buf , len ) ;
DEBUG ( 10 , ( " do_drv_upgrade_printer: Got message for new driver [%s] \n " , drivername ) ) ;
/* Iterate the printer list */
for ( snum = 0 ; snum < n_services ; snum + + )
{
if ( lp_snum_ok ( snum ) & & lp_print_ok ( snum ) )
{
WERROR result ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
result = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( result ) )
continue ;
if ( printer & & printer - > info_2 & & ! strcmp ( drivername , printer - > info_2 - > drivername ) )
{
DEBUG ( 6 , ( " Updating printer [%s] \n " , printer - > info_2 - > printername ) ) ;
/* all we care about currently is the change_id */
result = mod_a_printer ( * printer , 2 ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 3 , ( " do_drv_upgrade_printer: mod_a_printer() failed with status [%s] \n " ,
dos_errstr ( result ) ) ) ;
}
}
free_a_printer ( & printer , 2 ) ;
}
}
/* all done */
}
2000-09-26 01:05:18 +04:00
2002-08-17 19:34:15 +04:00
/********************************************************************
Send a message to ourself about new driver being installed
so we can upgrade the information for each printer bound to this
driver
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL srv_spoolss_reset_printerdata ( char * drivername )
{
int len = strlen ( drivername ) ;
if ( ! len )
return False ;
DEBUG ( 10 , ( " srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s] \n " ,
drivername ) ) ;
message_send_pid ( sys_getpid ( ) , MSG_PRINTERDATA_INIT_RESET , drivername , len + 1 , False ) ;
return True ;
}
/**********************************************************************
callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
over all printers , resetting printer data as neessary
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void reset_all_printerdata ( int msg_type , pid_t src , void * buf , size_t len )
{
fstring drivername ;
int snum ;
int n_services = lp_numservices ( ) ;
len = MIN ( len , sizeof ( drivername ) - 1 ) ;
strncpy ( drivername , buf , len ) ;
DEBUG ( 10 , ( " reset_all_printerdata: Got message for new driver [%s] \n " , drivername ) ) ;
/* Iterate the printer list */
for ( snum = 0 ; snum < n_services ; snum + + )
{
if ( lp_snum_ok ( snum ) & & lp_print_ok ( snum ) )
{
WERROR result ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
result = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( result ) )
continue ;
/*
* if the printer is bound to the driver ,
* then reset to the new driver initdata
*/
if ( printer & & printer - > info_2 & & ! strcmp ( drivername , printer - > info_2 - > drivername ) )
{
DEBUG ( 6 , ( " reset_all_printerdata: Updating printer [%s] \n " , printer - > info_2 - > printername ) ) ;
if ( ! set_driver_init ( printer , 2 ) ) {
DEBUG ( 5 , ( " reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]! \n " ,
printer - > info_2 - > printername , printer - > info_2 - > drivername ) ) ;
}
}
free_a_printer ( & printer , 2 ) ;
}
}
/* all done */
return ;
}
2002-03-26 06:15:30 +03:00
/********************************************************************
Copy routines used by convert_to_openprinterex ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static DEVICEMODE * dup_devicemode ( TALLOC_CTX * ctx , DEVICEMODE * devmode )
{
DEVICEMODE * d ;
int len ;
if ( ! devmode )
return NULL ;
DEBUG ( 8 , ( " dup_devmode \n " ) ) ;
/* bulk copy first */
d = talloc_memdup ( ctx , devmode , sizeof ( DEVICEMODE ) ) ;
if ( ! d )
return NULL ;
/* dup the pointer members separately */
len = unistrlen ( devmode - > devicename . buffer ) ;
if ( len ! = - 1 ) {
d - > devicename . buffer = talloc ( ctx , len * 2 ) ;
if ( unistrcpy ( d - > devicename . buffer , devmode - > devicename . buffer ) ! = len )
return NULL ;
}
len = unistrlen ( devmode - > formname . buffer ) ;
if ( len ! = - 1 ) {
d - > devicename . buffer = talloc ( ctx , len * 2 ) ;
if ( unistrcpy ( d - > formname . buffer , devmode - > formname . buffer ) ! = len )
return NULL ;
}
d - > private = talloc_memdup ( ctx , devmode - > private , devmode - > driverextra ) ;
return d ;
}
static void copy_devmode_ctr ( TALLOC_CTX * ctx , DEVMODE_CTR * new_ctr , DEVMODE_CTR * ctr )
{
if ( ! new_ctr | | ! ctr )
return ;
DEBUG ( 8 , ( " copy_devmode_ctr \n " ) ) ;
new_ctr - > size = ctr - > size ;
new_ctr - > devmode_ptr = ctr - > devmode_ptr ;
if ( ctr - > devmode_ptr )
new_ctr - > devmode = dup_devicemode ( ctx , ctr - > devmode ) ;
}
static void copy_printer_default ( TALLOC_CTX * ctx , PRINTER_DEFAULT * new_def , PRINTER_DEFAULT * def )
{
if ( ! new_def | | ! def )
return ;
DEBUG ( 8 , ( " copy_printer_defaults \n " ) ) ;
new_def - > datatype_ptr = def - > datatype_ptr ;
if ( def - > datatype_ptr )
copy_unistr2 ( & new_def - > datatype , & def - > datatype ) ;
copy_devmode_ctr ( ctx , & new_def - > devmode_cont , & def - > devmode_cont ) ;
new_def - > access_required = def - > access_required ;
}
/********************************************************************
* Convert a SPOOL_Q_OPEN_PRINTER structure to a
* SPOOL_Q_OPEN_PRINTER_EX structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void convert_to_openprinterex ( TALLOC_CTX * ctx , SPOOL_Q_OPEN_PRINTER_EX * q_u_ex , SPOOL_Q_OPEN_PRINTER * q_u )
{
if ( ! q_u_ex | | ! q_u )
return ;
DEBUG ( 8 , ( " convert_to_openprinterex \n " ) ) ;
q_u_ex - > printername_ptr = q_u - > printername_ptr ;
if ( q_u - > printername_ptr )
copy_unistr2 ( & q_u_ex - > printername , & q_u - > printername ) ;
copy_printer_default ( ctx , & q_u_ex - > printer_default , & q_u - > printer_default ) ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* spoolss_open_printer
*
* called from the spoolss dispatcher
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2002-03-26 06:15:30 +03:00
WERROR _spoolss_open_printer ( pipes_struct * p , SPOOL_Q_OPEN_PRINTER * q_u , SPOOL_R_OPEN_PRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2002-03-26 06:15:30 +03:00
SPOOL_Q_OPEN_PRINTER_EX q_u_ex ;
SPOOL_R_OPEN_PRINTER_EX r_u_ex ;
if ( ! q_u | | ! r_u )
return WERR_NOMEM ;
ZERO_STRUCT ( q_u_ex ) ;
ZERO_STRUCT ( r_u_ex ) ;
/* convert the OpenPrinter() call to OpenPrinterEx() */
convert_to_openprinterex ( p - > mem_ctx , & q_u_ex , q_u ) ;
r_u_ex . status = _spoolss_open_printer_ex ( p , & q_u_ex , & r_u_ex ) ;
/* convert back to OpenPrinter() */
memcpy ( r_u , & r_u_ex , sizeof ( * r_u ) ) ;
return r_u - > status ;
}
/********************************************************************
* spoolss_open_printer
*
2002-09-25 19:19:00 +04:00
* If the openprinterex rpc call contains a devmode ,
* it ' s a per - user one . This per - user devmode is derivated
* from the global devmode . Openprinterex ( ) contains a per - user
* devmode for when you do EMF printing and spooling .
* In the EMF case , the NT workstation is only doing half the job
* of rendering the page . The other half is done by running the printer
* driver on the server .
* The EMF file doesn ' t contain the page description ( paper size , orientation , . . . ) .
* The EMF file only contains what is to be printed on the page .
* So in order for the server to know how to print , the NT client sends
* a devicemode attached to the openprinterex call .
* But this devicemode is short lived , it ' s only valid for the current print job .
*
* If Samba would have supported EMF spooling , this devicemode would
* have been attached to the handle , to sent it to the driver to correctly
* rasterize the EMF file .
*
* As Samba only supports RAW spooling , we only receive a ready - to - print file ,
* we just act as a pass - thru between windows and the printer .
*
* In order to know that Samba supports only RAW spooling , NT has to call
* getprinter ( ) at level 2 ( attribute field ) or NT has to call startdoc ( )
* and until NT sends a RAW job , we refuse it .
*
* But to call getprinter ( ) or startdoc ( ) , you first need a valid handle ,
* and to get an handle you have to call openprintex ( ) . Hence why you have
* a devicemode in the openprinterex ( ) call .
*
*
* Differences between NT4 and NT 2000.
* NT4 :
* - - -
* On NT4 , you only have a global devicemode . This global devicemode can be changed
* by the administrator ( or by a user with enough privs ) . Everytime a user
* wants to print , the devicemode is resetted to the default . In Word , everytime
* you print , the printer ' s characteristics are always reset to the global devicemode .
*
* NT 2000 :
* - - - - - - -
* In W2K , there is the notion of per - user devicemode . The first time you use
* a printer , a per - user devicemode is build from the global devicemode .
* If you change your per - user devicemode , it is saved in the registry , under the
* H_KEY_CURRENT_KEY sub_tree . So that everytime you print , you have your default
* printer preferences available .
*
* To change the per - user devicemode : it ' s the " Printing Preferences ... " button
* on the General Tab of the printer properties windows .
*
* To change the global devicemode : it ' s the " Printing Defaults... " button
* on the Advanced Tab of the printer properties window .
*
* JFM .
2002-03-26 06:15:30 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2002-03-26 06:15:30 +03:00
WERROR _spoolss_open_printer_ex ( pipes_struct * p , SPOOL_Q_OPEN_PRINTER_EX * q_u , SPOOL_R_OPEN_PRINTER_EX * r_u )
{
2002-09-25 19:19:00 +04:00
UNISTR2 * printername = NULL ;
PRINTER_DEFAULT * printer_default = & q_u - > printer_default ;
POLICY_HND * handle = & r_u - > handle ;
2001-02-28 04:24:55 +03:00
2000-02-07 19:17:59 +03:00
fstring name ;
2001-01-25 23:15:32 +03:00
int snum ;
2001-01-31 21:34:49 +03:00
struct current_user user ;
2002-03-07 04:02:48 +03:00
Printer_entry * Printer = NULL ;
2001-02-28 04:24:55 +03:00
if ( q_u - > printername_ptr ! = 0 )
printername = & q_u - > printername ;
2001-01-31 21:34:49 +03:00
if ( printername = = NULL )
2001-09-04 11:13:01 +04:00
return WERR_INVALID_PRINTER_NAME ;
2000-02-07 19:17:59 +03:00
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
unistr2_to_ascii ( name , printername , sizeof ( name ) - 1 ) ;
DEBUGADD ( 3 , ( " checking name: %s \n " , name ) ) ;
2002-03-07 04:02:48 +03:00
if ( ! open_printer_hnd ( p , handle , name , 0 ) )
2001-09-04 11:13:01 +04:00
return WERR_INVALID_PRINTER_NAME ;
2000-02-07 19:17:59 +03:00
2002-03-07 04:02:48 +03:00
Printer = find_printer_index_by_hnd ( p , handle ) ;
if ( ! Printer ) {
DEBUG ( 0 , ( " _spoolss_open_printer_ex: logic error. \
2002-04-09 10:19:42 +04:00
Can ' t find printer handle we created for printer % s \ n " , name ));
2002-03-07 04:02:48 +03:00
close_printer_handle ( p , handle ) ;
return WERR_INVALID_PRINTER_NAME ;
}
2001-01-31 21:34:49 +03:00
get_current_user ( & user , p ) ;
2001-02-16 22:21:18 +03:00
2002-09-25 19:19:00 +04:00
/*
* First case : the user is opening the print server :
*
* Disallow MS AddPrinterWizard if parameter disables it . A Win2k
* client 1 st tries an OpenPrinterEx with access = = 0 , MUST be allowed .
*
* Then both Win2k and WinNT clients try an OpenPrinterEx with
* SERVER_ALL_ACCESS , which we allow only if the user is root ( uid = 0 )
* or if the user is listed in the smb . conf printer admin parameter .
*
* Then they try OpenPrinterEx with SERVER_READ which we allow . This lets the
* client view printer folder , but does not show the MSAPW .
*
* Note : this test needs code to check access rights here too . Jeremy
* could you look at this ?
*
* Second case : the user is opening a printer :
* NT doesn ' t let us connect to a printer if the connecting user
* doesn ' t have print permission .
*/
2002-04-15 07:49:53 +04:00
2002-09-25 19:19:00 +04:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTSERVER )
{
2002-04-15 07:49:53 +04:00
/* Printserver handles use global struct... */
snum = - 1 ;
2002-09-25 19:19:00 +04:00
/* Map standard access rights to object specific access rights */
2002-04-15 07:49:53 +04:00
se_map_standard ( & printer_default - > access_required ,
& printserver_std_mapping ) ;
/* Deny any object specific bits that don't apply to print
servers ( i . e printer and job specific bits ) */
printer_default - > access_required & = SPECIFIC_RIGHTS_MASK ;
if ( printer_default - > access_required &
~ ( SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE ) ) {
DEBUG ( 3 , ( " access DENIED for non-printserver bits " ) ) ;
close_printer_handle ( p , handle ) ;
return WERR_ACCESS_DENIED ;
2001-01-05 22:01:11 +03:00
}
2002-04-15 07:49:53 +04:00
/* Allow admin access */
2002-09-25 19:19:00 +04:00
if ( printer_default - > access_required & SERVER_ACCESS_ADMINISTER )
{
2001-02-04 02:45:59 +03:00
if ( ! lp_ms_add_printer_wizard ( ) ) {
2001-03-11 03:32:10 +03:00
close_printer_handle ( p , handle ) ;
2001-09-04 11:13:01 +04:00
return WERR_ACCESS_DENIED ;
2001-01-31 21:34:49 +03:00
}
2002-04-15 07:49:53 +04:00
2002-09-25 19:19:00 +04:00
/* if the user is not root and not a printer admin, then fail */
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( user . uid ! = 0
& & ! user_in_list ( uidtoname ( user . uid ) , lp_printer_admin ( snum ) ) )
{
close_printer_handle ( p , handle ) ;
return WERR_ACCESS_DENIED ;
}
printer_default - > access_required = SERVER_ACCESS_ADMINISTER ;
}
else
{
printer_default - > access_required = SERVER_ACCESS_ENUMERATE ;
2001-01-31 21:34:49 +03:00
}
2002-04-15 07:49:53 +04:00
2002-09-25 19:19:00 +04:00
DEBUG ( 4 , ( " Setting print server access = %s \n " , ( printer_default - > access_required = = SERVER_ACCESS_ADMINISTER )
? " SERVER_ACCESS_ADMINISTER " : " SERVER_ACCESS_ENUMERATE " ) ) ;
2002-04-15 07:49:53 +04:00
/* We fall through to return WERR_OK */
2001-02-16 22:21:18 +03:00
}
else
{
/* NT doesn't let us connect to a printer if the connecting user
doesn ' t have print permission . */
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2001-03-03 08:27:26 +03:00
2002-03-15 11:14:10 +03:00
se_map_standard ( & printer_default - > access_required , & printer_std_mapping ) ;
2001-02-04 02:45:59 +03:00
/* map an empty access mask to the minimum access mask */
if ( printer_default - > access_required = = 0x0 )
printer_default - > access_required = PRINTER_ACCESS_USE ;
2001-08-14 01:30:27 +04:00
/*
* If we are not serving the printer driver for this printer ,
* map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE . This
* will keep NT clients happy - - jerry
*/
if ( lp_use_client_driver ( snum )
& & ( printer_default - > access_required & PRINTER_ACCESS_ADMINISTER ) )
{
printer_default - > access_required = PRINTER_ACCESS_USE ;
}
2002-07-15 14:35:28 +04:00
/* check smb.conf parameters and the the sec_desc */
if ( ! user_ok ( uidtoname ( user . uid ) , snum ) | | ! print_access_check ( & user , snum , printer_default - > access_required ) ) {
2001-01-25 23:15:32 +03:00
DEBUG ( 3 , ( " access DENIED for printer open \n " ) ) ;
2001-03-11 03:32:10 +03:00
close_printer_handle ( p , handle ) ;
2001-09-04 11:13:01 +04:00
return WERR_ACCESS_DENIED ;
2001-01-25 23:15:32 +03:00
}
2001-01-30 00:34:08 +03:00
2002-04-11 06:59:31 +04:00
if ( ( printer_default - > access_required & SPECIFIC_RIGHTS_MASK ) & ~ ( PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE ) ) {
DEBUG ( 3 , ( " access DENIED for printer open - unknown bits \n " ) ) ;
close_printer_handle ( p , handle ) ;
return WERR_ACCESS_DENIED ;
}
2002-03-07 04:02:48 +03:00
if ( printer_default - > access_required & PRINTER_ACCESS_ADMINISTER )
printer_default - > access_required = PRINTER_ACCESS_ADMINISTER ;
else
printer_default - > access_required = PRINTER_ACCESS_USE ;
2002-09-25 19:19:00 +04:00
DEBUG ( 4 , ( " Setting printer access = %s \n " , ( printer_default - > access_required = = PRINTER_ACCESS_ADMINISTER )
? " PRINTER_ACCESS_ADMINISTER " : " PRINTER_ACCESS_USE " ) ) ;
2001-02-16 22:21:18 +03:00
2001-01-05 22:01:11 +03:00
}
2002-09-25 19:19:00 +04:00
Printer - > access_granted = printer_default - > access_required ;
/*
* If the client sent a devmode in the OpenPrinter ( ) call , then
* save it here in case we get a job submission on this handle
*/
if ( ( Printer - > printer_type ! = PRINTER_HANDLE_IS_PRINTSERVER )
& & q_u - > printer_default . devmode_cont . devmode_ptr )
{
convert_devicemode ( Printer - > dev . handlename , q_u - > printer_default . devmode_cont . devmode ,
& Printer - > nt_devmode ) ;
}
2001-01-05 22:01:11 +03:00
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-07 19:17:59 +03:00
static BOOL convert_printer_info ( const SPOOL_PRINTER_INFO_LEVEL * uni ,
2000-02-21 04:58:13 +03:00
NT_PRINTER_INFO_LEVEL * printer , uint32 level )
2000-02-07 19:17:59 +03:00
{
2001-11-30 06:45:21 +03:00
BOOL ret = True ;
2000-02-21 04:58:13 +03:00
switch ( level ) {
2000-11-18 02:10:56 +03:00
case 2 :
2001-11-30 06:45:21 +03:00
ret = uni_2_asc_printer_info_2 ( uni - > info_2 , & printer - > info_2 ) ;
2000-02-07 19:17:59 +03:00
break ;
default :
break ;
}
2001-11-30 06:45:21 +03:00
return ret ;
2000-02-07 19:17:59 +03:00
}
static BOOL convert_printer_driver_info ( const SPOOL_PRINTER_DRIVER_INFO_LEVEL * uni ,
2000-02-21 04:58:13 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL * printer , uint32 level )
2000-02-07 19:17:59 +03:00
{
2001-08-12 21:30:01 +04:00
BOOL result = True ;
2000-02-21 04:58:13 +03:00
switch ( level ) {
2000-11-18 02:10:56 +03:00
case 3 :
2000-02-07 19:17:59 +03:00
printer - > info_3 = NULL ;
2001-08-12 21:30:01 +04:00
if ( ! uni_2_asc_printer_driver_3 ( uni - > info_3 , & printer - > info_3 ) )
result = False ;
2000-05-12 18:28:46 +04:00
break ;
2000-11-18 02:10:56 +03:00
case 6 :
2000-05-12 18:28:46 +04:00
printer - > info_6 = NULL ;
2001-08-12 21:30:01 +04:00
if ( ! uni_2_asc_printer_driver_6 ( uni - > info_6 , & printer - > info_6 ) )
result = False ;
2000-02-07 19:17:59 +03:00
break ;
default :
break ;
}
2001-08-12 21:30:01 +04:00
return result ;
2000-02-07 19:17:59 +03:00
}
2001-01-30 00:34:08 +03:00
BOOL convert_devicemode ( char * printername , const DEVICEMODE * devmode ,
NT_DEVICEMODE * * pp_nt_devmode )
2000-06-01 06:35:30 +04:00
{
2001-01-30 00:34:08 +03:00
NT_DEVICEMODE * nt_devmode = * pp_nt_devmode ;
/*
* Ensure nt_devmode is a valid pointer
* as we will be overwriting it .
*/
2001-02-16 22:21:18 +03:00
if ( nt_devmode = = NULL ) {
DEBUG ( 5 , ( " convert_devicemode: allocating a generic devmode \n " ) ) ;
2001-01-30 00:34:08 +03:00
if ( ( nt_devmode = construct_nt_devicemode ( printername ) ) = = NULL )
return False ;
2001-02-16 22:21:18 +03:00
}
2001-01-30 00:34:08 +03:00
2001-07-04 11:15:53 +04:00
rpcstr_pull ( nt_devmode - > devicename , devmode - > devicename . buffer , 31 , - 1 , 0 ) ;
rpcstr_pull ( nt_devmode - > formname , devmode - > formname . buffer , 31 , - 1 , 0 ) ;
2000-06-01 06:35:30 +04:00
nt_devmode - > specversion = devmode - > specversion ;
nt_devmode - > driverversion = devmode - > driverversion ;
nt_devmode - > size = devmode - > size ;
nt_devmode - > fields = devmode - > fields ;
nt_devmode - > orientation = devmode - > orientation ;
nt_devmode - > papersize = devmode - > papersize ;
nt_devmode - > paperlength = devmode - > paperlength ;
nt_devmode - > paperwidth = devmode - > paperwidth ;
nt_devmode - > scale = devmode - > scale ;
nt_devmode - > copies = devmode - > copies ;
nt_devmode - > defaultsource = devmode - > defaultsource ;
nt_devmode - > printquality = devmode - > printquality ;
nt_devmode - > color = devmode - > color ;
nt_devmode - > duplex = devmode - > duplex ;
nt_devmode - > yresolution = devmode - > yresolution ;
nt_devmode - > ttoption = devmode - > ttoption ;
nt_devmode - > collate = devmode - > collate ;
nt_devmode - > logpixels = devmode - > logpixels ;
nt_devmode - > bitsperpel = devmode - > bitsperpel ;
nt_devmode - > pelswidth = devmode - > pelswidth ;
nt_devmode - > pelsheight = devmode - > pelsheight ;
nt_devmode - > displayflags = devmode - > displayflags ;
nt_devmode - > displayfrequency = devmode - > displayfrequency ;
nt_devmode - > icmmethod = devmode - > icmmethod ;
nt_devmode - > icmintent = devmode - > icmintent ;
nt_devmode - > mediatype = devmode - > mediatype ;
nt_devmode - > dithertype = devmode - > dithertype ;
nt_devmode - > reserved1 = devmode - > reserved1 ;
nt_devmode - > reserved2 = devmode - > reserved2 ;
nt_devmode - > panningwidth = devmode - > panningwidth ;
nt_devmode - > panningheight = devmode - > panningheight ;
2001-01-30 00:34:08 +03:00
/*
* Only change private and driverextra if the incoming devmode
* has a new one . JRA .
*/
if ( ( devmode - > driverextra ! = 0 ) & & ( devmode - > private ! = NULL ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( nt_devmode - > private ) ;
2001-01-30 00:34:08 +03:00
nt_devmode - > driverextra = devmode - > driverextra ;
2000-04-07 02:48:53 +04:00
if ( ( nt_devmode - > private = ( uint8 * ) malloc ( nt_devmode - > driverextra * sizeof ( uint8 ) ) ) = = NULL )
return False ;
2000-06-01 06:35:30 +04:00
memcpy ( nt_devmode - > private , devmode - > private , nt_devmode - > driverextra ) ;
2000-02-07 19:17:59 +03:00
}
2001-01-30 00:34:08 +03:00
* pp_nt_devmode = nt_devmode ;
2000-02-07 19:17:59 +03:00
return True ;
}
2001-02-28 05:38:09 +03:00
/********************************************************************
* _spoolss_enddocprinter_internal .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-04 11:13:01 +04:00
static WERROR _spoolss_enddocprinter_internal ( pipes_struct * p , POLICY_HND * handle )
2001-02-28 05:38:09 +03:00
{
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2002-08-17 19:34:15 +04:00
int snum ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2001-02-28 05:38:09 +03:00
}
2002-08-17 19:34:15 +04:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
2001-02-28 05:38:09 +03:00
Printer - > document_started = False ;
2002-08-17 19:34:15 +04:00
print_job_end ( snum , Printer - > jobid , True ) ;
2001-02-28 05:38:09 +03:00
/* error codes unhandled so far ... */
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2001-02-28 05:38:09 +03:00
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* api_spoolss_closeprinter
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_closeprinter ( pipes_struct * p , SPOOL_Q_CLOSEPRINTER * q_u , SPOOL_R_CLOSEPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 04:24:55 +03:00
POLICY_HND * handle = & q_u - > handle ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-09-22 01:44:15 +04:00
if ( Printer & & Printer - > document_started )
2001-03-11 03:32:10 +03:00
_spoolss_enddocprinter_internal ( p , handle ) ; /* print job was not closed */
2000-09-22 01:44:15 +04:00
2001-03-11 03:32:10 +03:00
if ( ! close_printer_handle ( p , handle ) )
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
2002-02-09 07:10:24 +03:00
/* clear the returned printer handle. Observed behavior
from Win2k server . Don ' t think this really matters .
Previous code just copied the value of the closed
handle . - - jerry */
memset ( & r_u - > handle , ' \0 ' , sizeof ( r_u - > handle ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-05-02 19:31:55 +04:00
/********************************************************************
* api_spoolss_deleteprinter
2001-02-28 04:24:55 +03:00
2000-05-02 19:31:55 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_deleteprinter ( pipes_struct * p , SPOOL_Q_DELETEPRINTER * q_u , SPOOL_R_DELETEPRINTER * r_u )
2000-05-02 19:31:55 +04:00
{
2001-02-28 04:24:55 +03:00
POLICY_HND * handle = & q_u - > handle ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2001-09-04 11:13:01 +04:00
WERROR result ;
2000-09-22 01:44:15 +04:00
if ( Printer & & Printer - > document_started )
2001-03-11 03:32:10 +03:00
_spoolss_enddocprinter_internal ( p , handle ) ; /* print job was not closed */
2000-09-22 01:44:15 +04:00
2001-02-28 04:24:55 +03:00
memcpy ( & r_u - > handle , & q_u - > handle , sizeof ( r_u - > handle ) ) ;
2001-03-11 03:32:10 +03:00
result = delete_printer_handle ( p , handle ) ;
2000-09-26 01:05:18 +04:00
2002-03-15 11:14:10 +03:00
update_c_setprinter ( False ) ;
2002-02-09 07:10:24 +03:00
2001-01-23 23:25:25 +03:00
return result ;
2000-05-02 19:31:55 +04:00
}
2001-05-18 08:11:17 +04:00
/*******************************************************************
* static function to lookup the version id corresponding to an
* long architecture string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-05-18 08:11:17 +04:00
static int get_version_id ( char * arch )
{
int i ;
struct table_node archi_table [ ] = {
{ " Windows 4.0 " , " WIN40 " , 0 } ,
{ " Windows NT x86 " , " W32X86 " , 2 } ,
{ " Windows NT R4000 " , " W32MIPS " , 2 } ,
{ " Windows NT Alpha_AXP " , " W32ALPHA " , 2 } ,
{ " Windows NT PowerPC " , " W32PPC " , 2 } ,
{ NULL , " " , - 1 }
} ;
for ( i = 0 ; archi_table [ i ] . long_archi ! = NULL ; i + + )
{
if ( strcmp ( arch , archi_table [ i ] . long_archi ) = = 0 )
return ( archi_table [ i ] . version ) ;
}
return - 1 ;
}
/********************************************************************
* _spoolss_deleteprinterdriver
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
WERROR _spoolss_deleteprinterdriver ( pipes_struct * p , SPOOL_Q_DELETEPRINTERDRIVER * q_u , SPOOL_R_DELETEPRINTERDRIVER * r_u )
2001-05-18 08:11:17 +04:00
{
fstring driver ;
fstring arch ;
NT_PRINTER_DRIVER_INFO_LEVEL info ;
2002-09-25 19:19:00 +04:00
NT_PRINTER_DRIVER_INFO_LEVEL info_win2k ;
2001-05-18 08:11:17 +04:00
int version ;
2002-07-15 14:35:28 +04:00
struct current_user user ;
2002-09-25 19:19:00 +04:00
WERROR status ;
WERROR status_win2k = WERR_ACCESS_DENIED ;
2002-07-15 14:35:28 +04:00
get_current_user ( & user , p ) ;
2001-05-18 08:11:17 +04:00
unistr2_to_ascii ( driver , & q_u - > driver , sizeof ( driver ) - 1 ) ;
unistr2_to_ascii ( arch , & q_u - > arch , sizeof ( arch ) - 1 ) ;
/* check that we have a valid driver name first */
2002-09-25 19:19:00 +04:00
if ( ( version = get_version_id ( arch ) ) = = - 1 )
2001-09-04 11:13:01 +04:00
return WERR_INVALID_ENVIRONMENT ;
2002-09-25 19:19:00 +04:00
ZERO_STRUCT ( info ) ;
ZERO_STRUCT ( info_win2k ) ;
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & info , 3 , driver , arch , version ) ) )
{
/* try for Win2k driver if "Windows NT x86" */
if ( version = = 2 ) {
version = 3 ;
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & info , 3 , driver , arch , version ) ) ) {
status = WERR_UNKNOWN_PRINTER_DRIVER ;
goto done ;
}
}
2001-05-18 08:11:17 +04:00
}
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( printer_driver_in_use ( info . info_3 ) ) {
status = WERR_PRINTER_DRIVER_IN_USE ;
goto done ;
}
2002-07-15 14:35:28 +04:00
if ( version = = 2 )
2002-09-25 19:19:00 +04:00
{
if ( W_ERROR_IS_OK ( get_a_printer_driver ( & info_win2k , 3 , driver , arch , 3 ) ) )
{
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
2001-05-18 08:11:17 +04:00
2002-09-25 19:19:00 +04:00
status_win2k = delete_printer_driver ( info_win2k . info_3 , & user , 3 , False ) ;
free_a_printer_driver ( info_win2k , 3 ) ;
/* this should not have failed---if it did, report to client */
if ( ! W_ERROR_IS_OK ( status_win2k ) )
goto done ;
}
}
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
status = delete_printer_driver ( info . info_3 , & user , version , False ) ;
/* if at least one of the deletes succeeded return OK */
2001-05-18 08:11:17 +04:00
2002-09-25 19:19:00 +04:00
if ( W_ERROR_IS_OK ( status ) | | W_ERROR_IS_OK ( status_win2k ) )
status = WERR_OK ;
done :
free_a_printer_driver ( info , 3 ) ;
2001-05-18 08:11:17 +04:00
2002-09-25 19:19:00 +04:00
return status ;
2002-07-15 14:35:28 +04:00
}
/********************************************************************
* spoolss_deleteprinterdriverex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_deleteprinterdriverex ( pipes_struct * p , SPOOL_Q_DELETEPRINTERDRIVEREX * q_u , SPOOL_R_DELETEPRINTERDRIVEREX * r_u )
{
fstring driver ;
fstring arch ;
NT_PRINTER_DRIVER_INFO_LEVEL info ;
2002-09-25 19:19:00 +04:00
NT_PRINTER_DRIVER_INFO_LEVEL info_win2k ;
2002-07-15 14:35:28 +04:00
int version ;
uint32 flags = q_u - > delete_flags ;
BOOL delete_files ;
struct current_user user ;
2002-09-25 19:19:00 +04:00
WERROR status ;
WERROR status_win2k = WERR_ACCESS_DENIED ;
2002-07-15 14:35:28 +04:00
get_current_user ( & user , p ) ;
unistr2_to_ascii ( driver , & q_u - > driver , sizeof ( driver ) - 1 ) ;
unistr2_to_ascii ( arch , & q_u - > arch , sizeof ( arch ) - 1 ) ;
/* check that we have a valid driver name first */
if ( ( version = get_version_id ( arch ) ) = = - 1 ) {
/* this is what NT returns */
return WERR_INVALID_ENVIRONMENT ;
}
if ( flags & DPD_DELETE_SPECIFIC_VERSION )
version = q_u - > version ;
ZERO_STRUCT ( info ) ;
2002-09-25 19:19:00 +04:00
ZERO_STRUCT ( info_win2k ) ;
status = get_a_printer_driver ( & info , 3 , driver , arch , version ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( ! W_ERROR_IS_OK ( status ) )
{
/*
* if the client asked for a specific version ,
* or this is something other than Windows NT x86 ,
* then we ' ve failed
*/
if ( ( flags & DPD_DELETE_SPECIFIC_VERSION ) | | ( version ! = 2 ) )
goto done ;
/* try for Win2k driver if "Windows NT x86" */
version = 3 ;
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & info , 3 , driver , arch , version ) ) ) {
status = WERR_UNKNOWN_PRINTER_DRIVER ;
goto done ;
}
}
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( printer_driver_in_use ( info . info_3 ) ) {
status = WERR_PRINTER_DRIVER_IN_USE ;
goto done ;
}
2002-07-15 14:35:28 +04:00
/*
* we have a couple of cases to consider .
* ( 1 ) Are any files in use ? If so and DPD_DELTE_ALL_FILE is set ,
* then the delete should fail if * * any * * files overlap with
* other drivers
* ( 2 ) If DPD_DELTE_UNUSED_FILES is sert , then delete all
* non - overlapping files
* ( 3 ) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
* is set , the do not delete any files
* Refer to MSDN docs on DeletePrinterDriverEx ( ) for details .
*/
delete_files = flags & ( DPD_DELETE_ALL_FILES | DPD_DELETE_UNUSED_FILES ) ;
2002-09-25 19:19:00 +04:00
/* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
if ( delete_files & & printer_driver_files_in_use ( info . info_3 ) & ( flags & DPD_DELETE_ALL_FILES ) ) {
/* no idea of the correct error here */
status = WERR_ACCESS_DENIED ;
goto done ;
}
/* also check for W32X86/3 if necessary; maybe we already have? */
if ( ( version = = 2 ) & & ( ( flags & DPD_DELETE_SPECIFIC_VERSION ) ! = DPD_DELETE_SPECIFIC_VERSION ) ) {
if ( W_ERROR_IS_OK ( get_a_printer_driver ( & info_win2k , 3 , driver , arch , 3 ) ) )
{
if ( delete_files & & printer_driver_files_in_use ( info_win2k . info_3 ) & ( flags & DPD_DELETE_ALL_FILES ) ) {
/* no idea of the correct error here */
free_a_printer_driver ( info_win2k , 3 ) ;
status = WERR_ACCESS_DENIED ;
goto done ;
}
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
status_win2k = delete_printer_driver ( info_win2k . info_3 , & user , 3 , delete_files ) ;
free_a_printer_driver ( info_win2k , 3 ) ;
/* this should not have failed---if it did, report to client */
if ( ! W_ERROR_IS_OK ( status_win2k ) )
goto done ;
}
2001-05-18 08:11:17 +04:00
}
2002-09-25 19:19:00 +04:00
status = delete_printer_driver ( info . info_3 , & user , version , delete_files ) ;
if ( W_ERROR_IS_OK ( status ) | | W_ERROR_IS_OK ( status_win2k ) )
status = WERR_OK ;
done :
free_a_printer_driver ( info , 3 ) ;
return status ;
}
/****************************************************************************
Internal routine for retreiving printerdata
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR get_printer_dataex ( TALLOC_CTX * ctx , NT_PRINTER_INFO_LEVEL * printer ,
char * key , char * value , uint32 * type , uint8 * * data ,
uint32 * needed , uint32 in_size )
{
REGISTRY_VALUE * val ;
int size , data_len ;
if ( ! ( val = get_printer_data ( printer - > info_2 , key , value ) ) )
return WERR_BADFILE ;
* type = regval_type ( val ) ;
DEBUG ( 5 , ( " get_printer_dataex: allocating %d \n " , in_size ) ) ;
size = regval_size ( val ) ;
/* copy the min(in_size, len) */
if ( in_size ) {
data_len = ( size > in_size ) ? in_size : size * sizeof ( uint8 ) ;
if ( ( * data = ( uint8 * ) talloc_memdup ( ctx , regval_data_p ( val ) , data_len ) ) = = NULL )
return WERR_NOMEM ;
}
else
* data = NULL ;
* needed = size ;
DEBUG ( 5 , ( " get_printer_dataex: copy done \n " ) ) ;
return WERR_OK ;
}
/****************************************************************************
Internal routine for removing printerdata
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR delete_printer_dataex ( NT_PRINTER_INFO_LEVEL * printer , char * key , char * value )
{
delete_printer_data ( printer - > info_2 , key , value ) ;
return mod_a_printer ( * printer , 2 ) ;
2001-05-18 08:11:17 +04:00
}
2002-09-25 19:19:00 +04:00
/****************************************************************************
Internal routine for storing printerdata
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR set_printer_dataex ( NT_PRINTER_INFO_LEVEL * printer , char * key , char * value ,
uint32 type , uint8 * data , int real_len )
{
delete_printer_data ( printer - > info_2 , key , value ) ;
add_printer_data ( printer - > info_2 , key , value , type , data , real_len ) ;
return mod_a_printer ( * printer , 2 ) ;
}
2002-07-15 14:35:28 +04:00
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-02-15 21:07:45 +03:00
GetPrinterData on a printer server Handle .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-09-25 19:19:00 +04:00
static WERROR getprinterdata_printer_server ( TALLOC_CTX * ctx , fstring value , uint32 * type , uint8 * * data , uint32 * needed , uint32 in_size )
2000-02-07 19:17:59 +03:00
{
int i ;
2000-02-07 21:06:54 +03:00
DEBUG ( 8 , ( " getprinterdata_printer_server:%s \n " , value ) ) ;
2000-02-07 19:17:59 +03:00
2002-02-09 07:10:24 +03:00
if ( ! strcmp ( value , " W3SvcInstalled " ) ) {
* type = 0x4 ;
if ( ( * data = ( uint8 * ) talloc_zero ( ctx , 4 * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
* needed = 0x4 ;
return WERR_OK ;
2002-02-09 07:10:24 +03:00
}
2000-06-01 06:35:30 +04:00
if ( ! strcmp ( value , " BeepEnabled " ) ) {
2000-02-07 19:17:59 +03:00
* type = 0x4 ;
2001-03-01 07:00:45 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , 4 * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
2002-02-21 02:36:23 +03:00
SIVAL ( * data , 0 , 0x00 ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
2002-09-25 19:19:00 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-06-01 06:35:30 +04:00
if ( ! strcmp ( value , " EventLog " ) ) {
2000-02-07 19:17:59 +03:00
* type = 0x4 ;
2001-03-01 07:00:45 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , 4 * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
2002-02-21 02:36:23 +03:00
/* formally was 0x1b */
SIVAL ( * data , 0 , 0x0 ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
2002-09-25 19:19:00 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-06-01 06:35:30 +04:00
if ( ! strcmp ( value , " NetPopup " ) ) {
2000-02-07 19:17:59 +03:00
* type = 0x4 ;
2001-03-01 07:00:45 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , 4 * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
2002-02-21 02:36:23 +03:00
SIVAL ( * data , 0 , 0x00 ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
2002-09-25 19:19:00 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-06-01 06:35:30 +04:00
if ( ! strcmp ( value , " MajorVersion " ) ) {
2000-02-07 19:17:59 +03:00
* type = 0x4 ;
2001-03-01 07:00:45 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , 4 * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
2002-07-15 14:35:28 +04:00
# ifndef EMULATE_WIN2K_HACK /* JERRY */
2002-04-06 02:41:39 +04:00
SIVAL ( * data , 0 , 2 ) ;
2002-07-15 14:35:28 +04:00
# else
SIVAL ( * data , 0 , 3 ) ;
# endif
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
2002-09-25 19:19:00 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2002-02-21 02:36:23 +03:00
if ( ! strcmp ( value , " DefaultSpoolDirectory " ) ) {
fstring string ;
fstrcpy ( string , string_truncate ( lp_serverstring ( ) , MAX_SERVER_STRING_LENGTH ) ) ;
2000-02-07 19:17:59 +03:00
* type = 0x1 ;
2000-02-07 21:06:54 +03:00
* needed = 2 * ( strlen ( string ) + 1 ) ;
2001-03-03 08:27:26 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , ( ( * needed > in_size ) ? * needed : in_size ) * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
2001-03-03 08:27:26 +03:00
memset ( * data , 0 , ( * needed > in_size ) ? * needed : in_size ) ;
2000-02-07 19:17:59 +03:00
/* it's done by hand ready to go on the wire */
2000-06-01 06:35:30 +04:00
for ( i = 0 ; i < strlen ( string ) ; i + + ) {
2000-02-07 21:06:54 +03:00
( * data ) [ 2 * i ] = string [ i ] ;
2000-02-07 19:17:59 +03:00
( * data ) [ 2 * i + 1 ] = ' \0 ' ;
}
2002-09-25 19:19:00 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-06-01 06:35:30 +04:00
if ( ! strcmp ( value , " Architecture " ) ) {
2000-02-07 21:06:54 +03:00
pstring string = " Windows NT x86 " ;
2000-02-07 19:17:59 +03:00
* type = 0x1 ;
2000-02-07 21:06:54 +03:00
* needed = 2 * ( strlen ( string ) + 1 ) ;
2001-03-03 08:27:26 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , ( ( * needed > in_size ) ? * needed : in_size ) * sizeof ( uint8 ) ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return WERR_NOMEM ;
2001-03-03 08:27:26 +03:00
memset ( * data , 0 , ( * needed > in_size ) ? * needed : in_size ) ;
2000-06-01 06:35:30 +04:00
for ( i = 0 ; i < strlen ( string ) ; i + + ) {
2000-02-07 21:06:54 +03:00
( * data ) [ 2 * i ] = string [ i ] ;
2000-02-07 19:17:59 +03:00
( * data ) [ 2 * i + 1 ] = ' \0 ' ;
}
2002-09-25 19:19:00 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2002-09-25 19:19:00 +04:00
return WERR_INVALID_PARAM ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* spoolss_getprinterdata
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_getprinterdata ( pipes_struct * p , SPOOL_Q_GETPRINTERDATA * q_u , SPOOL_R_GETPRINTERDATA * r_u )
2000-02-07 19:17:59 +03:00
{
2002-09-25 19:19:00 +04:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * valuename = & q_u - > valuename ;
uint32 in_size = q_u - > size ;
uint32 * type = & r_u - > type ;
uint32 * out_size = & r_u - > size ;
uint8 * * data = & r_u - > data ;
uint32 * needed = & r_u - > needed ;
WERROR status ;
fstring value ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
2000-02-07 19:17:59 +03:00
2000-11-18 02:10:56 +03:00
/*
2000-02-07 19:17:59 +03:00
* Reminder : when it ' s a string , the length is in BYTES
* even if UNICODE is negociated .
*
* JFM , 4 / 19 / 1999
*/
2002-08-17 19:34:15 +04:00
* out_size = in_size ;
2000-02-07 19:17:59 +03:00
/* in case of problem, return some default values */
2002-08-17 19:34:15 +04:00
* needed = 0 ;
* type = 0 ;
2000-02-07 19:17:59 +03:00
2000-02-07 21:06:54 +03:00
DEBUG ( 4 , ( " _spoolss_getprinterdata \n " ) ) ;
2000-02-07 19:17:59 +03:00
2002-09-25 19:19:00 +04:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_getprinterdata: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2002-09-25 19:19:00 +04:00
status = WERR_BADFID ;
goto done ;
2000-02-07 19:17:59 +03:00
}
2002-07-15 14:35:28 +04:00
unistr2_to_ascii ( value , valuename , sizeof ( value ) - 1 ) ;
2002-09-25 19:19:00 +04:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTSERVER )
status = getprinterdata_printer_server ( p - > mem_ctx , value , type , data , needed , * out_size ) ;
2002-07-15 14:35:28 +04:00
else
2002-09-25 19:19:00 +04:00
{
if ( ! get_printer_snum ( p , handle , & snum ) ) {
status = WERR_BADFID ;
goto done ;
}
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
goto done ;
status = get_printer_dataex ( p - > mem_ctx , printer , SPOOL_PRINTERDATA_KEY , value , type , data , needed , * out_size ) ;
}
if ( * needed > * out_size )
status = WERR_MORE_DATA ;
done :
if ( ! W_ERROR_IS_OK ( status ) )
2002-08-17 19:34:15 +04:00
{
2002-09-25 19:19:00 +04:00
DEBUG ( 5 , ( " error: allocating %d \n " , * out_size ) ) ;
2002-08-17 19:34:15 +04:00
2002-07-15 14:35:28 +04:00
/* reply this param doesn't exist */
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
if ( * out_size ) {
if ( ( * data = ( uint8 * ) talloc_zero ( p - > mem_ctx , * out_size * sizeof ( uint8 ) ) ) = = NULL ) {
if ( printer )
free_a_printer ( & printer , 2 ) ;
2002-07-15 14:35:28 +04:00
return WERR_NOMEM ;
2002-09-25 19:19:00 +04:00
}
}
else {
2002-07-15 14:35:28 +04:00
* data = NULL ;
}
}
2002-09-25 19:19:00 +04:00
/* cleanup & exit */
if ( printer )
free_a_printer ( & printer , 2 ) ;
return status ;
2002-07-15 14:35:28 +04:00
}
/*********************************************************
Connect to the client machine .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL spoolss_connect_to_client ( struct cli_state * the_cli , char * remote_machine )
{
extern pstring global_myname ;
ZERO_STRUCTP ( the_cli ) ;
if ( cli_initialise ( the_cli ) = = NULL ) {
DEBUG ( 0 , ( " connect_to_client: unable to initialize client connection. \n " ) ) ;
return False ;
}
if ( ! resolve_name ( remote_machine , & the_cli - > dest_ip , 0x20 ) ) {
DEBUG ( 0 , ( " connect_to_client: Can't resolve address for %s \n " , remote_machine ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
if ( ismyip ( the_cli - > dest_ip ) ) {
DEBUG ( 0 , ( " connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves. \n " , remote_machine ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
if ( ! cli_connect ( the_cli , remote_machine , & the_cli - > dest_ip ) ) {
DEBUG ( 0 , ( " connect_to_client: unable to connect to SMB server on machine %s. Error was : %s. \n " , remote_machine , cli_errstr ( the_cli ) ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
if ( ! attempt_netbios_session_request ( the_cli , global_myname , remote_machine , & the_cli - > dest_ip ) ) {
DEBUG ( 0 , ( " connect_to_client: machine %s rejected the NetBIOS session request. \n " ,
remote_machine ) ) ;
2002-09-25 19:19:00 +04:00
cli_shutdown ( the_cli ) ;
2002-07-15 14:35:28 +04:00
return False ;
}
the_cli - > protocol = PROTOCOL_NT1 ;
if ( ! cli_negprot ( the_cli ) ) {
DEBUG ( 0 , ( " connect_to_client: machine %s rejected the negotiate protocol. Error was : %s. \n " , remote_machine , cli_errstr ( the_cli ) ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
if ( the_cli - > protocol ! = PROTOCOL_NT1 ) {
DEBUG ( 0 , ( " connect_to_client: machine %s didn't negotiate NT protocol. \n " , remote_machine ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
/*
* Do an anonymous session setup .
*/
if ( ! cli_session_setup ( the_cli , " " , " " , 0 , " " , 0 , " " ) ) {
DEBUG ( 0 , ( " connect_to_client: machine %s rejected the session setup. Error was : %s. \n " , remote_machine , cli_errstr ( the_cli ) ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
if ( ! ( the_cli - > sec_mode & 1 ) ) {
DEBUG ( 0 , ( " connect_to_client: machine %s isn't in user level security mode \n " , remote_machine ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
if ( ! cli_send_tconX ( the_cli , " IPC$ " , " IPC " , " " , 1 ) ) {
DEBUG ( 0 , ( " connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s. \n " , remote_machine , cli_errstr ( the_cli ) ) ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
2000-02-07 19:17:59 +03:00
2002-07-15 14:35:28 +04:00
/*
* Ok - we have an anonymous connection to the IPC $ share .
* Now start the NT Domain stuff : - ) .
*/
2000-06-06 00:55:57 +04:00
2002-10-04 08:10:23 +04:00
if ( cli_nt_session_open ( the_cli , PI_SPOOLSS ) = = False ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " connect_to_client: unable to open the domain client session to machine %s. Error was : %s. \n " , remote_machine , cli_errstr ( the_cli ) ) ) ;
cli_nt_session_close ( the_cli ) ;
cli_ulogoff ( the_cli ) ;
cli_shutdown ( the_cli ) ;
return False ;
}
2002-03-28 19:44:26 +03:00
2002-07-15 14:35:28 +04:00
return True ;
2000-02-07 19:17:59 +03:00
}
2000-09-26 01:05:18 +04:00
/***************************************************************************
2002-03-07 04:02:48 +03:00
Connect to the client .
2000-09-26 01:05:18 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-09-26 01:05:18 +04:00
static BOOL srv_spoolss_replyopenprinter ( char * printer , uint32 localprinter , uint32 type , POLICY_HND * handle )
{
2002-04-11 05:50:18 +04:00
WERROR result ;
2000-09-26 01:05:18 +04:00
/*
2000-11-18 02:10:56 +03:00
* If it ' s the first connection , contact the client
2000-09-26 01:05:18 +04:00
* and connect to the IPC $ share anonumously
*/
2000-09-26 14:15:12 +04:00
if ( smb_connections = = 0 ) {
2001-06-02 07:03:28 +04:00
fstring unix_printer ;
fstrcpy ( unix_printer , printer + 2 ) ; /* the +2 is to strip the leading 2 backslashs */
2002-08-17 19:34:15 +04:00
if ( ! spoolss_connect_to_client ( & notify_cli , unix_printer ) )
2000-09-26 01:05:18 +04:00
return False ;
2002-04-11 05:50:18 +04:00
2002-09-25 19:19:00 +04:00
message_register ( MSG_PRINTER_NOTIFY2 , receive_notify2_message_list ) ;
/* Tell the connections db we're now interested in printer
* notify messages . */
register_message_flags ( True , FLAG_MSG_PRINTING ) ;
2000-09-26 14:15:12 +04:00
}
2000-09-26 01:05:18 +04:00
smb_connections + + ;
2002-08-17 19:34:15 +04:00
result = cli_spoolss_reply_open_printer ( & notify_cli , notify_cli . mem_ctx , printer , localprinter ,
2002-03-15 11:14:10 +03:00
type , handle ) ;
2002-07-15 14:35:28 +04:00
2002-04-11 05:50:18 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
DEBUG ( 5 , ( " srv_spoolss_reply_open_printer: Client RPC returned [%s] \n " ,
2002-04-11 06:13:56 +04:00
dos_errstr ( result ) ) ) ;
2002-04-11 05:50:18 +04:00
return ( W_ERROR_IS_OK ( result ) ) ;
2000-09-26 01:05:18 +04:00
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* _spoolss_rffpcnex
* ReplyFindFirstPrinterChangeNotifyEx
*
2002-07-15 14:35:28 +04:00
* before replying OK : status = 0 a rpc call is made to the workstation
* asking ReplyOpenPrinter
2000-02-07 19:17:59 +03:00
*
* in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2000-11-18 02:10:56 +03:00
* called from api_spoolss_rffpcnex
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_rffpcnex ( pipes_struct * p , SPOOL_Q_RFFPCNEX * q_u , SPOOL_R_RFFPCNEX * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 04:24:55 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 flags = q_u - > flags ;
uint32 options = q_u - > options ;
UNISTR2 * localmachine = & q_u - > localmachine ;
uint32 printerlocal = q_u - > printerlocal ;
SPOOL_NOTIFY_OPTION * option = q_u - > option ;
2000-02-07 19:17:59 +03:00
/* store the notify value in the printer struct */
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_rffpcnex: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
Printer - > notify . flags = flags ;
2001-03-03 08:27:26 +03:00
Printer - > notify . options = options ;
2000-02-25 02:01:24 +03:00
Printer - > notify . printerlocal = printerlocal ;
2001-03-01 03:14:45 +03:00
if ( Printer - > notify . option )
free_spool_notify_option ( & Printer - > notify . option ) ;
Printer - > notify . option = dup_spool_notify_option ( option ) ;
2002-07-15 14:35:28 +04:00
unistr2_to_ascii ( Printer - > notify . localmachine , localmachine ,
sizeof ( Printer - > notify . localmachine ) - 1 ) ;
/* Connect to the client machine and send a ReplyOpenPrinter */
2000-02-07 19:17:59 +03:00
2002-07-15 14:35:28 +04:00
if ( ! srv_spoolss_replyopenprinter ( Printer - > notify . localmachine ,
2000-11-18 02:10:56 +03:00
Printer - > notify . printerlocal , 1 ,
2000-09-26 01:05:18 +04:00
& Printer - > notify . client_hnd ) )
2002-07-15 14:35:28 +04:00
return WERR_SERVER_UNAVAILABLE ;
Printer - > notify . client_connected = True ;
2000-09-26 01:05:18 +04:00
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the servername
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_server_name ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp_name , temp ;
uint32 len ;
2000-02-07 19:17:59 +03:00
2002-01-08 03:46:56 +03:00
slprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , get_called_name ( ) ) ;
2000-02-07 19:17:59 +03:00
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , temp_name , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-11-14 05:14:58 +03:00
* fill a notify_info_data with the printername ( not including the servername ) .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_printer_name ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2000-11-08 06:12:16 +03:00
/* the notify name should not contain the \\server\ part */
2002-02-09 07:10:24 +03:00
char * p = strrchr ( printer - > info_2 - > printername , ' \\ ' ) ;
2001-01-18 01:55:02 +03:00
2000-11-08 06:12:16 +03:00
if ( ! p ) {
p = printer - > info_2 - > printername ;
} else {
p + + ;
}
2000-11-14 05:14:58 +03:00
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , p , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2002-02-09 07:10:24 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the servicename
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_share_name ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , lp_servicename ( snum ) , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the port name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_port_name ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2000-02-07 19:17:59 +03:00
/* even if it's strange, that's consistant in all the code */
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > portname , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the printername
* but it doesn ' t exist , have to see what to do
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_driver_name ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > drivername , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the comment
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_comment ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2000-07-26 14:31:05 +04:00
if ( * printer - > info_2 - > comment = = ' \0 ' )
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , lp_comment ( snum ) , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2000-07-26 14:31:05 +04:00
else
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > comment , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the comment
* location = " Room 1, floor 2, building 3 "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_location ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > location , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the device mode
* jfm : xxxx don ' t to it for know but that ' s a real problem ! ! !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_devmode ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
}
/*******************************************************************
* fill a notify_info_data with the separator file name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_sepfile ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > sepfile , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the print processor
* jfm : xxxx return always winprint to indicate we don ' t do anything to it
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_print_processor ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > printprocessor , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the print processor options
* jfm : xxxx send an empty string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_parameters ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > parameters , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the data type
* jfm : xxxx always send RAW as data type
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_datatype ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > datatype , sizeof ( pstring ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the security descriptor
* jfm : xxxx send an null pointer to say no security desc
* have to implement security before !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_security_desc ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2002-09-25 19:19:00 +04:00
data - > notify_data . sd . size = printer - > info_2 - > secdesc_buf - > len ;
data - > notify_data . sd . desc = dup_sec_desc ( mem_ctx , printer - > info_2 - > secdesc_buf - > sec ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the attributes
* jfm : xxxx a samba printer is always shared
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_attributes ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2000-11-14 05:14:58 +03:00
data - > notify_data . value [ 0 ] = printer - > info_2 - > attributes ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the priority
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_priority ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > priority ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the default priority
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_default_priority ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > default_priority ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the start time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_start_time ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > starttime ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the until time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_until_time ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > untiltime ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the status
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_status ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
print_status_struct status ;
2001-12-05 03:54:33 +03:00
print_queue_length ( snum , & status ) ;
2000-02-07 19:17:59 +03:00
data - > notify_data . value [ 0 ] = ( uint32 ) status . status ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the number of jobs queued
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void spoolss_notify_cjobs ( int snum ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-12-05 03:54:33 +03:00
data - > notify_data . value [ 0 ] = print_queue_length ( snum , NULL ) ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the average ppm
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_average_ppm ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
/* always respond 8 pages per minutes */
/* a little hard ! */
data - > notify_data . value [ 0 ] = printer - > info_2 - > averageppm ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with username
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_username ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2002-03-15 11:14:10 +03:00
len = rpcstr_push ( temp , queue - > fs_user , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-07-04 11:15:53 +04:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job status
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_job_status ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2000-04-16 11:28:06 +04:00
data - > notify_data . value [ 0 ] = nt_printj_status ( queue - > status ) ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job name
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_job_name ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2002-03-15 11:14:10 +03:00
len = rpcstr_push ( temp , queue - > fs_file , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2002-02-09 07:10:24 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job status
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_job_status_string ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2001-02-23 06:59:37 +03:00
/*
* Now we ' re returning job status codes we just return a " " here . JRA .
*/
char * p = " " ;
2001-01-18 01:55:02 +03:00
pstring temp ;
uint32 len ;
2000-11-08 03:20:26 +03:00
2001-02-23 06:59:37 +03:00
#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
p = " unknown " ;
2000-04-16 11:28:06 +04:00
switch ( queue - > status ) {
case LPQ_QUEUED :
2000-11-08 03:20:26 +03:00
p = " Queued " ;
2000-04-16 11:28:06 +04:00
break ;
case LPQ_PAUSED :
2000-11-08 03:20:26 +03:00
p = " " ; /* NT provides the paused string */
2000-04-16 11:28:06 +04:00
break ;
case LPQ_SPOOLING :
2000-11-08 03:20:26 +03:00
p = " Spooling " ;
2000-04-16 11:28:06 +04:00
break ;
case LPQ_PRINTING :
2000-11-08 03:20:26 +03:00
p = " Printing " ;
2000-04-16 11:28:06 +04:00
break ;
}
2001-02-23 06:59:37 +03:00
# endif /* NO LONGER NEEDED. */
2001-01-18 01:55:02 +03:00
2001-10-17 02:42:24 +04:00
len = rpcstr_push ( temp , p , sizeof ( temp ) - 2 , STR_TERMINATE ) ;
2001-01-18 01:55:02 +03:00
2002-07-15 14:35:28 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
memcpy ( data - > notify_data . data . string , temp , len ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job time
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_job_time ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = 0x0 ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job size
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_job_size ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = queue - > size ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
2002-03-19 05:35:12 +03:00
/*******************************************************************
* fill a notify_info_data with page info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_total_pages ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
{
data - > notify_data . value [ 0 ] = queue - > page_count ;
data - > notify_data . value [ 1 ] = 0 ;
}
/*******************************************************************
* fill a notify_info_data with pages printed info .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_pages_printed ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
{
data - > notify_data . value [ 0 ] = 0 ; /* Add code when back-end tracks this */
data - > notify_data . value [ 1 ] = 0 ;
}
2000-02-07 19:17:59 +03:00
/*******************************************************************
2002-01-25 21:27:40 +03:00
Fill a notify_info_data with job position .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-25 21:27:40 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_job_position ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
data - > notify_data . value [ 0 ] = queue - > job ;
2001-10-17 02:42:24 +04:00
data - > notify_data . value [ 1 ] = 0 ;
2000-02-07 19:17:59 +03:00
}
2000-10-29 20:27:41 +03:00
/*******************************************************************
2002-01-25 21:27:40 +03:00
Fill a notify_info_data with submitted time .
2000-10-29 20:27:41 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-25 21:27:40 +03:00
2001-01-18 01:55:02 +03:00
static void spoolss_notify_submitted_time ( int snum ,
SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer ,
TALLOC_CTX * mem_ctx )
2000-10-29 20:27:41 +03:00
{
struct tm * t ;
2001-01-18 01:55:02 +03:00
uint32 len ;
2001-03-03 09:47:37 +03:00
SYSTEMTIME st ;
2002-01-25 21:27:40 +03:00
char * p ;
2000-10-29 20:27:41 +03:00
t = gmtime ( & queue - > time ) ;
2001-01-18 01:55:02 +03:00
len = sizeof ( SYSTEMTIME ) ;
2001-10-17 02:42:24 +04:00
data - > notify_data . data . length = len ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . string = ( uint16 * ) talloc ( mem_ctx , len ) ;
if ( ! data - > notify_data . data . string ) {
data - > notify_data . data . length = 0 ;
return ;
}
2001-03-03 09:47:37 +03:00
make_systemtime ( & st , t ) ;
2002-01-25 21:27:40 +03:00
/*
* Systemtime must be linearized as a set of UINT16 ' s .
* Fix from Benjamin ( Bj ) Kuit bj @ it . uts . edu . au
*/
p = ( char * ) data - > notify_data . data . string ;
SSVAL ( p , 0 , st . year ) ;
SSVAL ( p , 2 , st . month ) ;
SSVAL ( p , 4 , st . dayofweek ) ;
SSVAL ( p , 6 , st . day ) ;
SSVAL ( p , 8 , st . hour ) ;
SSVAL ( p , 10 , st . minute ) ;
SSVAL ( p , 12 , st . second ) ;
SSVAL ( p , 14 , st . milliseconds ) ;
2000-10-29 20:27:41 +03:00
}
2000-05-29 01:01:14 +04:00
struct s_notify_info_data_table
{
uint16 type ;
uint16 field ;
char * name ;
uint32 size ;
void ( * fn ) ( int snum , SPOOL_NOTIFY_INFO_DATA * data ,
print_queue_struct * queue ,
2001-01-18 01:55:02 +03:00
NT_PRINTER_INFO_LEVEL * printer , TALLOC_CTX * mem_ctx ) ;
2000-05-29 01:01:14 +04:00
} ;
2002-07-15 14:35:28 +04:00
/* A table describing the various print notification constants and
whether the notification data is a pointer to a variable sized
buffer , a one value uint32 or a two value uint32 . */
2000-02-07 19:17:59 +03:00
struct s_notify_info_data_table notify_info_data_table [ ] =
{
2002-07-15 14:35:28 +04:00
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SERVER_NAME , " PRINTER_NOTIFY_SERVER_NAME " , NOTIFY_STRING , spoolss_notify_server_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRINTER_NAME , " PRINTER_NOTIFY_PRINTER_NAME " , NOTIFY_STRING , spoolss_notify_printer_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SHARE_NAME , " PRINTER_NOTIFY_SHARE_NAME " , NOTIFY_STRING , spoolss_notify_share_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PORT_NAME , " PRINTER_NOTIFY_PORT_NAME " , NOTIFY_STRING , spoolss_notify_port_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DRIVER_NAME , " PRINTER_NOTIFY_DRIVER_NAME " , NOTIFY_STRING , spoolss_notify_driver_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_COMMENT , " PRINTER_NOTIFY_COMMENT " , NOTIFY_STRING , spoolss_notify_comment } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_LOCATION , " PRINTER_NOTIFY_LOCATION " , NOTIFY_STRING , spoolss_notify_location } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DEVMODE , " PRINTER_NOTIFY_DEVMODE " , NOTIFY_POINTER , spoolss_notify_devmode } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SEPFILE , " PRINTER_NOTIFY_SEPFILE " , NOTIFY_STRING , spoolss_notify_sepfile } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRINT_PROCESSOR , " PRINTER_NOTIFY_PRINT_PROCESSOR " , NOTIFY_STRING , spoolss_notify_print_processor } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PARAMETERS , " PRINTER_NOTIFY_PARAMETERS " , NOTIFY_STRING , spoolss_notify_parameters } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DATATYPE , " PRINTER_NOTIFY_DATATYPE " , NOTIFY_STRING , spoolss_notify_datatype } ,
2002-08-17 19:34:15 +04:00
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SECURITY_DESCRIPTOR , " PRINTER_NOTIFY_SECURITY_DESCRIPTOR " , NOTIFY_SECDESC , spoolss_notify_security_desc } ,
2002-07-15 14:35:28 +04:00
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_ATTRIBUTES , " PRINTER_NOTIFY_ATTRIBUTES " , NOTIFY_ONE_VALUE , spoolss_notify_attributes } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRIORITY , " PRINTER_NOTIFY_PRIORITY " , NOTIFY_ONE_VALUE , spoolss_notify_priority } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DEFAULT_PRIORITY , " PRINTER_NOTIFY_DEFAULT_PRIORITY " , NOTIFY_ONE_VALUE , spoolss_notify_default_priority } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_START_TIME , " PRINTER_NOTIFY_START_TIME " , NOTIFY_ONE_VALUE , spoolss_notify_start_time } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_UNTIL_TIME , " PRINTER_NOTIFY_UNTIL_TIME " , NOTIFY_ONE_VALUE , spoolss_notify_until_time } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_STATUS , " PRINTER_NOTIFY_STATUS " , NOTIFY_ONE_VALUE , spoolss_notify_status } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_STATUS_STRING , " PRINTER_NOTIFY_STATUS_STRING " , NOTIFY_POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_CJOBS , " PRINTER_NOTIFY_CJOBS " , NOTIFY_ONE_VALUE , spoolss_notify_cjobs } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_AVERAGE_PPM , " PRINTER_NOTIFY_AVERAGE_PPM " , NOTIFY_ONE_VALUE , spoolss_notify_average_ppm } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_TOTAL_PAGES , " PRINTER_NOTIFY_TOTAL_PAGES " , NOTIFY_POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PAGES_PRINTED , " PRINTER_NOTIFY_PAGES_PRINTED " , NOTIFY_POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_TOTAL_BYTES , " PRINTER_NOTIFY_TOTAL_BYTES " , NOTIFY_POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_BYTES_PRINTED , " PRINTER_NOTIFY_BYTES_PRINTED " , NOTIFY_POINTER , NULL } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PRINTER_NAME , " JOB_NOTIFY_PRINTER_NAME " , NOTIFY_STRING , spoolss_notify_printer_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_MACHINE_NAME , " JOB_NOTIFY_MACHINE_NAME " , NOTIFY_STRING , spoolss_notify_server_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PORT_NAME , " JOB_NOTIFY_PORT_NAME " , NOTIFY_STRING , spoolss_notify_port_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_USER_NAME , " JOB_NOTIFY_USER_NAME " , NOTIFY_STRING , spoolss_notify_username } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_NOTIFY_NAME , " JOB_NOTIFY_NOTIFY_NAME " , NOTIFY_STRING , spoolss_notify_username } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DATATYPE , " JOB_NOTIFY_DATATYPE " , NOTIFY_STRING , spoolss_notify_datatype } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PRINT_PROCESSOR , " JOB_NOTIFY_PRINT_PROCESSOR " , NOTIFY_STRING , spoolss_notify_print_processor } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PARAMETERS , " JOB_NOTIFY_PARAMETERS " , NOTIFY_STRING , spoolss_notify_parameters } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DRIVER_NAME , " JOB_NOTIFY_DRIVER_NAME " , NOTIFY_STRING , spoolss_notify_driver_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DEVMODE , " JOB_NOTIFY_DEVMODE " , NOTIFY_POINTER , spoolss_notify_devmode } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_STATUS , " JOB_NOTIFY_STATUS " , NOTIFY_ONE_VALUE , spoolss_notify_job_status } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_STATUS_STRING , " JOB_NOTIFY_STATUS_STRING " , NOTIFY_STRING , spoolss_notify_job_status_string } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_SECURITY_DESCRIPTOR , " JOB_NOTIFY_SECURITY_DESCRIPTOR " , NOTIFY_POINTER , NULL } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DOCUMENT , " JOB_NOTIFY_DOCUMENT " , NOTIFY_STRING , spoolss_notify_job_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PRIORITY , " JOB_NOTIFY_PRIORITY " , NOTIFY_ONE_VALUE , spoolss_notify_priority } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_POSITION , " JOB_NOTIFY_POSITION " , NOTIFY_ONE_VALUE , spoolss_notify_job_position } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_SUBMITTED , " JOB_NOTIFY_SUBMITTED " , NOTIFY_POINTER , spoolss_notify_submitted_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_START_TIME , " JOB_NOTIFY_START_TIME " , NOTIFY_ONE_VALUE , spoolss_notify_start_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_UNTIL_TIME , " JOB_NOTIFY_UNTIL_TIME " , NOTIFY_ONE_VALUE , spoolss_notify_until_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_TIME , " JOB_NOTIFY_TIME " , NOTIFY_ONE_VALUE , spoolss_notify_job_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_TOTAL_PAGES , " JOB_NOTIFY_TOTAL_PAGES " , NOTIFY_ONE_VALUE , spoolss_notify_total_pages } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PAGES_PRINTED , " JOB_NOTIFY_PAGES_PRINTED " , NOTIFY_ONE_VALUE , spoolss_notify_pages_printed } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_TOTAL_BYTES , " JOB_NOTIFY_TOTAL_BYTES " , NOTIFY_ONE_VALUE , spoolss_notify_job_size } ,
2000-02-07 19:17:59 +03:00
} ;
/*******************************************************************
2002-03-07 04:02:48 +03:00
Return the size of info_data structure .
2000-11-18 02:10:56 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-07 19:17:59 +03:00
static uint32 size_of_notify_info_data ( uint16 type , uint16 field )
{
int i = 0 ;
2002-08-17 19:34:15 +04:00
for ( i = 0 ; i < sizeof ( notify_info_data_table ) ; i + + )
{
if ( ( notify_info_data_table [ i ] . type = = type )
& & ( notify_info_data_table [ i ] . field = = field ) )
{
switch ( notify_info_data_table [ i ] . size )
{
2002-07-15 14:35:28 +04:00
case NOTIFY_ONE_VALUE :
case NOTIFY_TWO_VALUE :
return 1 ;
case NOTIFY_STRING :
return 2 ;
/* The only pointer notify data I have seen on
the wire is the submitted time and this has
the notify size set to 4. - tpot */
case NOTIFY_POINTER :
return 4 ;
2002-08-17 19:34:15 +04:00
case NOTIFY_SECDESC :
return 5 ;
2002-07-15 14:35:28 +04:00
}
2000-02-07 19:17:59 +03:00
}
}
2002-07-15 14:35:28 +04:00
DEBUG ( 5 , ( " invalid notify data type %d/%d \n " , type , field ) ) ;
return 0 ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
2002-03-07 04:02:48 +03:00
Return the type of notify_info_data .
2000-11-18 02:10:56 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-07-15 14:35:28 +04:00
static int type_of_notify_info_data ( uint16 type , uint16 field )
2000-02-07 19:17:59 +03:00
{
int i = 0 ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < sizeof ( notify_info_data_table ) ; i + + ) {
if ( notify_info_data_table [ i ] . type = = type & &
notify_info_data_table [ i ] . field = = field )
return notify_info_data_table [ i ] . size ;
2000-02-07 19:17:59 +03:00
}
2002-07-15 14:35:28 +04:00
return False ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-07 19:17:59 +03:00
static int search_notify ( uint16 type , uint16 field , int * value )
{
2002-07-15 14:35:28 +04:00
int i ;
2000-02-07 19:17:59 +03:00
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < sizeof ( notify_info_data_table ) ; i + + ) {
if ( notify_info_data_table [ i ] . type = = type & &
notify_info_data_table [ i ] . field = = field & &
notify_info_data_table [ i ] . fn ! = NULL ) {
* value = i ;
return True ;
}
2000-02-07 19:17:59 +03:00
}
2002-07-15 14:35:28 +04:00
return False ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-03-15 11:14:10 +03:00
void construct_info_data ( SPOOL_NOTIFY_INFO_DATA * info_data , uint16 type , uint16 field , int id )
2000-02-07 19:17:59 +03:00
{
info_data - > type = type ;
info_data - > field = field ;
2000-02-24 19:27:06 +03:00
info_data - > reserved = 0 ;
2002-07-15 14:35:28 +04:00
2000-02-07 19:17:59 +03:00
info_data - > size = size_of_notify_info_data ( type , field ) ;
info_data - > enc_type = type_of_notify_info_data ( type , field ) ;
2002-08-17 19:34:15 +04:00
info_data - > id = id ;
2000-02-07 19:17:59 +03:00
}
2001-03-03 08:27:26 +03:00
2000-02-07 19:17:59 +03:00
/*******************************************************************
*
* fill a notify_info struct with info asked
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-18 01:55:02 +03:00
static BOOL construct_notify_printer_info ( SPOOL_NOTIFY_INFO * info , int
snum , SPOOL_NOTIFY_OPTION_TYPE
* option_type , uint32 id ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2000-02-24 19:27:06 +03:00
int field_num , j ;
2000-02-07 19:17:59 +03:00
uint16 type ;
uint16 field ;
2001-08-12 21:30:01 +04:00
SPOOL_NOTIFY_INFO_DATA * current_data , * tid ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-24 19:27:06 +03:00
print_queue_struct * queue = NULL ;
2001-02-28 03:51:02 +03:00
2000-02-24 19:27:06 +03:00
type = option_type - > type ;
2000-02-07 19:17:59 +03:00
2001-01-17 21:47:46 +03:00
DEBUG ( 4 , ( " construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s] \n " ,
2000-11-18 02:10:56 +03:00
( option_type - > type = = PRINTER_NOTIFY_TYPE ? " PRINTER_NOTIFY_TYPE " : " JOB_NOTIFY_TYPE " ) ,
2000-02-24 19:27:06 +03:00
option_type - > count , lp_servicename ( snum ) ) ) ;
2000-02-07 19:17:59 +03:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
2000-02-24 19:27:06 +03:00
return False ;
2002-08-17 19:34:15 +04:00
for ( field_num = 0 ; field_num < option_type - > count ; field_num + + )
{
2000-02-24 19:27:06 +03:00
field = option_type - > fields [ field_num ] ;
2002-08-17 19:34:15 +04:00
2001-01-17 21:47:46 +03:00
DEBUG ( 4 , ( " construct_notify_printer_info: notify [%d]: type [%x], field [%x] \n " , field_num , type , field ) ) ;
2000-02-24 19:27:06 +03:00
if ( ! search_notify ( type , field , & j ) )
continue ;
2001-11-22 08:56:09 +03:00
2002-08-17 19:34:15 +04:00
if ( ( tid = ( SPOOL_NOTIFY_INFO_DATA * ) Realloc ( info - > data , ( info - > count + 1 ) * sizeof ( SPOOL_NOTIFY_INFO_DATA ) ) ) = = NULL )
{
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " construct_notify_printer_info: failed to enlarge buffer info->data! \n " ) ) ;
2000-04-07 02:48:53 +04:00
return False ;
}
2002-08-17 19:34:15 +04:00
else
info - > data = tid ;
2001-11-22 08:56:09 +03:00
2002-08-17 19:34:15 +04:00
current_data = & info - > data [ info - > count ] ;
2000-02-07 19:17:59 +03:00
2002-07-15 14:35:28 +04:00
construct_info_data ( current_data , type , field , id ) ;
2000-11-10 22:36:34 +03:00
2001-01-17 21:47:46 +03:00
DEBUG ( 10 , ( " construct_notify_printer_info: calling [%s] snum=%d printername=[%s]) \n " ,
notify_info_data_table [ j ] . name , snum , printer - > info_2 - > printername ) ) ;
2000-11-10 22:36:34 +03:00
2001-01-18 01:55:02 +03:00
notify_info_data_table [ j ] . fn ( snum , current_data , queue ,
printer , mem_ctx ) ;
2000-02-24 19:27:06 +03:00
info - > count + + ;
2000-02-07 19:17:59 +03:00
}
2000-02-24 19:27:06 +03:00
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-02-24 19:27:06 +03:00
return True ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
*
* fill a notify_info struct with info asked
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-01-17 21:47:46 +03:00
static BOOL construct_notify_jobs_info ( print_queue_struct * queue ,
SPOOL_NOTIFY_INFO * info ,
NT_PRINTER_INFO_LEVEL * printer ,
int snum , SPOOL_NOTIFY_OPTION_TYPE
2001-01-18 01:55:02 +03:00
* option_type , uint32 id ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
2000-02-24 19:27:06 +03:00
int field_num , j ;
2000-02-07 19:17:59 +03:00
uint16 type ;
uint16 field ;
2001-03-03 08:27:26 +03:00
2001-08-12 21:30:01 +04:00
SPOOL_NOTIFY_INFO_DATA * current_data , * tid ;
2000-02-07 19:17:59 +03:00
DEBUG ( 4 , ( " construct_notify_jobs_info \n " ) ) ;
2000-02-24 19:27:06 +03:00
type = option_type - > type ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
DEBUGADD ( 4 , ( " Notify type: [%s], number of notify info: [%d] \n " ,
2000-11-18 02:10:56 +03:00
( option_type - > type = = PRINTER_NOTIFY_TYPE ? " PRINTER_NOTIFY_TYPE " : " JOB_NOTIFY_TYPE " ) ,
2000-02-24 19:27:06 +03:00
option_type - > count ) ) ;
2000-02-07 19:17:59 +03:00
2000-06-01 06:35:30 +04:00
for ( field_num = 0 ; field_num < option_type - > count ; field_num + + ) {
2000-02-24 19:27:06 +03:00
field = option_type - > fields [ field_num ] ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
if ( ! search_notify ( type , field , & j ) )
continue ;
2001-08-12 21:30:01 +04:00
if ( ( tid = Realloc ( info - > data , ( info - > count + 1 ) * sizeof ( SPOOL_NOTIFY_INFO_DATA ) ) ) = = NULL ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " construct_notify_jobs_info: failed to enlarg buffer info->data! \n " ) ) ;
2000-04-07 02:48:53 +04:00
return False ;
}
2001-08-12 21:30:01 +04:00
else info - > data = tid ;
2000-04-07 02:48:53 +04:00
2001-03-03 08:27:26 +03:00
current_data = & ( info - > data [ info - > count ] ) ;
2000-02-24 19:27:06 +03:00
construct_info_data ( current_data , type , field , id ) ;
2001-01-18 01:55:02 +03:00
notify_info_data_table [ j ] . fn ( snum , current_data , queue ,
printer , mem_ctx ) ;
2000-02-24 19:27:06 +03:00
info - > count + + ;
2000-02-07 19:17:59 +03:00
}
2000-06-01 06:35:30 +04:00
2000-02-24 19:27:06 +03:00
return True ;
2000-02-07 19:17:59 +03:00
}
2000-02-24 19:27:06 +03:00
/*
* JFM : The enumeration is not that simple , it ' s even non obvious .
*
* let ' s take an example : I want to monitor the PRINTER SERVER for
* the printer ' s name and the number of jobs currently queued .
* So in the NOTIFY_OPTION , I have one NOTIFY_OPTION_TYPE structure .
* Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS .
2000-11-18 02:10:56 +03:00
*
2000-02-24 19:27:06 +03:00
* I have 3 printers on the back of my server .
*
* Now the response is a NOTIFY_INFO structure , with 6 NOTIFY_INFO_DATA
* structures .
* Number Data Id
* 1 printer 1 name 1
* 2 printer 1 cjob 1
* 3 printer 2 name 2
* 4 printer 2 cjob 2
* 5 printer 3 name 3
* 6 printer 3 name 3
*
* that ' s the print server case , the printer case is even worse .
*/
2000-02-07 19:17:59 +03:00
/*******************************************************************
*
* enumerate all printers on the printserver
* fill a notify_info struct with info asked
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
2001-09-03 12:50:59 +04:00
static WERROR printserver_notify_info ( pipes_struct * p , POLICY_HND * hnd ,
2001-01-18 01:55:02 +03:00
SPOOL_NOTIFY_INFO * info ,
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
int snum ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , hnd ) ;
2000-02-07 19:17:59 +03:00
int n_services = lp_numservices ( ) ;
2000-02-24 19:27:06 +03:00
int i ;
uint32 id ;
SPOOL_NOTIFY_OPTION * option ;
SPOOL_NOTIFY_OPTION_TYPE * option_type ;
DEBUG ( 4 , ( " printserver_notify_info \n " ) ) ;
2002-02-09 07:10:24 +03:00
if ( ! Printer )
return WERR_BADFID ;
2000-02-25 02:01:24 +03:00
option = Printer - > notify . option ;
2000-02-24 19:27:06 +03:00
id = 1 ;
info - > version = 2 ;
info - > data = NULL ;
2000-02-07 19:17:59 +03:00
info - > count = 0 ;
2000-06-29 04:52:40 +04:00
for ( i = 0 ; i < option - > count ; i + + ) {
2000-02-24 19:27:06 +03:00
option_type = & ( option - > ctr . type [ i ] ) ;
if ( option_type - > type ! = PRINTER_NOTIFY_TYPE )
continue ;
for ( snum = 0 ; snum < n_services ; snum + + )
2002-08-17 19:34:15 +04:00
{
2000-02-24 19:27:06 +03:00
if ( lp_browseable ( snum ) & & lp_snum_ok ( snum ) & & lp_print_ok ( snum ) )
2002-08-17 19:34:15 +04:00
construct_notify_printer_info ( info , snum , option_type , snum , mem_ctx ) ;
}
2000-02-07 19:17:59 +03:00
}
2000-02-24 19:27:06 +03:00
2002-08-17 19:34:15 +04:00
#if 0
2000-02-24 19:27:06 +03:00
/*
* Debugging information , don ' t delete .
*/
2002-08-17 19:34:15 +04:00
2001-03-03 08:27:26 +03:00
DEBUG ( 1 , ( " dumping the NOTIFY_INFO \n " ) ) ;
2000-02-24 19:27:06 +03:00
DEBUGADD ( 1 , ( " info->version:[%d], info->flags:[%d], info->count:[%d] \n " , info - > version , info - > flags , info - > count ) ) ;
DEBUGADD ( 1 , ( " num \t type \t field \t res \t id \t size \t enc_type \n " ) ) ;
2000-06-29 04:52:40 +04:00
for ( i = 0 ; i < info - > count ; i + + ) {
2000-02-24 19:27:06 +03:00
DEBUGADD ( 1 , ( " [%d] \t [%d] \t [%d] \t [%d] \t [%d] \t [%d] \t [%d] \n " ,
i , info - > data [ i ] . type , info - > data [ i ] . field , info - > data [ i ] . reserved ,
info - > data [ i ] . id , info - > data [ i ] . size , info - > data [ i ] . enc_type ) ) ;
2000-02-07 19:17:59 +03:00
}
2002-08-17 19:34:15 +04:00
# endif
2000-02-24 19:27:06 +03:00
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
*
* fill a notify_info struct with info asked
2000-11-18 02:10:56 +03:00
*
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR printer_notify_info ( pipes_struct * p , POLICY_HND * hnd , SPOOL_NOTIFY_INFO * info ,
2001-01-18 01:55:02 +03:00
TALLOC_CTX * mem_ctx )
2000-02-07 19:17:59 +03:00
{
int snum ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , hnd ) ;
2000-02-24 19:27:06 +03:00
int i ;
uint32 id ;
SPOOL_NOTIFY_OPTION * option ;
SPOOL_NOTIFY_OPTION_TYPE * option_type ;
int count , j ;
print_queue_struct * queue = NULL ;
print_status_struct status ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
DEBUG ( 4 , ( " printer_notify_info \n " ) ) ;
2002-02-09 07:10:24 +03:00
if ( ! Printer )
return WERR_BADFID ;
2000-02-25 02:01:24 +03:00
option = Printer - > notify . option ;
2002-03-15 11:14:10 +03:00
id = 0x0 ;
2000-02-24 19:27:06 +03:00
info - > version = 2 ;
info - > data = NULL ;
2000-02-07 19:17:59 +03:00
info - > count = 0 ;
2001-03-11 03:32:10 +03:00
get_printer_snum ( p , hnd , & snum ) ;
2000-02-07 19:17:59 +03:00
2000-06-29 04:52:40 +04:00
for ( i = 0 ; i < option - > count ; i + + ) {
option_type = & option - > ctr . type [ i ] ;
2000-02-24 19:27:06 +03:00
switch ( option_type - > type ) {
case PRINTER_NOTIFY_TYPE :
2001-03-03 08:27:26 +03:00
if ( construct_notify_printer_info ( info , snum ,
option_type , id ,
mem_ctx ) )
2000-04-05 14:05:32 +04:00
id - - ;
2000-02-24 19:27:06 +03:00
break ;
2001-01-17 21:47:46 +03:00
case JOB_NOTIFY_TYPE : {
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-04-16 10:20:43 +04:00
count = print_queue_status ( snum , & queue , & status ) ;
2001-01-17 21:47:46 +03:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 ,
lp_servicename ( snum ) ) ) )
2001-01-17 21:47:46 +03:00
goto done ;
for ( j = 0 ; j < count ; j + + ) {
construct_notify_jobs_info ( & queue [ j ] , info ,
printer , snum ,
option_type ,
2001-01-18 01:55:02 +03:00
queue [ j ] . job ,
mem_ctx ) ;
2001-01-17 21:47:46 +03:00
}
free_a_printer ( & printer , 2 ) ;
2001-01-18 01:55:02 +03:00
2001-01-17 21:47:46 +03:00
done :
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2000-02-24 19:27:06 +03:00
break ;
2000-02-07 19:17:59 +03:00
}
2001-01-17 21:47:46 +03:00
}
2000-02-07 19:17:59 +03:00
}
2000-02-24 19:27:06 +03:00
/*
* Debugging information , don ' t delete .
*/
2001-03-03 08:27:26 +03:00
/*
DEBUG ( 1 , ( " dumping the NOTIFY_INFO \n " ) ) ;
DEBUGADD ( 1 , ( " info->version:[%d], info->flags:[%d], info->count:[%d] \n " , info - > version , info - > flags , info - > count ) ) ;
DEBUGADD ( 1 , ( " num \t type \t field \t res \t id \t size \t enc_type \n " ) ) ;
2000-02-24 19:27:06 +03:00
2000-06-29 04:52:40 +04:00
for ( i = 0 ; i < info - > count ; i + + ) {
2001-03-03 08:27:26 +03:00
DEBUGADD ( 1 , ( " [%d] \t [%d] \t [%d] \t [%d] \t [%d] \t [%d] \t [%d] \n " ,
2000-02-24 19:27:06 +03:00
i , info - > data [ i ] . type , info - > data [ i ] . field , info - > data [ i ] . reserved ,
info - > data [ i ] . id , info - > data [ i ] . size , info - > data [ i ] . enc_type ) ) ;
}
2001-03-03 08:27:26 +03:00
*/
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* spoolss_rfnpcnex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-03 12:50:59 +04:00
WERROR _spoolss_rfnpcnex ( pipes_struct * p , SPOOL_Q_RFNPCNEX * q_u , SPOOL_R_RFNPCNEX * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 04:24:55 +03:00
POLICY_HND * handle = & q_u - > handle ;
SPOOL_NOTIFY_INFO * info = & r_u - > info ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2001-09-03 12:50:59 +04:00
WERROR result = WERR_BADFID ;
2000-02-07 19:17:59 +03:00
2001-02-28 04:24:55 +03:00
/* we always have a NOTIFY_INFO struct */
r_u - > info_ptr = 0x1 ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_rfnpcnex: Invalid handle (%s:%u:%u). \n " ,
2001-01-18 01:55:02 +03:00
OUR_HANDLE ( handle ) ) ) ;
goto done ;
2000-07-07 03:31:46 +04:00
}
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
DEBUG ( 4 , ( " Printer type %x \n " , Printer - > printer_type ) ) ;
2000-02-24 19:27:06 +03:00
2002-07-15 14:35:28 +04:00
/*
* We are now using the change value , and
2000-11-18 02:10:56 +03:00
* I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2000-02-24 19:27:06 +03:00
* I don ' t have a global notification system , I ' m sending back all the
* informations even when _NOTHING_ has changed .
*/
2000-02-07 19:17:59 +03:00
2002-07-15 14:35:28 +04:00
/* We need to keep track of the change value to send back in
RRPCN replies otherwise our updates are ignored . */
2002-08-17 19:34:15 +04:00
if ( Printer - > notify . client_connected ) {
DEBUG ( 10 , ( " _spoolss_rfnpcnex: Saving change value in request [%x] \n " , q_u - > change ) ) ;
2002-07-15 14:35:28 +04:00
Printer - > notify . change = q_u - > change ;
2002-08-17 19:34:15 +04:00
}
2002-07-15 14:35:28 +04:00
2001-02-28 03:51:02 +03:00
/* just ignore the SPOOL_NOTIFY_OPTION */
2000-02-24 19:27:06 +03:00
2000-02-25 02:01:24 +03:00
switch ( Printer - > printer_type ) {
2000-02-07 19:17:59 +03:00
case PRINTER_HANDLE_IS_PRINTSERVER :
2001-03-11 03:32:10 +03:00
result = printserver_notify_info ( p , handle , info , p - > mem_ctx ) ;
2001-01-18 01:55:02 +03:00
break ;
2000-02-07 19:17:59 +03:00
case PRINTER_HANDLE_IS_PRINTER :
2001-03-11 03:32:10 +03:00
result = printer_notify_info ( p , handle , info , p - > mem_ctx ) ;
2001-01-18 01:55:02 +03:00
break ;
2000-02-07 19:17:59 +03:00
}
2001-03-03 08:27:26 +03:00
2001-01-18 01:55:02 +03:00
done :
return result ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_info_0
2000-11-10 22:36:34 +03:00
* fill a printer_info_0 struct
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-11-10 22:36:34 +03:00
static BOOL construct_printer_info_0 ( PRINTER_INFO_0 * printer , int snum )
2000-02-07 19:17:59 +03:00
{
pstring chaine ;
int count ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2000-03-10 20:12:24 +03:00
counter_printer_0 * session_counter ;
uint32 global_counter ;
struct tm * t ;
2000-10-27 01:43:13 +04:00
time_t setuptime ;
2000-02-07 19:17:59 +03:00
print_status_struct status ;
2000-03-10 20:12:24 +03:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ) )
2000-03-10 20:12:24 +03:00
return False ;
2000-02-07 19:17:59 +03:00
2001-12-05 05:11:03 +03:00
count = print_queue_length ( snum , & status ) ;
2000-03-10 20:12:24 +03:00
/* check if we already have a counter for this printer */
session_counter = ( counter_printer_0 * ) ubi_dlFirst ( & counter_list ) ;
for ( ; session_counter ; session_counter = ( counter_printer_0 * ) ubi_dlNext ( session_counter ) ) {
if ( session_counter - > snum = = snum )
break ;
}
/* it's the first time, add it to the list */
if ( session_counter = = NULL ) {
2000-06-01 06:35:30 +04:00
if ( ( session_counter = ( counter_printer_0 * ) malloc ( sizeof ( counter_printer_0 ) ) ) = = NULL ) {
free_a_printer ( & ntprinter , 2 ) ;
2000-04-07 02:48:53 +04:00
return False ;
2000-06-01 06:35:30 +04:00
}
2000-03-10 20:12:24 +03:00
ZERO_STRUCTP ( session_counter ) ;
session_counter - > snum = snum ;
session_counter - > counter = 0 ;
ubi_dlAddHead ( & counter_list , ( ubi_dlNode * ) session_counter ) ;
}
/* increment it */
session_counter - > counter + + ;
/* JFM:
* the global_counter should be stored in a TDB as it ' s common to all the clients
* and should be zeroed on samba startup
*/
global_counter = session_counter - > counter ;
2000-02-07 19:17:59 +03:00
2000-11-08 06:12:16 +03:00
pstrcpy ( chaine , ntprinter - > info_2 - > printername ) ;
2000-06-24 04:15:08 +04:00
init_unistr ( & printer - > printername , chaine ) ;
2000-02-07 19:17:59 +03:00
2002-01-08 03:46:56 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s " , get_called_name ( ) ) ;
2000-06-24 04:15:08 +04:00
init_unistr ( & printer - > servername , chaine ) ;
2000-02-07 19:17:59 +03:00
printer - > cjobs = count ;
2000-03-10 20:12:24 +03:00
printer - > total_jobs = 0 ;
printer - > total_bytes = 0 ;
2000-10-27 01:43:13 +04:00
setuptime = ( time_t ) ntprinter - > info_2 - > setuptime ;
t = gmtime ( & setuptime ) ;
2000-03-10 20:12:24 +03:00
printer - > year = t - > tm_year + 1900 ;
printer - > month = t - > tm_mon + 1 ;
printer - > dayofweek = t - > tm_wday ;
printer - > day = t - > tm_mday ;
printer - > hour = t - > tm_hour ;
printer - > minute = t - > tm_min ;
printer - > second = t - > tm_sec ;
printer - > milliseconds = 0 ;
printer - > global_counter = global_counter ;
printer - > total_pages = 0 ;
2002-07-15 14:35:28 +04:00
# ifndef EMULATE_WIN2K_HACK /* JERRY */
2000-03-10 20:12:24 +03:00
printer - > major_version = 0x0004 ; /* NT 4 */
printer - > build_version = 0x0565 ; /* build 1381 */
2002-03-15 11:14:10 +03:00
# else
printer - > major_version = 0x0005 ; /* NT 5 */
printer - > build_version = 0x0893 ; /* build 2195 */
# endif
2000-03-10 20:12:24 +03:00
printer - > unknown7 = 0x1 ;
printer - > unknown8 = 0x0 ;
2000-04-05 14:05:32 +04:00
printer - > unknown9 = 0x0 ;
2000-03-10 20:12:24 +03:00
printer - > session_counter = session_counter - > counter ;
printer - > unknown11 = 0x0 ;
printer - > printer_errors = 0x0 ; /* number of print failure */
printer - > unknown13 = 0x0 ;
printer - > unknown14 = 0x1 ;
printer - > unknown15 = 0x024a ; /* 586 Pentium ? */
2001-01-30 00:34:08 +03:00
printer - > unknown16 = 0x0 ;
2000-06-01 06:35:30 +04:00
printer - > change_id = ntprinter - > info_2 - > changeid ; /* ChangeID in milliseconds*/
2001-01-30 00:34:08 +03:00
printer - > unknown18 = 0x0 ;
2000-04-16 11:28:06 +04:00
printer - > status = nt_printq_status ( status . status ) ;
2001-01-30 00:34:08 +03:00
printer - > unknown20 = 0x0 ;
2002-02-09 07:10:24 +03:00
printer - > c_setprinter = get_c_setprinter ( ) ; /* monotonically increasing sum of delta printer counts */
2000-03-10 20:12:24 +03:00
printer - > unknown22 = 0x0 ;
printer - > unknown23 = 0x6 ; /* 6 ???*/
printer - > unknown24 = 0 ; /* unknown 24 to 26 are always 0 */
printer - > unknown25 = 0 ;
printer - > unknown26 = 0 ;
printer - > unknown27 = 0 ;
printer - > unknown28 = 0 ;
printer - > unknown29 = 0 ;
2000-06-01 06:35:30 +04:00
free_a_printer ( & ntprinter , 2 ) ;
2000-02-07 19:17:59 +03:00
return ( True ) ;
}
/********************************************************************
* construct_printer_info_1
* fill a printer_info_1 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-14 04:48:59 +03:00
static BOOL construct_printer_info_1 ( uint32 flags , PRINTER_INFO_1 * printer , int snum )
2000-02-07 19:17:59 +03:00
{
pstring chaine ;
2000-02-15 21:07:45 +03:00
pstring chaine2 ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2000-03-07 21:10:20 +03:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ) )
2000-03-07 21:10:20 +03:00
return False ;
2000-02-07 19:17:59 +03:00
2000-03-07 21:10:20 +03:00
printer - > flags = flags ;
2000-02-15 21:07:45 +03:00
2000-07-26 14:31:05 +04:00
if ( * ntprinter - > info_2 - > comment = = ' \0 ' ) {
init_unistr ( & printer - > comment , lp_comment ( snum ) ) ;
2002-03-20 03:24:35 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " %s,%s,%s " , ntprinter - > info_2 - > printername ,
2002-03-14 04:48:59 +03:00
ntprinter - > info_2 - > drivername , lp_comment ( snum ) ) ;
}
else {
2000-07-26 14:31:05 +04:00
init_unistr ( & printer - > comment , ntprinter - > info_2 - > comment ) ; /* saved comment. */
2002-03-20 03:24:35 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " %s,%s,%s " , ntprinter - > info_2 - > printername ,
2002-03-14 04:48:59 +03:00
ntprinter - > info_2 - > drivername , ntprinter - > info_2 - > comment ) ;
2000-07-26 14:31:05 +04:00
}
2000-03-07 21:10:20 +03:00
2001-02-16 22:21:18 +03:00
slprintf ( chaine2 , sizeof ( chaine ) - 1 , " %s " , ntprinter - > info_2 - > printername ) ;
2000-03-07 21:10:20 +03:00
init_unistr ( & printer - > description , chaine ) ;
init_unistr ( & printer - > name , chaine2 ) ;
2000-02-07 19:17:59 +03:00
2000-06-01 06:35:30 +04:00
free_a_printer ( & ntprinter , 2 ) ;
2000-03-07 21:10:20 +03:00
return True ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
2000-06-01 06:35:30 +04:00
Free a DEVMODE struct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_dev_mode ( DEVICEMODE * dev )
{
if ( dev = = NULL )
return ;
2002-02-09 07:10:24 +03:00
SAFE_FREE ( dev - > private ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( dev ) ;
2000-06-01 06:35:30 +04:00
}
2002-09-25 19:19:00 +04:00
2000-06-01 06:35:30 +04:00
/****************************************************************************
2002-09-25 19:19:00 +04:00
Convert an NT_DEVICEMODE to a DEVICEMODE structure . Both pointers
should be valid upon entry
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
2002-09-25 19:19:00 +04:00
static BOOL convert_nt_devicemode ( DEVICEMODE * devmode , NT_DEVICEMODE * ntdevmode )
2000-02-07 19:17:59 +03:00
{
2002-09-25 19:19:00 +04:00
if ( ! devmode | | ! ntdevmode )
return False ;
init_unistr ( & devmode - > devicename , ntdevmode - > devicename ) ;
2000-02-07 19:17:59 +03:00
2002-09-25 19:19:00 +04:00
init_unistr ( & devmode - > formname , ntdevmode - > formname ) ;
2000-02-07 19:17:59 +03:00
2000-06-01 06:35:30 +04:00
devmode - > specversion = ntdevmode - > specversion ;
devmode - > driverversion = ntdevmode - > driverversion ;
devmode - > size = ntdevmode - > size ;
devmode - > driverextra = ntdevmode - > driverextra ;
devmode - > fields = ntdevmode - > fields ;
2000-11-18 02:10:56 +03:00
2000-06-01 06:35:30 +04:00
devmode - > orientation = ntdevmode - > orientation ;
devmode - > papersize = ntdevmode - > papersize ;
devmode - > paperlength = ntdevmode - > paperlength ;
devmode - > paperwidth = ntdevmode - > paperwidth ;
devmode - > scale = ntdevmode - > scale ;
devmode - > copies = ntdevmode - > copies ;
devmode - > defaultsource = ntdevmode - > defaultsource ;
devmode - > printquality = ntdevmode - > printquality ;
devmode - > color = ntdevmode - > color ;
devmode - > duplex = ntdevmode - > duplex ;
devmode - > yresolution = ntdevmode - > yresolution ;
devmode - > ttoption = ntdevmode - > ttoption ;
devmode - > collate = ntdevmode - > collate ;
devmode - > icmmethod = ntdevmode - > icmmethod ;
devmode - > icmintent = ntdevmode - > icmintent ;
devmode - > mediatype = ntdevmode - > mediatype ;
devmode - > dithertype = ntdevmode - > dithertype ;
if ( ntdevmode - > private ! = NULL ) {
if ( ( devmode - > private = ( uint8 * ) memdup ( ntdevmode - > private , ntdevmode - > driverextra ) ) = = NULL )
2002-09-25 19:19:00 +04:00
return False ;
2000-06-01 06:35:30 +04:00
}
2002-09-25 19:19:00 +04:00
return True ;
}
2000-06-01 06:35:30 +04:00
2002-09-25 19:19:00 +04:00
/****************************************************************************
Create a DEVMODE struct . Returns malloced memory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-02 23:42:11 +04:00
2002-09-25 19:19:00 +04:00
DEVICEMODE * construct_dev_mode ( int snum )
{
NT_PRINTER_INFO_LEVEL * printer = NULL ;
DEVICEMODE * devmode = NULL ;
DEBUG ( 7 , ( " construct_dev_mode \n " ) ) ;
DEBUGADD ( 8 , ( " getting printer characteristics \n " ) ) ;
2000-06-01 06:35:30 +04:00
2002-09-25 19:19:00 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
return NULL ;
2000-06-01 06:35:30 +04:00
2002-09-25 19:19:00 +04:00
if ( ! printer - > info_2 - > devmode ) {
DEBUG ( 5 , ( " BONG! There was no device mode! \n " ) ) ;
goto done ;
}
if ( ( devmode = ( DEVICEMODE * ) malloc ( sizeof ( DEVICEMODE ) ) ) = = NULL ) {
DEBUG ( 2 , ( " construct_dev_mode: malloc fail. \n " ) ) ;
goto done ;
}
ZERO_STRUCTP ( devmode ) ;
DEBUGADD ( 8 , ( " loading DEVICEMODE \n " ) ) ;
if ( ! convert_nt_devicemode ( devmode , printer - > info_2 - > devmode ) ) {
free_dev_mode ( devmode ) ;
devmode = NULL ;
}
2000-02-07 19:17:59 +03:00
2002-09-25 19:19:00 +04:00
done :
free_a_printer ( & printer , 2 ) ;
return devmode ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_info_2
* fill a printer_info_2 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
2000-11-10 22:36:34 +03:00
static BOOL construct_printer_info_2 ( PRINTER_INFO_2 * printer , int snum )
2000-02-07 19:17:59 +03:00
{
int count ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2000-03-10 20:12:24 +03:00
2000-02-07 19:17:59 +03:00
print_status_struct status ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ) )
2000-03-10 20:12:24 +03:00
return False ;
2001-12-05 05:11:03 +03:00
count = print_queue_length ( snum , & status ) ;
2000-02-07 19:17:59 +03:00
2000-11-10 22:36:34 +03:00
init_unistr ( & printer - > servername , ntprinter - > info_2 - > servername ) ; /* servername*/
init_unistr ( & printer - > printername , ntprinter - > info_2 - > printername ) ; /* printername*/
2000-03-10 20:12:24 +03:00
init_unistr ( & printer - > sharename , lp_servicename ( snum ) ) ; /* sharename */
2000-08-01 01:41:03 +04:00
init_unistr ( & printer - > portname , ntprinter - > info_2 - > portname ) ; /* port */
2000-06-01 06:35:30 +04:00
init_unistr ( & printer - > drivername , ntprinter - > info_2 - > drivername ) ; /* drivername */
2000-07-22 04:48:29 +04:00
if ( * ntprinter - > info_2 - > comment = = ' \0 ' )
init_unistr ( & printer - > comment , lp_comment ( snum ) ) ; /* comment */
else
init_unistr ( & printer - > comment , ntprinter - > info_2 - > comment ) ; /* saved comment. */
2000-06-01 06:35:30 +04:00
init_unistr ( & printer - > location , ntprinter - > info_2 - > location ) ; /* location */
init_unistr ( & printer - > sepfile , ntprinter - > info_2 - > sepfile ) ; /* separator file */
init_unistr ( & printer - > printprocessor , ntprinter - > info_2 - > printprocessor ) ; /* print processor */
init_unistr ( & printer - > datatype , ntprinter - > info_2 - > datatype ) ; /* datatype */
init_unistr ( & printer - > parameters , ntprinter - > info_2 - > parameters ) ; /* parameters (of print processor) */
2000-02-07 19:17:59 +03:00
2000-06-06 05:34:20 +04:00
printer - > attributes = ntprinter - > info_2 - > attributes ;
2000-03-10 20:12:24 +03:00
2000-06-01 06:35:30 +04:00
printer - > priority = ntprinter - > info_2 - > priority ; /* priority */
printer - > defaultpriority = ntprinter - > info_2 - > default_priority ; /* default priority */
printer - > starttime = ntprinter - > info_2 - > starttime ; /* starttime */
printer - > untiltime = ntprinter - > info_2 - > untiltime ; /* untiltime */
2000-04-16 11:28:06 +04:00
printer - > status = nt_printq_status ( status . status ) ; /* status */
2000-03-10 20:12:24 +03:00
printer - > cjobs = count ; /* jobs */
2000-06-01 06:35:30 +04:00
printer - > averageppm = ntprinter - > info_2 - > averageppm ; /* average pages per minute */
2000-02-07 19:17:59 +03:00
2000-11-10 22:36:34 +03:00
if ( ( printer - > devmode = construct_dev_mode ( snum ) ) = = NULL ) {
2000-07-12 18:10:40 +04:00
DEBUG ( 8 , ( " Returning NULL Devicemode! \n " ) ) ;
}
2000-04-07 02:48:53 +04:00
2000-06-27 02:08:20 +04:00
if ( ntprinter - > info_2 - > secdesc_buf & & ntprinter - > info_2 - > secdesc_buf - > len ! = 0 ) {
2000-05-27 05:26:34 +04:00
/* steal the printer info sec_desc structure. [badly done]. */
2000-06-01 06:35:30 +04:00
printer - > secdesc = ntprinter - > info_2 - > secdesc_buf - > sec ;
ntprinter - > info_2 - > secdesc_buf - > sec = NULL ; /* Stolen memory. */
ntprinter - > info_2 - > secdesc_buf - > len = 0 ; /* Stolen memory. */
ntprinter - > info_2 - > secdesc_buf - > max_len = 0 ; /* Stolen memory. */
2000-05-27 05:26:34 +04:00
}
2000-06-01 06:35:30 +04:00
else {
2000-05-27 05:26:34 +04:00
printer - > secdesc = NULL ;
}
2000-06-01 06:35:30 +04:00
free_a_printer ( & ntprinter , 2 ) ;
2000-03-10 20:12:24 +03:00
return True ;
2000-02-07 19:17:59 +03:00
}
2000-05-27 05:26:34 +04:00
/********************************************************************
* construct_printer_info_3
* fill a printer_info_3 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-11-10 22:36:34 +03:00
static BOOL construct_printer_info_3 ( PRINTER_INFO_3 * * pp_printer , int snum )
2000-05-27 05:26:34 +04:00
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2000-06-03 00:08:28 +04:00
PRINTER_INFO_3 * printer = NULL ;
2000-05-27 05:26:34 +04:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ) )
2000-05-27 05:26:34 +04:00
return False ;
2000-06-03 00:08:28 +04:00
* pp_printer = NULL ;
if ( ( printer = ( PRINTER_INFO_3 * ) malloc ( sizeof ( PRINTER_INFO_3 ) ) ) = = NULL ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " construct_printer_info_3: malloc fail. \n " ) ) ;
2000-06-03 00:08:28 +04:00
return False ;
}
2000-06-07 05:49:23 +04:00
ZERO_STRUCTP ( printer ) ;
2000-06-03 00:08:28 +04:00
2000-09-15 04:15:10 +04:00
printer - > flags = 4 ; /* These are the components of the SD we are returning. */
2000-06-27 02:08:20 +04:00
if ( ntprinter - > info_2 - > secdesc_buf & & ntprinter - > info_2 - > secdesc_buf - > len ! = 0 ) {
2000-05-27 05:26:34 +04:00
/* steal the printer info sec_desc structure. [badly done]. */
2000-06-01 06:35:30 +04:00
printer - > secdesc = ntprinter - > info_2 - > secdesc_buf - > sec ;
2000-09-15 04:15:10 +04:00
#if 0
/*
* Set the flags for the components we are returning .
*/
if ( printer - > secdesc - > owner_sid )
printer - > flags | = OWNER_SECURITY_INFORMATION ;
if ( printer - > secdesc - > grp_sid )
printer - > flags | = GROUP_SECURITY_INFORMATION ;
if ( printer - > secdesc - > dacl )
printer - > flags | = DACL_SECURITY_INFORMATION ;
if ( printer - > secdesc - > sacl )
printer - > flags | = SACL_SECURITY_INFORMATION ;
# endif
2000-06-01 06:35:30 +04:00
ntprinter - > info_2 - > secdesc_buf - > sec = NULL ; /* Stolen the malloced memory. */
ntprinter - > info_2 - > secdesc_buf - > len = 0 ; /* Stolen the malloced memory. */
ntprinter - > info_2 - > secdesc_buf - > max_len = 0 ; /* Stolen the malloced memory. */
2000-05-27 05:26:34 +04:00
}
2000-06-01 06:35:30 +04:00
free_a_printer ( & ntprinter , 2 ) ;
2000-06-03 00:08:28 +04:00
* pp_printer = printer ;
2000-05-27 05:26:34 +04:00
return True ;
}
2002-01-12 05:37:54 +03:00
/********************************************************************
* construct_printer_info_4
* fill a printer_info_4 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL construct_printer_info_4 ( PRINTER_INFO_4 * printer , int snum )
{
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
if ( ! W_ERROR_IS_OK ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ) )
return False ;
init_unistr ( & printer - > printername , ntprinter - > info_2 - > printername ) ; /* printername*/
init_unistr ( & printer - > servername , ntprinter - > info_2 - > servername ) ; /* servername*/
printer - > attributes = ntprinter - > info_2 - > attributes ;
free_a_printer ( & ntprinter , 2 ) ;
return True ;
}
/********************************************************************
* construct_printer_info_5
* fill a printer_info_5 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL construct_printer_info_5 ( PRINTER_INFO_5 * printer , int snum )
{
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
if ( ! W_ERROR_IS_OK ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ) )
return False ;
init_unistr ( & printer - > printername , ntprinter - > info_2 - > printername ) ; /* printername*/
init_unistr ( & printer - > portname , ntprinter - > info_2 - > portname ) ; /* portname */
printer - > attributes = ntprinter - > info_2 - > attributes ;
printer - > device_not_selected_timeout = 0x3a98 ;
printer - > transmission_retry_timeout = 0xafc8 ;
free_a_printer ( & ntprinter , 2 ) ;
return True ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-03-07 21:10:20 +03:00
Spoolss_enumprinters .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enum_all_printers_info_1 ( uint32 flags , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
int snum ;
2000-02-15 21:07:45 +03:00
int i ;
2000-02-07 19:17:59 +03:00
int n_services = lp_numservices ( ) ;
2001-08-12 21:30:01 +04:00
PRINTER_INFO_1 * tp , * printers = NULL ;
2000-03-07 21:10:20 +03:00
PRINTER_INFO_1 current_prt ;
DEBUG ( 4 , ( " enum_all_printers_info_1 \n " ) ) ;
2000-02-15 21:07:45 +03:00
for ( snum = 0 ; snum < n_services ; snum + + ) {
if ( lp_browseable ( snum ) & & lp_snum_ok ( snum ) & & lp_print_ok ( snum ) ) {
DEBUG ( 4 , ( " Found a printer in smb.conf: %s[%x] \n " , lp_servicename ( snum ) , snum ) ) ;
2002-03-12 03:16:03 +03:00
2002-03-14 04:48:59 +03:00
if ( construct_printer_info_1 ( flags , & current_prt , snum ) ) {
2001-08-12 21:30:01 +04:00
if ( ( tp = Realloc ( printers , ( * returned + 1 ) * sizeof ( PRINTER_INFO_1 ) ) ) = = NULL ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " enum_all_printers_info_1: failed to enlarge printers buffer! \n " ) ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printers ) ;
2000-04-07 02:48:53 +04:00
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
}
2001-08-12 21:30:01 +04:00
else printers = tp ;
2000-03-07 21:10:20 +03:00
DEBUG ( 4 , ( " ReAlloced memory for [%d] PRINTER_INFO_1 \n " , * returned ) ) ;
2002-03-12 03:16:03 +03:00
2001-03-01 03:40:25 +03:00
memcpy ( & printers [ * returned ] , & current_prt , sizeof ( PRINTER_INFO_1 ) ) ;
2000-02-15 21:07:45 +03:00
( * returned ) + + ;
2000-03-07 21:10:20 +03:00
}
2000-02-15 21:07:45 +03:00
}
}
2000-03-07 21:10:20 +03:00
2000-02-15 21:07:45 +03:00
/* check the required size. */
for ( i = 0 ; i < * returned ; i + + )
2001-03-01 03:40:25 +03:00
( * needed ) + = spoolss_size_printer_info_1 ( & printers [ i ] ) ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
/* fill the buffer with the structures */
for ( i = 0 ; i < * returned ; i + + )
2001-03-28 20:08:00 +04:00
smb_io_printer_info_1 ( " " , buffer , & printers [ i ] , 0 ) ;
2000-03-07 21:10:20 +03:00
2000-02-15 21:07:45 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printers ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
else
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/********************************************************************
2000-03-07 21:10:20 +03:00
enum_all_printers_info_1_local .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enum_all_printers_info_1_local ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
2000-03-07 21:10:20 +03:00
DEBUG ( 4 , ( " enum_all_printers_info_1_local \n " ) ) ;
2000-02-15 21:07:45 +03:00
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_1 ( PRINTER_ENUM_ICON8 , buffer , offered , needed , returned ) ;
2000-03-07 21:10:20 +03:00
}
/********************************************************************
enum_all_printers_info_1_name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enum_all_printers_info_1_name ( fstring name , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-03-07 21:10:20 +03:00
{
2001-11-29 00:51:11 +03:00
char * s = name ;
2000-03-07 21:10:20 +03:00
DEBUG ( 4 , ( " enum_all_printers_info_1_name \n " ) ) ;
2000-02-15 21:07:45 +03:00
2001-11-29 00:51:11 +03:00
if ( ( name [ 0 ] = = ' \\ ' ) & & ( name [ 1 ] = = ' \\ ' ) )
s = name + 2 ;
2002-02-09 07:10:24 +03:00
2001-11-29 00:51:11 +03:00
if ( is_myname_or_ipaddr ( s ) ) {
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_1 ( PRINTER_ENUM_ICON8 , buffer , offered , needed , returned ) ;
2000-02-07 19:17:59 +03:00
}
2000-03-07 21:10:20 +03:00
else
2001-09-03 12:50:59 +04:00
return WERR_INVALID_NAME ;
2000-03-07 21:10:20 +03:00
}
/********************************************************************
enum_all_printers_info_1_remote .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enum_all_printers_info_1_remote ( fstring name , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-03-07 21:10:20 +03:00
{
PRINTER_INFO_1 * printer ;
fstring printername ;
fstring desc ;
fstring comment ;
DEBUG ( 4 , ( " enum_all_printers_info_1_remote \n " ) ) ;
/* JFM: currently it's more a place holder than anything else.
* In the spooler world there is a notion of server registration .
* the print servers are registring ( sp ? ) on the PDC ( in the same domain )
2000-11-18 02:10:56 +03:00
*
2000-03-07 21:10:20 +03:00
* We should have a TDB here . The registration is done thru an undocumented RPC call .
*/
2000-04-07 02:48:53 +04:00
if ( ( printer = ( PRINTER_INFO_1 * ) malloc ( sizeof ( PRINTER_INFO_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-03-07 21:10:20 +03:00
* returned = 1 ;
2002-01-08 03:46:56 +03:00
slprintf ( printername , sizeof ( printername ) - 1 , " Windows NT Remote Printers!! \\ \\ %s " , get_called_name ( ) ) ;
slprintf ( desc , sizeof ( desc ) - 1 , " %s " , get_called_name ( ) ) ;
2001-02-16 22:21:18 +03:00
slprintf ( comment , sizeof ( comment ) - 1 , " Logged on Domain " ) ;
2000-03-07 21:10:20 +03:00
init_unistr ( & printer - > description , desc ) ;
init_unistr ( & printer - > name , printername ) ;
init_unistr ( & printer - > comment , comment ) ;
printer - > flags = PRINTER_ENUM_ICON3 | PRINTER_ENUM_CONTAINER ;
2000-02-15 21:07:45 +03:00
/* check the required size. */
2000-03-07 21:10:20 +03:00
* needed + = spoolss_size_printer_info_1 ( printer ) ;
2000-02-15 21:07:45 +03:00
2000-03-10 20:12:24 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printer ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_info_1 ( " " , buffer , printer , 0 ) ;
2000-02-15 21:07:45 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printer ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
else
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-03-07 21:10:20 +03:00
/********************************************************************
enum_all_printers_info_1_network .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2002-07-15 14:35:28 +04:00
static WERROR enum_all_printers_info_1_network ( fstring name , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-03-07 21:10:20 +03:00
{
2002-07-15 14:35:28 +04:00
char * s = name ;
2000-03-07 21:10:20 +03:00
DEBUG ( 4 , ( " enum_all_printers_info_1_network \n " ) ) ;
2002-07-15 14:35:28 +04:00
/* If we respond to a enum_printers level 1 on our name with flags
set to PRINTER_ENUM_REMOTE with a list of printers then these
printers incorrectly appear in the APW browse list .
Specifically the printers for the server appear at the workgroup
level where all the other servers in the domain are
listed . Windows responds to this call with a
WERR_CAN_NOT_COMPLETE so we should do the same . */
if ( name [ 0 ] = = ' \\ ' & & name [ 1 ] = = ' \\ ' )
s = name + 2 ;
if ( is_myname_or_ipaddr ( s ) )
return WERR_CAN_NOT_COMPLETE ;
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_1 ( PRINTER_ENUM_UNKNOWN_8 , buffer , offered , needed , returned ) ;
2000-03-07 21:10:20 +03:00
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* api_spoolss_enumprinters
*
* called from api_spoolss_enumprinters ( see this to understand )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enum_all_printers_info_2 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
int snum ;
2000-02-15 21:07:45 +03:00
int i ;
2000-02-07 19:17:59 +03:00
int n_services = lp_numservices ( ) ;
2001-08-12 21:30:01 +04:00
PRINTER_INFO_2 * tp , * printers = NULL ;
2000-03-10 20:12:24 +03:00
PRINTER_INFO_2 current_prt ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
for ( snum = 0 ; snum < n_services ; snum + + ) {
if ( lp_browseable ( snum ) & & lp_snum_ok ( snum ) & & lp_print_ok ( snum ) ) {
DEBUG ( 4 , ( " Found a printer in smb.conf: %s[%x] \n " , lp_servicename ( snum ) , snum ) ) ;
2000-03-10 20:12:24 +03:00
2000-11-10 22:36:34 +03:00
if ( construct_printer_info_2 ( & current_prt , snum ) ) {
2001-08-12 21:30:01 +04:00
if ( ( tp = Realloc ( printers , ( * returned + 1 ) * sizeof ( PRINTER_INFO_2 ) ) ) = = NULL ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " enum_all_printers_info_2: failed to enlarge printers buffer! \n " ) ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printers ) ;
2001-08-12 21:30:01 +04:00
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2001-08-12 21:30:01 +04:00
}
else printers = tp ;
2000-03-10 20:12:24 +03:00
DEBUG ( 4 , ( " ReAlloced memory for [%d] PRINTER_INFO_2 \n " , * returned ) ) ;
2000-06-29 04:52:40 +04:00
memcpy ( & printers [ * returned ] , & current_prt , sizeof ( PRINTER_INFO_2 ) ) ;
2000-02-15 21:07:45 +03:00
( * returned ) + + ;
2000-03-10 20:12:24 +03:00
}
2000-02-07 19:17:59 +03:00
}
}
2000-02-15 21:07:45 +03:00
/* check the required size. */
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < * returned ; i + + )
2000-06-02 23:42:11 +04:00
( * needed ) + = spoolss_size_printer_info_2 ( & printers [ i ] ) ;
2002-07-15 14:35:28 +04:00
2000-03-29 16:36:44 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
for ( i = 0 ; i < * returned ; i + + ) {
2000-06-02 23:42:11 +04:00
free_devmode ( printers [ i ] . devmode ) ;
2000-03-29 16:36:44 +04:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printers ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-29 16:36:44 +04:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the structures */
for ( i = 0 ; i < * returned ; i + + )
2001-03-28 20:08:00 +04:00
smb_io_printer_info_2 ( " " , buffer , & ( printers [ i ] ) , 0 ) ;
2000-02-15 21:07:45 +03:00
/* clear memory */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-06-03 00:08:28 +04:00
free_devmode ( printers [ i ] . devmode ) ;
2000-03-29 16:36:44 +04:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printers ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
else
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/********************************************************************
* handle enumeration of printers at level 1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enumprinters_level1 ( uint32 flags , fstring name ,
2000-02-15 21:07:45 +03:00
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
2000-03-07 21:10:20 +03:00
/* Not all the flags are equals */
if ( flags & PRINTER_ENUM_LOCAL )
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_1_local ( buffer , offered , needed , returned ) ;
2000-03-07 21:10:20 +03:00
if ( flags & PRINTER_ENUM_NAME )
return enum_all_printers_info_1_name ( name , buffer , offered , needed , returned ) ;
if ( flags & PRINTER_ENUM_REMOTE )
return enum_all_printers_info_1_remote ( name , buffer , offered , needed , returned ) ;
if ( flags & PRINTER_ENUM_NETWORK )
2002-07-15 14:35:28 +04:00
return enum_all_printers_info_1_network ( name , buffer , offered , needed , returned ) ;
2000-02-15 21:07:45 +03:00
2001-09-03 12:50:59 +04:00
return WERR_OK ; /* NT4sp5 does that */
2000-02-15 21:07:45 +03:00
}
/********************************************************************
* handle enumeration of printers at level 2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enumprinters_level2 ( uint32 flags , fstring servername ,
2000-02-15 21:07:45 +03:00
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
2001-11-29 00:51:11 +03:00
char * s = servername ;
2000-03-10 20:12:24 +03:00
if ( flags & PRINTER_ENUM_LOCAL ) {
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_2 ( buffer , offered , needed , returned ) ;
2000-03-10 20:12:24 +03:00
}
if ( flags & PRINTER_ENUM_NAME ) {
2001-11-29 00:51:11 +03:00
if ( ( servername [ 0 ] = = ' \\ ' ) & & ( servername [ 1 ] = = ' \\ ' ) )
s = servername + 2 ;
if ( is_myname_or_ipaddr ( s ) )
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_2 ( buffer , offered , needed , returned ) ;
2000-03-10 20:12:24 +03:00
else
2001-09-03 12:50:59 +04:00
return WERR_INVALID_NAME ;
2000-03-10 20:12:24 +03:00
}
if ( flags & PRINTER_ENUM_REMOTE )
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-03-10 20:12:24 +03:00
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/********************************************************************
* handle enumeration of printers at level 5
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR enumprinters_level5 ( uint32 flags , fstring servername ,
2000-02-15 21:07:45 +03:00
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* api_spoolss_enumprinters
*
* called from api_spoolss_enumprinters ( see this to understand )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-09-03 12:50:59 +04:00
WERROR _spoolss_enumprinters ( pipes_struct * p , SPOOL_Q_ENUMPRINTERS * q_u , SPOOL_R_ENUMPRINTERS * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 04:24:55 +03:00
uint32 flags = q_u - > flags ;
UNISTR2 * servername = & q_u - > servername ;
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * returned = & r_u - > returned ;
2001-11-22 08:56:09 +03:00
2000-02-15 21:07:45 +03:00
fstring name ;
2001-02-28 04:24:55 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-02-28 04:24:55 +03:00
buffer = r_u - > buffer ;
2000-02-15 21:07:45 +03:00
DEBUG ( 4 , ( " _spoolss_enumprinters \n " ) ) ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
* needed = 0 ;
* returned = 0 ;
/*
2000-11-18 02:10:56 +03:00
* Level 1 :
2000-02-15 21:07:45 +03:00
* 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
*/
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
unistr2_to_ascii ( name , servername , sizeof ( name ) - 1 ) ;
2000-03-13 14:09:20 +03:00
strupper ( name ) ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
switch ( level ) {
case 1 :
return enumprinters_level1 ( flags , name , buffer , offered , needed , returned ) ;
case 2 :
return enumprinters_level2 ( flags , name , buffer , offered , needed , returned ) ;
case 5 :
return enumprinters_level5 ( flags , name , buffer , offered , needed , returned ) ;
case 3 :
case 4 :
2001-09-04 15:18:50 +04:00
break ;
2000-02-15 21:07:45 +03:00
}
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinter_level_0 ( int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-07 19:17:59 +03:00
{
2000-02-21 04:58:13 +03:00
PRINTER_INFO_0 * printer = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( printer = ( PRINTER_INFO_0 * ) malloc ( sizeof ( PRINTER_INFO_0 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-03-10 20:12:24 +03:00
2000-11-10 22:36:34 +03:00
construct_printer_info_0 ( printer , snum ) ;
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
/* check the required size. */
* needed + = spoolss_size_printer_info_0 ( printer ) ;
2000-02-07 19:17:59 +03:00
2000-03-10 20:12:24 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printer ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_info_0 ( " " , buffer , printer , 0 ) ;
2000-02-21 04:58:13 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printer ) ;
2000-02-21 04:58:13 +03:00
if ( * needed > offered ) {
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-07 19:17:59 +03:00
}
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-21 04:58:13 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinter_level_1 ( int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
PRINTER_INFO_1 * printer = NULL ;
2000-02-07 19:17:59 +03:00
2000-04-07 02:48:53 +04:00
if ( ( printer = ( PRINTER_INFO_1 * ) malloc ( sizeof ( PRINTER_INFO_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
2002-03-14 04:48:59 +03:00
construct_printer_info_1 ( PRINTER_ENUM_ICON8 , printer , snum ) ;
2000-02-21 04:58:13 +03:00
/* check the required size. */
* needed + = spoolss_size_printer_info_1 ( printer ) ;
2000-02-07 19:17:59 +03:00
2000-03-10 20:12:24 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printer ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_info_1 ( " " , buffer , printer , 0 ) ;
2000-02-21 04:58:13 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( printer ) ;
2000-02-21 04:58:13 +03:00
if ( * needed > offered ) {
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-07 19:17:59 +03:00
}
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-21 04:58:13 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinter_level_2 ( int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
PRINTER_INFO_2 * printer = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( printer = ( PRINTER_INFO_2 * ) malloc ( sizeof ( PRINTER_INFO_2 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-03-10 20:12:24 +03:00
2000-11-10 22:36:34 +03:00
construct_printer_info_2 ( printer , snum ) ;
2000-02-21 04:58:13 +03:00
/* check the required size. */
* needed + = spoolss_size_printer_info_2 ( printer ) ;
2002-07-15 14:35:28 +04:00
2000-03-10 20:12:24 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2000-06-02 23:42:11 +04:00
free_printer_info_2 ( printer ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
if ( ! smb_io_printer_info_2 ( " " , buffer , printer , 0 ) ) {
2000-06-03 01:16:39 +04:00
free_printer_info_2 ( printer ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-06-03 01:16:39 +04:00
}
2000-02-21 04:58:13 +03:00
/* clear memory */
2000-06-02 23:42:11 +04:00
free_printer_info_2 ( printer ) ;
2000-02-21 04:58:13 +03:00
if ( * needed > offered ) {
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-21 04:58:13 +03:00
}
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-05-27 05:26:34 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinter_level_3 ( int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-05-27 05:26:34 +04:00
{
PRINTER_INFO_3 * printer = NULL ;
2000-11-10 22:36:34 +03:00
if ( ! construct_printer_info_3 ( & printer , snum ) )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-05-27 05:26:34 +04:00
/* check the required size. */
* needed + = spoolss_size_printer_info_3 ( printer ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2000-06-03 00:08:28 +04:00
free_printer_info_3 ( printer ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-05-27 05:26:34 +04:00
}
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_info_3 ( " " , buffer , printer , 0 ) ;
2000-05-27 05:26:34 +04:00
/* clear memory */
2000-06-03 00:08:28 +04:00
free_printer_info_3 ( printer ) ;
2000-05-27 05:26:34 +04:00
if ( * needed > offered ) {
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-05-27 05:26:34 +04:00
}
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-05-27 05:26:34 +04:00
}
2002-01-12 05:37:54 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-01-12 05:37:54 +03:00
static WERROR getprinter_level_4 ( int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
PRINTER_INFO_4 * printer = NULL ;
if ( ( printer = ( PRINTER_INFO_4 * ) malloc ( sizeof ( PRINTER_INFO_4 ) ) ) = = NULL )
return WERR_NOMEM ;
if ( ! construct_printer_info_4 ( printer , snum ) )
return WERR_NOMEM ;
/* check the required size. */
* needed + = spoolss_size_printer_info_4 ( printer ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
free_printer_info_4 ( printer ) ;
return WERR_INSUFFICIENT_BUFFER ;
}
/* fill the buffer with the structures */
smb_io_printer_info_4 ( " " , buffer , printer , 0 ) ;
/* clear memory */
free_printer_info_4 ( printer ) ;
if ( * needed > offered ) {
return WERR_INSUFFICIENT_BUFFER ;
}
return WERR_OK ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-01-12 05:37:54 +03:00
static WERROR getprinter_level_5 ( int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
PRINTER_INFO_5 * printer = NULL ;
if ( ( printer = ( PRINTER_INFO_5 * ) malloc ( sizeof ( PRINTER_INFO_5 ) ) ) = = NULL )
return WERR_NOMEM ;
if ( ! construct_printer_info_5 ( printer , snum ) )
return WERR_NOMEM ;
/* check the required size. */
* needed + = spoolss_size_printer_info_5 ( printer ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
free_printer_info_5 ( printer ) ;
return WERR_INSUFFICIENT_BUFFER ;
}
/* fill the buffer with the structures */
smb_io_printer_info_5 ( " " , buffer , printer , 0 ) ;
/* clear memory */
free_printer_info_5 ( printer ) ;
if ( * needed > offered ) {
return WERR_INSUFFICIENT_BUFFER ;
}
return WERR_OK ;
}
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:38:12 +03:00
2001-09-03 12:50:59 +04:00
WERROR _spoolss_getprinter ( pipes_struct * p , SPOOL_Q_GETPRINTER * q_u , SPOOL_R_GETPRINTER * r_u )
2000-02-21 04:58:13 +03:00
{
2001-02-28 04:38:12 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
2000-02-21 04:58:13 +03:00
int snum ;
2001-02-28 04:38:12 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-02-28 04:38:12 +03:00
buffer = r_u - > buffer ;
2000-02-21 04:58:13 +03:00
* needed = 0 ;
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 12:50:59 +04:00
return WERR_BADFID ;
2000-02-21 04:58:13 +03:00
switch ( level ) {
case 0 :
2000-11-10 22:36:34 +03:00
return getprinter_level_0 ( snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
case 1 :
2000-11-10 22:36:34 +03:00
return getprinter_level_1 ( snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
case 2 :
2000-11-10 22:36:34 +03:00
return getprinter_level_2 ( snum , buffer , offered , needed ) ;
2000-05-27 05:26:34 +04:00
case 3 :
2000-11-10 22:36:34 +03:00
return getprinter_level_3 ( snum , buffer , offered , needed ) ;
2002-01-12 05:37:54 +03:00
case 4 :
return getprinter_level_4 ( snum , buffer , offered , needed ) ;
case 5 :
return getprinter_level_5 ( snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
}
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-21 04:58:13 +03:00
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-07-25 17:15:16 +04:00
* fill a DRIVER_INFO_1 struct
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-07-25 17:15:16 +04:00
static void fill_printer_driver_info_1 ( DRIVER_INFO_1 * info , NT_PRINTER_DRIVER_INFO_LEVEL driver , fstring servername , fstring architecture )
2000-02-07 19:17:59 +03:00
{
2000-07-27 04:47:19 +04:00
init_unistr ( & info - > name , driver . info_3 - > name ) ;
2000-02-07 19:17:59 +03:00
}
2000-07-25 17:15:16 +04:00
/********************************************************************
* construct_printer_driver_info_1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR construct_printer_driver_info_1 ( DRIVER_INFO_1 * info , int snum , fstring servername , fstring architecture , uint32 version )
2000-02-07 19:17:59 +03:00
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-07 19:17:59 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2000-05-12 18:28:46 +04:00
ZERO_STRUCT ( driver ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
return WERR_INVALID_PRINTER_NAME ;
2000-07-25 17:15:16 +04:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ) )
return WERR_UNKNOWN_PRINTER_DRIVER ;
2000-07-25 17:15:16 +04:00
2000-02-07 19:17:59 +03:00
fill_printer_driver_info_1 ( info , driver , servername , architecture ) ;
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-07-25 17:15:16 +04:00
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_driver_info_2
* fill a printer_info_2 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-07-25 17:15:16 +04:00
static void fill_printer_driver_info_2 ( DRIVER_INFO_2 * info , NT_PRINTER_DRIVER_INFO_LEVEL driver , fstring servername )
2000-02-07 19:17:59 +03:00
{
2001-01-11 23:41:19 +03:00
pstring temp ;
2000-02-07 19:17:59 +03:00
info - > version = driver . info_3 - > cversion ;
2000-07-25 17:15:16 +04:00
init_unistr ( & info - > name , driver . info_3 - > name ) ;
init_unistr ( & info - > architecture , driver . info_3 - > environment ) ;
2000-02-07 19:17:59 +03:00
2000-07-25 17:15:16 +04:00
2001-01-11 23:41:19 +03:00
if ( strlen ( driver . info_3 - > driverpath ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > driverpath ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > driverpath , temp ) ;
} else
init_unistr ( & info - > driverpath , " " ) ;
2000-02-07 19:17:59 +03:00
2001-01-11 23:41:19 +03:00
if ( strlen ( driver . info_3 - > datafile ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > datafile ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > datafile , temp ) ;
} else
init_unistr ( & info - > datafile , " " ) ;
if ( strlen ( driver . info_3 - > configfile ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > configfile ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > configfile , temp ) ;
} else
init_unistr ( & info - > configfile , " " ) ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_driver_info_2
* fill a printer_info_2 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR construct_printer_driver_info_2 ( DRIVER_INFO_2 * info , int snum , fstring servername , fstring architecture , uint32 version )
2000-02-07 19:17:59 +03:00
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-07 19:17:59 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2000-05-12 18:28:46 +04:00
ZERO_STRUCT ( printer ) ;
ZERO_STRUCT ( driver ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
return WERR_INVALID_PRINTER_NAME ;
2000-07-25 17:15:16 +04:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ) )
return WERR_UNKNOWN_PRINTER_DRIVER ;
2000-02-07 19:17:59 +03:00
2000-07-25 17:15:16 +04:00
fill_printer_driver_info_2 ( info , driver , servername ) ;
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-07-25 17:15:16 +04:00
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* copy a strings array and convert to UNICODE
2000-03-29 16:36:44 +04:00
*
* convert an array of ascii string to a UNICODE string
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-09-25 19:19:00 +04:00
static uint32 init_unistr_array ( uint16 * * uni_array , fstring * char_array , char * servername )
2000-02-07 19:17:59 +03:00
{
int i = 0 ;
2000-03-29 16:36:44 +04:00
int j = 0 ;
2000-02-07 19:17:59 +03:00
char * v ;
pstring line ;
2001-08-12 21:30:01 +04:00
uint16 * tuary ;
2000-02-07 19:17:59 +03:00
DEBUG ( 6 , ( " init_unistr_array \n " ) ) ;
2000-03-29 16:36:44 +04:00
* uni_array = NULL ;
2000-02-07 19:17:59 +03:00
2002-08-17 19:34:15 +04:00
while ( True )
{
2002-09-25 19:19:00 +04:00
if ( ! char_array )
2000-06-03 00:08:28 +04:00
v = " " ;
2002-09-25 19:19:00 +04:00
else
{
2000-06-03 00:08:28 +04:00
v = char_array [ i ] ;
2002-09-25 19:19:00 +04:00
if ( ! v )
v = " " ; /* hack to handle null lists */
2000-06-03 00:08:28 +04:00
}
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
/* hack to allow this to be used in places other than when generating
the list of dependent files */
if ( servername )
slprintf ( line , sizeof ( line ) - 1 , " \\ \\ %s%s " , servername , v ) ;
else
pstrcpy ( line , v ) ;
2002-08-17 19:34:15 +04:00
2000-03-29 16:36:44 +04:00
DEBUGADD ( 6 , ( " %d:%s:%d \n " , i , line , strlen ( line ) ) ) ;
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
if ( ( tuary = Realloc ( * uni_array , ( j + strlen ( line ) + 2 ) * sizeof ( uint16 ) ) ) = = NULL ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " init_unistr_array: Realloc error \n " ) ) ;
2002-09-25 19:19:00 +04:00
return 0 ;
2002-02-09 07:10:24 +03:00
} else
* uni_array = tuary ;
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
if ( ! strlen ( v ) )
break ;
2002-08-17 19:34:15 +04:00
j + = ( rpcstr_push ( ( * uni_array + j ) , line , sizeof ( uint16 ) * strlen ( line ) + 2 , STR_TERMINATE ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
i + + ;
}
2000-05-24 10:34:47 +04:00
if ( * uni_array ) {
( * uni_array ) [ j ] = 0x0000 ;
}
2000-03-29 16:36:44 +04:00
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " last one:done \n " ) ) ;
2002-09-25 19:19:00 +04:00
/* return size of array in uint16's */
return j + 1 ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_info_3
* fill a printer_info_3 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-07-25 17:15:16 +04:00
static void fill_printer_driver_info_3 ( DRIVER_INFO_3 * info , NT_PRINTER_DRIVER_INFO_LEVEL driver , fstring servername )
2000-02-07 19:17:59 +03:00
{
2001-01-11 23:41:19 +03:00
pstring temp ;
2000-05-23 00:04:50 +04:00
2000-09-15 04:15:10 +04:00
ZERO_STRUCTP ( info ) ;
2000-02-07 19:17:59 +03:00
info - > version = driver . info_3 - > cversion ;
2000-07-25 17:15:16 +04:00
init_unistr ( & info - > name , driver . info_3 - > name ) ;
init_unistr ( & info - > architecture , driver . info_3 - > environment ) ;
2002-09-25 19:19:00 +04:00
if ( strlen ( driver . info_3 - > driverpath ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > driverpath ) ;
init_unistr ( & info - > driverpath , temp ) ;
} else
init_unistr ( & info - > driverpath , " " ) ;
2001-01-11 23:41:19 +03:00
2002-09-25 19:19:00 +04:00
if ( strlen ( driver . info_3 - > datafile ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > datafile ) ;
init_unistr ( & info - > datafile , temp ) ;
} else
init_unistr ( & info - > datafile , " " ) ;
2001-01-11 23:41:19 +03:00
2002-09-25 19:19:00 +04:00
if ( strlen ( driver . info_3 - > configfile ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > configfile ) ;
init_unistr ( & info - > configfile , temp ) ;
} else
init_unistr ( & info - > configfile , " " ) ;
2001-01-11 23:41:19 +03:00
2002-09-25 19:19:00 +04:00
if ( strlen ( driver . info_3 - > helpfile ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > helpfile ) ;
init_unistr ( & info - > helpfile , temp ) ;
} else
init_unistr ( & info - > helpfile , " " ) ;
2000-02-07 19:17:59 +03:00
2000-06-27 02:08:20 +04:00
init_unistr ( & info - > monitorname , driver . info_3 - > monitorname ) ;
init_unistr ( & info - > defaultdatatype , driver . info_3 - > defaultdatatype ) ;
2000-02-07 19:17:59 +03:00
info - > dependentfiles = NULL ;
2000-07-25 17:15:16 +04:00
init_unistr_array ( & info - > dependentfiles , driver . info_3 - > dependentfiles , servername ) ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_info_3
* fill a printer_info_3 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR construct_printer_driver_info_3 ( DRIVER_INFO_3 * info , int snum , fstring servername , fstring architecture , uint32 version )
2000-02-07 19:17:59 +03:00
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-07 19:17:59 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2001-09-03 12:50:59 +04:00
WERROR status ;
2000-05-12 18:28:46 +04:00
ZERO_STRUCT ( driver ) ;
2000-07-25 17:15:16 +04:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
2002-03-17 09:04:15 +03:00
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %s \n " , dos_errstr ( status ) ) ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) )
return WERR_INVALID_PRINTER_NAME ;
2000-07-25 17:15:16 +04:00
status = get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ;
2002-03-17 09:04:15 +03:00
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %s \n " , dos_errstr ( status ) ) ) ;
2002-02-09 07:10:24 +03:00
#if 0 /* JERRY */
/*
* I put this code in during testing . Helpful when commenting out the
* support for DRIVER_INFO_6 in regards to win2k . Not needed in general
* as win2k always queries the driver using an infor level of 6.
* I ' ve left it in ( but ifdef ' d out ) because I ' ll probably
* use it in experimentation again in the future . - - jerry 22 / 01 / 2002
*/
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2002-02-09 07:10:24 +03:00
/*
* Is this a W2k client ?
*/
if ( version = = 3 ) {
/* Yes - try again with a WinNT driver. */
version = 2 ;
status = get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ;
2002-03-17 09:04:15 +03:00
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %s \n " , dos_errstr ( status ) ) ) ;
2002-02-09 07:10:24 +03:00
}
# endif
if ( ! W_ERROR_IS_OK ( status ) ) {
free_a_printer ( & printer , 2 ) ;
return WERR_UNKNOWN_PRINTER_DRIVER ;
}
#if 0 /* JERRY */
2000-07-26 02:35:57 +04:00
}
2002-02-09 07:10:24 +03:00
# endif
2000-02-07 19:17:59 +03:00
2000-07-25 17:15:16 +04:00
fill_printer_driver_info_3 ( info , driver , servername ) ;
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-07-25 17:15:16 +04:00
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-09-15 04:15:10 +04:00
/********************************************************************
* construct_printer_info_6
* fill a printer_info_6 struct - we know that driver is really level 3. This sucks . JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void fill_printer_driver_info_6 ( DRIVER_INFO_6 * info , NT_PRINTER_DRIVER_INFO_LEVEL driver , fstring servername )
{
2001-01-11 23:41:19 +03:00
pstring temp ;
2000-09-15 04:15:10 +04:00
fstring nullstr ;
ZERO_STRUCTP ( info ) ;
memset ( & nullstr , ' \0 ' , sizeof ( fstring ) ) ;
info - > version = driver . info_3 - > cversion ;
init_unistr ( & info - > name , driver . info_3 - > name ) ;
init_unistr ( & info - > architecture , driver . info_3 - > environment ) ;
2001-01-11 23:41:19 +03:00
if ( strlen ( driver . info_3 - > driverpath ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > driverpath ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > driverpath , temp ) ;
} else
init_unistr ( & info - > driverpath , " " ) ;
if ( strlen ( driver . info_3 - > datafile ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > datafile ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > datafile , temp ) ;
} else
init_unistr ( & info - > datafile , " " ) ;
if ( strlen ( driver . info_3 - > configfile ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > configfile ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > configfile , temp ) ;
} else
init_unistr ( & info - > configfile , " " ) ;
if ( strlen ( driver . info_3 - > helpfile ) ) {
2001-02-16 22:21:18 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > helpfile ) ;
2001-01-11 23:41:19 +03:00
init_unistr ( & info - > helpfile , temp ) ;
} else
init_unistr ( & info - > helpfile , " " ) ;
2000-09-15 04:15:10 +04:00
init_unistr ( & info - > monitorname , driver . info_3 - > monitorname ) ;
init_unistr ( & info - > defaultdatatype , driver . info_3 - > defaultdatatype ) ;
2002-08-17 19:34:15 +04:00
info - > dependentfiles = NULL ;
init_unistr_array ( & info - > dependentfiles , driver . info_3 - > dependentfiles , servername ) ;
2000-09-15 04:15:10 +04:00
info - > previousdrivernames = NULL ;
init_unistr_array ( & info - > previousdrivernames , & nullstr , servername ) ;
2000-09-16 14:07:46 +04:00
info - > driver_date . low = 0 ;
info - > driver_date . high = 0 ;
info - > padding = 0 ;
info - > driver_version_low = 0 ;
info - > driver_version_high = 0 ;
2000-09-15 04:15:10 +04:00
init_unistr ( & info - > mfgname , " " ) ;
init_unistr ( & info - > oem_url , " " ) ;
init_unistr ( & info - > hardware_id , " " ) ;
init_unistr ( & info - > provider , " " ) ;
}
/********************************************************************
* construct_printer_info_6
* fill a printer_info_6 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2002-08-17 19:34:15 +04:00
static WERROR construct_printer_driver_info_6 ( DRIVER_INFO_6 * info , int snum ,
fstring servername , fstring architecture , uint32 version )
2000-09-15 04:15:10 +04:00
{
2002-08-17 19:34:15 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
WERROR status ;
2000-09-15 04:15:10 +04:00
ZERO_STRUCT ( driver ) ;
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
2002-08-17 19:34:15 +04:00
2002-03-17 09:04:15 +03:00
DEBUG ( 8 , ( " construct_printer_driver_info_6: status: %s \n " , dos_errstr ( status ) ) ) ;
2002-08-17 19:34:15 +04:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) )
return WERR_INVALID_PRINTER_NAME ;
2000-09-15 04:15:10 +04:00
2002-08-17 19:34:15 +04:00
status = get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ;
2002-03-17 09:04:15 +03:00
DEBUG ( 8 , ( " construct_printer_driver_info_6: status: %s \n " , dos_errstr ( status ) ) ) ;
2002-08-17 19:34:15 +04:00
if ( ! W_ERROR_IS_OK ( status ) )
{
2000-11-10 22:36:34 +03:00
/*
* Is this a W2k client ?
*/
if ( version < 3 ) {
free_a_printer ( & printer , 2 ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_PRINTER_DRIVER ;
2000-11-10 22:36:34 +03:00
}
/* Yes - try again with a WinNT driver. */
version = 2 ;
status = get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ;
2002-03-17 09:04:15 +03:00
DEBUG ( 8 , ( " construct_printer_driver_info_6: status: %s \n " , dos_errstr ( status ) ) ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2000-11-10 22:36:34 +03:00
free_a_printer ( & printer , 2 ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_PRINTER_DRIVER ;
2000-11-10 22:36:34 +03:00
}
2000-09-15 04:15:10 +04:00
}
fill_printer_driver_info_6 ( info , driver , servername ) ;
free_a_printer ( & printer , 2 ) ;
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-09-15 04:15:10 +04:00
}
2000-06-03 00:08:28 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_printer_driver_info_3 ( DRIVER_INFO_3 * info )
{
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info - > dependentfiles ) ;
2000-06-03 00:08:28 +04:00
}
2000-09-15 04:15:10 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_printer_driver_info_6 ( DRIVER_INFO_6 * info )
{
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info - > dependentfiles ) ;
2000-09-15 04:15:10 +04:00
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinterdriver2_level1 ( fstring servername , fstring architecture , uint32 version , int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
DRIVER_INFO_1 * info = NULL ;
2001-09-03 12:50:59 +04:00
WERROR status ;
2000-02-21 04:58:13 +03:00
2000-04-07 02:48:53 +04:00
if ( ( info = ( DRIVER_INFO_1 * ) malloc ( sizeof ( DRIVER_INFO_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-02-21 04:58:13 +03:00
2000-07-25 17:15:16 +04:00
status = construct_printer_driver_info_1 ( info , snum , servername , architecture , version ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-07-25 17:15:16 +04:00
return status ;
}
2000-02-21 04:58:13 +03:00
/* check the required size. */
* needed + = spoolss_size_printer_driver_info_1 ( info ) ;
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_1 ( " " , buffer , info , 0 ) ;
2000-02-21 04:58:13 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-02-21 04:58:13 +03:00
2000-03-13 14:09:20 +03:00
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
return WERR_OK ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinterdriver2_level2 ( fstring servername , fstring architecture , uint32 version , int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
DRIVER_INFO_2 * info = NULL ;
2001-09-03 12:50:59 +04:00
WERROR status ;
2000-02-21 04:58:13 +03:00
2000-04-07 02:48:53 +04:00
if ( ( info = ( DRIVER_INFO_2 * ) malloc ( sizeof ( DRIVER_INFO_2 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-02-21 04:58:13 +03:00
2000-07-25 17:15:16 +04:00
status = construct_printer_driver_info_2 ( info , snum , servername , architecture , version ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-07-25 17:15:16 +04:00
return status ;
}
2000-02-21 04:58:13 +03:00
/* check the required size. */
* needed + = spoolss_size_printer_driver_info_2 ( info ) ;
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_2 ( " " , buffer , info , 0 ) ;
2000-02-21 04:58:13 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-02-21 04:58:13 +03:00
2000-03-13 14:09:20 +03:00
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
return WERR_OK ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinterdriver2_level3 ( fstring servername , fstring architecture , uint32 version , int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
2000-05-24 10:34:47 +04:00
DRIVER_INFO_3 info ;
2001-09-03 12:50:59 +04:00
WERROR status ;
2000-05-24 10:34:47 +04:00
ZERO_STRUCT ( info ) ;
2000-07-25 17:15:16 +04:00
status = construct_printer_driver_info_3 ( & info , snum , servername , architecture , version ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2000-07-25 17:15:16 +04:00
return status ;
}
2000-02-21 04:58:13 +03:00
/* check the required size. */
2000-05-24 10:34:47 +04:00
* needed + = spoolss_size_printer_driver_info_3 ( & info ) ;
2000-02-21 04:58:13 +03:00
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2000-06-03 00:08:28 +04:00
free_printer_driver_info_3 ( & info ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_3 ( " " , buffer , & info , 0 ) ;
2000-02-21 04:58:13 +03:00
2000-06-03 00:08:28 +04:00
free_printer_driver_info_3 ( & info ) ;
2000-03-13 14:09:20 +03:00
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
return WERR_OK ;
2000-02-21 04:58:13 +03:00
}
2000-09-15 04:15:10 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 12:50:59 +04:00
static WERROR getprinterdriver2_level6 ( fstring servername , fstring architecture , uint32 version , int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-09-15 04:15:10 +04:00
{
DRIVER_INFO_6 info ;
2001-09-03 12:50:59 +04:00
WERROR status ;
2000-09-15 04:15:10 +04:00
ZERO_STRUCT ( info ) ;
status = construct_printer_driver_info_6 ( & info , snum , servername , architecture , version ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
2000-09-15 04:15:10 +04:00
return status ;
}
/* check the required size. */
* needed + = spoolss_size_printer_driver_info_6 ( & info ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2000-10-03 22:29:12 +04:00
free_printer_driver_info_6 ( & info ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-09-15 04:15:10 +04:00
}
/* fill the buffer with the structures */
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_6 ( " " , buffer , & info , 0 ) ;
2000-09-15 04:15:10 +04:00
free_printer_driver_info_6 ( & info ) ;
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
return WERR_OK ;
2000-09-15 04:15:10 +04:00
}
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:03:02 +03:00
2001-09-03 12:50:59 +04:00
WERROR _spoolss_getprinterdriver2 ( pipes_struct * p , SPOOL_Q_GETPRINTERDRIVER2 * q_u , SPOOL_R_GETPRINTERDRIVER2 * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:03:02 +03:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * uni_arch = & q_u - > architecture ;
uint32 level = q_u - > level ;
uint32 clientmajorversion = q_u - > clientmajorversion ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * servermajorversion = & r_u - > servermajorversion ;
uint32 * serverminorversion = & r_u - > serverminorversion ;
2000-04-23 18:25:36 +04:00
fstring servername ;
2000-02-07 19:17:59 +03:00
fstring architecture ;
int snum ;
2000-02-21 04:58:13 +03:00
2001-02-28 05:03:02 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-02-28 05:03:02 +03:00
buffer = r_u - > buffer ;
2000-02-21 04:58:13 +03:00
DEBUG ( 4 , ( " _spoolss_getprinterdriver2 \n " ) ) ;
2002-08-17 19:34:15 +04:00
* needed = 0 ;
* servermajorversion = 0 ;
* serverminorversion = 0 ;
2000-02-07 19:17:59 +03:00
2002-01-08 03:46:56 +03:00
pstrcpy ( servername , get_called_name ( ) ) ;
2000-02-21 04:58:13 +03:00
unistr2_to_ascii ( architecture , uni_arch , sizeof ( architecture ) - 1 ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 12:50:59 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
switch ( level ) {
case 1 :
2000-07-25 17:15:16 +04:00
return getprinterdriver2_level1 ( servername , architecture , clientmajorversion , snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
case 2 :
2000-07-25 17:15:16 +04:00
return getprinterdriver2_level2 ( servername , architecture , clientmajorversion , snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
case 3 :
2000-07-25 17:15:16 +04:00
return getprinterdriver2_level3 ( servername , architecture , clientmajorversion , snum , buffer , offered , needed ) ;
2000-09-15 04:15:10 +04:00
case 6 :
return getprinterdriver2_level6 ( servername , architecture , clientmajorversion , snum , buffer , offered , needed ) ;
2000-02-07 19:17:59 +03:00
}
2001-11-22 08:56:09 +03:00
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:03:02 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_startpageprinter ( pipes_struct * p , SPOOL_Q_STARTPAGEPRINTER * q_u , SPOOL_R_STARTPAGEPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:03:02 +03:00
POLICY_HND * handle = & q_u - > handle ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
2002-01-23 14:47:19 +03:00
if ( ! Printer ) {
DEBUG ( 3 , ( " Error in startpageprinter printer handle \n " ) ) ;
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2002-01-23 14:47:19 +03:00
Printer - > page_started = True ;
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:03:02 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_endpageprinter ( pipes_struct * p , SPOOL_Q_ENDPAGEPRINTER * q_u , SPOOL_R_ENDPAGEPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:03:02 +03:00
POLICY_HND * handle = & q_u - > handle ;
2002-08-17 19:34:15 +04:00
int snum ;
2001-02-28 05:03:02 +03:00
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_endpageprinter: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2000-02-25 02:01:24 +03:00
2002-08-17 19:34:15 +04:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
2000-02-25 02:01:24 +03:00
Printer - > page_started = False ;
2002-08-17 19:34:15 +04:00
print_job_endpage ( snum , Printer - > jobid ) ;
2000-02-07 19:17:59 +03:00
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:03:02 +03:00
2001-09-03 12:50:59 +04:00
WERROR _spoolss_startdocprinter ( pipes_struct * p , SPOOL_Q_STARTDOCPRINTER * q_u , SPOOL_R_STARTDOCPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:03:02 +03:00
POLICY_HND * handle = & q_u - > handle ;
DOC_INFO * docinfo = & q_u - > doc_info_container . docinfo ;
uint32 * jobid = & r_u - > jobid ;
2000-02-07 19:17:59 +03:00
DOC_INFO_1 * info_1 = & docinfo - > doc_info_1 ;
int snum ;
2000-04-16 10:20:43 +04:00
pstring jobname ;
fstring datatype ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-07-06 10:53:47 +04:00
struct current_user user ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_startdocprinter: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 12:50:59 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2000-09-22 01:44:15 +04:00
get_current_user ( & user , p ) ;
2000-07-06 10:53:47 +04:00
2000-02-07 19:17:59 +03:00
/*
* a nice thing with NT is it doesn ' t listen to what you tell it .
* when asked to send _only_ RAW datas , it tries to send datas
* in EMF format .
*
* So I add checks like in NT Server . . .
*/
2000-08-24 03:05:49 +04:00
if ( info_1 - > p_datatype ! = 0 ) {
2000-09-08 06:20:48 +04:00
unistr2_to_ascii ( datatype , & info_1 - > datatype , sizeof ( datatype ) ) ;
2000-08-24 03:05:49 +04:00
if ( strcmp ( datatype , " RAW " ) ! = 0 ) {
2000-02-07 19:17:59 +03:00
( * jobid ) = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INVALID_DATATYPE ;
2000-02-07 19:17:59 +03:00
}
2000-11-18 02:10:56 +03:00
}
2000-02-07 19:17:59 +03:00
/* get the share number of the printer */
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) ) {
2001-09-03 12:50:59 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2000-04-16 10:20:43 +04:00
unistr2_to_ascii ( jobname , & info_1 - > docname , sizeof ( jobname ) ) ;
2000-02-07 19:17:59 +03:00
2002-09-25 19:19:00 +04:00
Printer - > jobid = print_job_start ( & user , snum , jobname , Printer - > nt_devmode ) ;
2000-04-16 10:20:43 +04:00
2000-09-01 22:49:26 +04:00
/* An error occured in print_job_start() so return an appropriate
NT error code . */
2000-04-16 10:20:43 +04:00
if ( Printer - > jobid = = - 1 ) {
2001-09-03 14:38:13 +04:00
return map_werror_from_unix ( errno ) ;
2000-04-16 10:20:43 +04:00
}
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
Printer - > document_started = True ;
2000-04-16 10:20:43 +04:00
( * jobid ) = Printer - > jobid ;
2000-02-07 19:17:59 +03:00
2001-09-03 12:50:59 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_enddocprinter ( pipes_struct * p , SPOOL_Q_ENDDOCPRINTER * q_u , SPOOL_R_ENDDOCPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:38:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
return _spoolss_enddocprinter_internal ( p , handle ) ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_writeprinter ( pipes_struct * p , SPOOL_Q_WRITEPRINTER * q_u , SPOOL_R_WRITEPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:38:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 buffer_size = q_u - > buffer_size ;
uint8 * buffer = q_u - > buffer ;
uint32 * buffer_written = & q_u - > buffer_size2 ;
2002-08-17 19:34:15 +04:00
int snum ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_writeprinter: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-02-28 05:38:09 +03:00
r_u - > buffer_written = q_u - > buffer_size2 ;
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2002-08-17 19:34:15 +04:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
2001-02-28 05:38:09 +03:00
2002-08-17 19:34:15 +04:00
( * buffer_written ) = print_job_write ( snum , Printer - > jobid , ( char * ) buffer , buffer_size ) ;
2002-09-25 19:19:00 +04:00
if ( * buffer_written = = - 1 ) {
r_u - > buffer_written = 0 ;
if ( errno = = ENOSPC )
return WERR_NO_SPOOL_SPACE ;
else
return WERR_ACCESS_DENIED ;
}
2001-02-28 05:38:09 +03:00
r_u - > buffer_written = q_u - > buffer_size2 ;
2000-02-07 19:17:59 +03:00
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR control_printer ( POLICY_HND * handle , uint32 command ,
2000-07-06 10:53:47 +04:00
pipes_struct * p )
2000-02-07 19:17:59 +03:00
{
2000-07-06 10:53:47 +04:00
struct current_user user ;
2001-09-03 14:38:13 +04:00
int snum ;
WERROR errcode = WERR_BADFUNC ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-25 02:01:24 +03:00
2000-09-22 01:44:15 +04:00
get_current_user ( & user , p ) ;
2000-07-06 10:53:47 +04:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " control_printer: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
2000-02-27 01:22:24 +03:00
switch ( command ) {
2000-04-16 10:20:43 +04:00
case PRINTER_CONTROL_PAUSE :
2000-08-30 04:45:59 +04:00
if ( print_queue_pause ( & user , snum , & errcode ) ) {
2001-09-03 14:38:13 +04:00
errcode = WERR_OK ;
2000-04-16 10:20:43 +04:00
}
break ;
case PRINTER_CONTROL_RESUME :
case PRINTER_CONTROL_UNPAUSE :
2000-08-30 04:45:59 +04:00
if ( print_queue_resume ( & user , snum , & errcode ) ) {
2001-09-03 14:38:13 +04:00
errcode = WERR_OK ;
2000-04-16 10:20:43 +04:00
}
break ;
2002-09-25 19:19:00 +04:00
#if 0 /* JERRY - Never called */
2000-04-16 10:20:43 +04:00
case PRINTER_CONTROL_PURGE :
2000-08-30 04:45:59 +04:00
if ( print_queue_purge ( & user , snum , & errcode ) ) {
2001-09-03 14:38:13 +04:00
errcode = WERR_OK ;
2000-04-16 10:20:43 +04:00
}
break ;
2002-09-25 19:19:00 +04:00
# endif
2000-11-08 03:20:26 +03:00
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
2000-11-07 05:54:50 +03:00
return errcode ;
2000-02-07 19:17:59 +03:00
}
2000-08-30 04:45:59 +04:00
/********************************************************************
* api_spoolss_abortprinter
2002-09-25 19:19:00 +04:00
* From MSDN : " Deletes printer's spool file if printer is configured
* for spooling "
2000-08-30 04:45:59 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-03 14:38:13 +04:00
WERROR _spoolss_abortprinter ( pipes_struct * p , SPOOL_Q_ABORTPRINTER * q_u , SPOOL_R_ABORTPRINTER * r_u )
2000-08-30 04:45:59 +04:00
{
2002-09-25 19:19:00 +04:00
POLICY_HND * handle = & q_u - > handle ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
int snum ;
struct current_user user ;
WERROR errcode = WERR_OK ;
if ( ! Printer ) {
DEBUG ( 2 , ( " _spoolss_abortprinter: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
return WERR_BADFID ;
}
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
get_current_user ( & user , p ) ;
print_job_delete ( & user , snum , Printer - > jobid , & errcode ) ;
return errcode ;
2000-08-30 04:45:59 +04:00
}
2000-05-27 13:53:11 +04:00
/********************************************************************
* called by spoolss_api_setprinter
* when updating a printer description
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR update_printer_sec ( POLICY_HND * handle , uint32 level ,
2000-05-27 13:53:11 +04:00
const SPOOL_PRINTER_INFO_LEVEL * info ,
2000-07-10 09:08:21 +04:00
pipes_struct * p , SEC_DESC_BUF * secdesc_ctr )
2000-05-27 13:53:11 +04:00
{
2000-11-07 05:54:50 +03:00
SEC_DESC_BUF * new_secdesc_ctr = NULL , * old_secdesc_ctr = NULL ;
2000-07-10 09:08:21 +04:00
struct current_user user ;
2001-09-03 14:38:13 +04:00
WERROR result ;
2000-08-09 08:19:18 +04:00
int snum ;
2000-07-10 09:08:21 +04:00
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-05-27 13:53:11 +04:00
2001-03-11 03:32:10 +03:00
if ( ! Printer | | ! get_printer_snum ( p , handle , & snum ) ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " update_printer_sec: Invalid handle (%s:%u:%u) \n " ,
2000-11-07 05:54:50 +03:00
OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
result = WERR_BADFID ;
2000-11-07 05:54:50 +03:00
goto done ;
}
/* NT seems to like setting the security descriptor even though
nothing may have actually changed . This causes annoying
dialog boxes when the user doesn ' t have permission to change
the security descriptor . */
2001-02-28 03:51:02 +03:00
nt_printing_getsec ( p - > mem_ctx , Printer - > dev . handlename , & old_secdesc_ctr ) ;
2000-11-07 05:54:50 +03:00
2000-12-11 22:24:59 +03:00
if ( DEBUGLEVEL > = 10 ) {
2001-04-28 01:49:22 +04:00
SEC_ACL * the_acl ;
2000-12-11 22:24:59 +03:00
int i ;
2001-04-28 01:49:22 +04:00
the_acl = old_secdesc_ctr - > sec - > dacl ;
2000-12-11 22:24:59 +03:00
DEBUG ( 10 , ( " old_secdesc_ctr for %s has %d aces: \n " ,
2001-04-28 01:49:22 +04:00
PRINTERNAME ( snum ) , the_acl - > num_aces ) ) ;
2000-12-11 22:24:59 +03:00
2001-04-28 01:49:22 +04:00
for ( i = 0 ; i < the_acl - > num_aces ; i + + ) {
2000-12-11 22:24:59 +03:00
fstring sid_str ;
2001-11-30 04:04:15 +03:00
sid_to_string ( sid_str , & the_acl - > ace [ i ] . trustee ) ;
2000-12-11 22:24:59 +03:00
DEBUG ( 10 , ( " %s 0x%08x \n " , sid_str ,
2001-04-28 01:49:22 +04:00
the_acl - > ace [ i ] . info . mask ) ) ;
2000-12-11 22:24:59 +03:00
}
2001-04-28 01:49:22 +04:00
the_acl = secdesc_ctr - > sec - > dacl ;
2000-12-11 22:24:59 +03:00
2001-04-28 01:49:22 +04:00
if ( the_acl ) {
2000-12-18 09:02:31 +03:00
DEBUG ( 10 , ( " secdesc_ctr for %s has %d aces: \n " ,
2001-04-28 01:49:22 +04:00
PRINTERNAME ( snum ) , the_acl - > num_aces ) ) ;
2000-12-11 22:24:59 +03:00
2001-04-28 01:49:22 +04:00
for ( i = 0 ; i < the_acl - > num_aces ; i + + ) {
2000-12-18 09:02:31 +03:00
fstring sid_str ;
2001-11-30 04:04:15 +03:00
sid_to_string ( sid_str , & the_acl - > ace [ i ] . trustee ) ;
2000-12-18 09:02:31 +03:00
DEBUG ( 10 , ( " %s 0x%08x \n " , sid_str ,
2001-04-28 01:49:22 +04:00
the_acl - > ace [ i ] . info . mask ) ) ;
2000-12-18 09:02:31 +03:00
}
} else {
DEBUG ( 10 , ( " dacl for secdesc_ctr is NULL \n " ) ) ;
2000-12-11 22:24:59 +03:00
}
}
2001-02-28 03:51:02 +03:00
new_secdesc_ctr = sec_desc_merge ( p - > mem_ctx , secdesc_ctr , old_secdesc_ctr ) ;
2000-11-07 05:54:50 +03:00
if ( sec_desc_equal ( new_secdesc_ctr - > sec , old_secdesc_ctr - > sec ) ) {
2001-09-03 14:38:13 +04:00
result = WERR_OK ;
2000-11-07 05:54:50 +03:00
goto done ;
2000-07-07 03:31:46 +04:00
}
2000-05-27 13:53:11 +04:00
2000-07-17 06:38:43 +04:00
/* Work out which user is performing the operation */
2000-11-07 05:54:50 +03:00
2000-09-22 01:44:15 +04:00
get_current_user ( & user , p ) ;
2000-07-10 09:08:21 +04:00
2000-07-17 06:38:43 +04:00
/* Check the user has permissions to change the security
descriptor . By experimentation with two NT machines , the user
requires Full Access to the printer to change security
2000-11-18 02:10:56 +03:00
information . */
2000-11-07 05:54:50 +03:00
2000-09-01 22:49:26 +04:00
if ( ! print_access_check ( & user , snum , PRINTER_ACCESS_ADMINISTER ) ) {
2001-09-03 14:38:13 +04:00
result = WERR_ACCESS_DENIED ;
2000-07-17 09:38:26 +04:00
goto done ;
2000-07-17 06:38:43 +04:00
}
2000-11-07 05:54:50 +03:00
result = nt_printing_setsec ( Printer - > dev . handlename , new_secdesc_ctr ) ;
2000-07-17 09:38:26 +04:00
done :
2000-11-07 05:54:50 +03:00
2000-07-17 09:38:26 +04:00
return result ;
2000-05-27 13:53:11 +04:00
}
2000-07-22 04:48:29 +04:00
/********************************************************************
Do Samba sanity checks on a printer info struct .
2000-11-08 06:12:16 +03:00
this has changed purpose : it now " canonicalises " printer
info from a client rather than just checking it is correct
2000-07-22 04:48:29 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL check_printer_ok ( NT_PRINTER_INFO_LEVEL_2 * info , int snum )
{
2000-11-08 06:12:16 +03:00
DEBUG ( 5 , ( " check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s \n " ,
info - > servername , info - > printername , info - > sharename , info - > portname , info - > drivername , info - > comment , info - > location ) ) ;
2000-07-22 04:48:29 +04:00
2000-11-08 06:12:16 +03:00
/* we force some elements to "correct" values */
2002-01-08 03:46:56 +03:00
slprintf ( info - > servername , sizeof ( info - > servername ) - 1 , " \\ \\ %s " , get_called_name ( ) ) ;
2000-11-08 06:12:16 +03:00
fstrcpy ( info - > sharename , lp_servicename ( snum ) ) ;
2002-03-15 11:14:10 +03:00
slprintf ( info - > printername , sizeof ( info - > printername ) - 1 , " \\ \\ %s \\ %s " ,
get_called_name ( ) , info - > sharename ) ;
2002-02-09 07:10:24 +03:00
info - > attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK ;
2000-11-08 06:12:16 +03:00
2000-07-22 04:48:29 +04:00
return True ;
}
2000-08-11 03:41:16 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-08-11 03:41:16 +04:00
static BOOL add_printer_hook ( NT_PRINTER_INFO_LEVEL * printer )
{
2002-07-15 14:35:28 +04:00
extern userdom_struct current_user_info ;
2000-08-11 03:41:16 +04:00
char * cmd = lp_addprinter_cmd ( ) ;
char * * qlines ;
pstring command ;
int numlines ;
int ret ;
2001-04-13 04:37:00 +04:00
int fd ;
2002-02-09 07:10:24 +03:00
fstring remote_machine = " %m " ;
2000-08-11 03:41:16 +04:00
2002-07-15 14:35:28 +04:00
standard_sub_basic ( current_user_info . smb_name , remote_machine , sizeof ( remote_machine ) ) ;
2002-02-09 07:10:24 +03:00
slprintf ( command , sizeof ( command ) - 1 , " %s \" %s \" \" %s \" \" %s \" \" %s \" \" %s \" \" %s \" \" %s \" " ,
2000-08-11 03:41:16 +04:00
cmd , printer - > info_2 - > printername , printer - > info_2 - > sharename ,
printer - > info_2 - > portname , printer - > info_2 - > drivername ,
2002-10-08 22:32:42 +04:00
printer - > info_2 - > location , printer - > info_2 - > comment , remote_machine ) ;
2000-08-11 03:41:16 +04:00
2001-04-13 23:12:06 +04:00
DEBUG ( 10 , ( " Running [%s] \n " , command ) ) ;
ret = smbrun ( command , & fd ) ;
2000-08-11 03:41:16 +04:00
DEBUGADD ( 10 , ( " returned [%d] \n " , ret ) ) ;
if ( ret ! = 0 ) {
2001-04-13 04:37:00 +04:00
if ( fd ! = - 1 )
close ( fd ) ;
2000-08-11 03:41:16 +04:00
return False ;
}
numlines = 0 ;
2001-04-13 23:12:06 +04:00
/* Get lines and convert them back to dos-codepage */
2001-07-04 11:15:53 +04:00
qlines = fd_lines_load ( fd , & numlines ) ;
2000-08-11 03:41:16 +04:00
DEBUGADD ( 10 , ( " Lines returned = [%d] \n " , numlines ) ) ;
2001-04-13 04:37:00 +04:00
close ( fd ) ;
2000-08-11 03:41:16 +04:00
if ( numlines ) {
2000-09-26 04:54:18 +04:00
/* Set the portname to what the script says the portname should be. */
2000-08-11 03:41:16 +04:00
strncpy ( printer - > info_2 - > portname , qlines [ 0 ] , sizeof ( printer - > info_2 - > portname ) ) ;
2000-09-01 22:49:26 +04:00
DEBUGADD ( 6 , ( " Line[0] = [%s] \n " , qlines [ 0 ] ) ) ;
2000-08-11 03:41:16 +04:00
2000-09-26 04:54:18 +04:00
/* Send SIGHUP to process group... is there a better way? */
2000-08-11 03:41:16 +04:00
kill ( 0 , SIGHUP ) ;
add_all_printers ( ) ;
}
file_lines_free ( qlines ) ;
return True ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2002-02-09 07:10:24 +03:00
* Called by spoolss_api_setprinter
* when updating a printer description .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
2001-09-03 14:38:13 +04:00
static WERROR update_printer ( pipes_struct * p , POLICY_HND * handle , uint32 level ,
2000-02-07 19:17:59 +03:00
const SPOOL_PRINTER_INFO_LEVEL * info ,
2000-06-01 06:35:30 +04:00
DEVICEMODE * devmode )
2000-02-07 19:17:59 +03:00
{
int snum ;
2000-11-07 05:54:50 +03:00
NT_PRINTER_INFO_LEVEL * printer = NULL , * old_printer = NULL ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2001-09-03 14:38:13 +04:00
WERROR result ;
2000-07-10 09:08:21 +04:00
2000-02-07 19:17:59 +03:00
DEBUG ( 8 , ( " update_printer \n " ) ) ;
2002-07-15 14:35:28 +04:00
2001-09-03 14:38:13 +04:00
result = WERR_OK ;
2000-07-10 09:08:21 +04:00
2000-02-27 01:22:24 +03:00
if ( level ! = 2 ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 0 , ( " update_printer: Send a mail to samba@samba.org \n " ) ) ;
2000-02-07 19:17:59 +03:00
DEBUGADD ( 0 , ( " with the following message: update_printer: level!=2 \n " ) ) ;
2001-09-03 12:50:59 +04:00
result = WERR_UNKNOWN_LEVEL ;
2000-07-10 09:08:21 +04:00
goto done ;
2000-02-07 19:17:59 +03:00
}
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2001-09-03 14:38:13 +04:00
result = WERR_BADFID ;
2000-07-10 09:08:21 +04:00
goto done ;
2000-07-07 03:31:46 +04:00
}
2000-02-25 02:01:24 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) ) {
2001-09-03 14:38:13 +04:00
result = WERR_BADFID ;
2000-07-10 09:08:21 +04:00
goto done ;
}
2000-08-09 08:19:18 +04:00
2001-09-03 14:38:13 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) | |
( ! W_ERROR_IS_OK ( get_a_printer ( & old_printer , 2 , lp_servicename ( snum ) ) ) ) ) {
result = WERR_BADFID ;
2000-07-10 09:08:21 +04:00
goto done ;
}
2000-02-07 19:17:59 +03:00
DEBUGADD ( 8 , ( " Converting info_2 struct \n " ) ) ;
2000-06-27 02:08:20 +04:00
/*
* convert_printer_info converts the incoming
* info from the client and overwrites the info
* just read from the tdb in the pointer ' printer ' .
*/
2001-11-30 06:45:21 +03:00
if ( ! convert_printer_info ( info , printer , level ) ) {
result = WERR_NOMEM ;
goto done ;
}
2000-11-10 22:36:34 +03:00
2002-04-22 22:48:45 +04:00
if ( devmode ) {
2000-02-07 19:17:59 +03:00
/* we have a valid devmode
convert it and link it */
2000-06-27 02:08:20 +04:00
2002-02-09 07:10:24 +03:00
DEBUGADD ( 8 , ( " update_printer: Converting the devicemode struct \n " ) ) ;
2001-01-30 00:34:08 +03:00
if ( ! convert_devicemode ( printer - > info_2 - > printername , devmode ,
& printer - > info_2 - > devmode ) ) {
2001-09-03 12:50:59 +04:00
result = WERR_NOMEM ;
2001-01-30 00:34:08 +03:00
goto done ;
}
2000-02-07 19:17:59 +03:00
}
2000-07-22 04:48:29 +04:00
2000-11-07 05:54:50 +03:00
/* Do sanity check on the requested changes for Samba */
2000-07-22 04:48:29 +04:00
if ( ! check_printer_ok ( printer - > info_2 , snum ) ) {
2001-09-03 14:38:13 +04:00
result = WERR_INVALID_PARAM ;
2000-07-22 04:48:29 +04:00
goto done ;
}
2000-11-18 02:10:56 +03:00
/* Check calling user has permission to update printer description */
2000-11-07 05:54:50 +03:00
2002-03-07 04:02:48 +03:00
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER ) {
DEBUG ( 3 , ( " update_printer: printer property change denied by handle \n " ) ) ;
2001-09-03 14:38:13 +04:00
result = WERR_ACCESS_DENIED ;
2000-11-07 05:54:50 +03:00
goto done ;
}
/* Call addprinter hook */
2001-09-04 11:13:01 +04:00
if ( * lp_addprinter_cmd ( ) ) {
2002-02-09 07:10:24 +03:00
if ( ! add_printer_hook ( printer ) ) {
2001-09-03 14:38:13 +04:00
result = WERR_ACCESS_DENIED ;
2000-08-11 03:41:16 +04:00
goto done ;
}
2001-09-04 11:13:01 +04:00
}
2000-08-11 03:41:16 +04:00
2002-02-09 07:10:24 +03:00
/*
2002-09-25 19:19:00 +04:00
* When a * new * driver is bound to a printer , the drivername is used to
* lookup previously saved driver initialization info , which is then
* bound to the printer , simulating what happens in the Windows arch .
2002-02-09 07:10:24 +03:00
*/
2002-09-25 19:19:00 +04:00
if ( ! strequal ( printer - > info_2 - > drivername , old_printer - > info_2 - > drivername ) )
2002-08-17 19:34:15 +04:00
{
2002-09-25 19:19:00 +04:00
if ( ! set_driver_init ( printer , 2 ) )
2002-08-17 19:34:15 +04:00
{
2002-09-25 19:19:00 +04:00
DEBUG ( 5 , ( " update_printer: Error restoring driver initialization data for driver [%s]! \n " ,
2002-08-17 19:34:15 +04:00
printer - > info_2 - > drivername ) ) ;
2002-03-15 11:14:10 +03:00
}
2002-09-25 19:19:00 +04:00
DEBUG ( 10 , ( " update_printer: changing driver [%s]! Sending event! \n " ,
printer - > info_2 - > drivername ) ) ;
notify_printer_driver ( snum , printer - > info_2 - > drivername ) ;
2002-02-09 07:10:24 +03:00
}
2000-11-07 05:54:50 +03:00
/* Update printer info */
2002-01-27 01:27:12 +03:00
result = mod_a_printer ( * printer , 2 ) ;
2000-02-07 19:17:59 +03:00
2002-03-15 11:14:10 +03:00
/* flag which changes actually occured. This is a small subset of
all the possible changes */
if ( ! strequal ( printer - > info_2 - > comment , old_printer - > info_2 - > comment ) )
2002-07-15 14:35:28 +04:00
notify_printer_comment ( snum , printer - > info_2 - > comment ) ;
2002-03-15 11:14:10 +03:00
if ( ! strequal ( printer - > info_2 - > sharename , old_printer - > info_2 - > sharename ) )
2002-07-15 14:35:28 +04:00
notify_printer_sharename ( snum , printer - > info_2 - > sharename ) ;
2002-03-15 11:14:10 +03:00
if ( ! strequal ( printer - > info_2 - > portname , old_printer - > info_2 - > portname ) )
2002-07-15 14:35:28 +04:00
notify_printer_port ( snum , printer - > info_2 - > portname ) ;
2002-03-15 11:14:10 +03:00
if ( ! strequal ( printer - > info_2 - > location , old_printer - > info_2 - > location ) )
2002-07-15 14:35:28 +04:00
notify_printer_location ( snum , printer - > info_2 - > location ) ;
2002-03-15 11:14:10 +03:00
2002-07-15 14:35:28 +04:00
done :
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-11-08 03:20:26 +03:00
free_a_printer ( & old_printer , 2 ) ;
2000-06-01 06:35:30 +04:00
2000-09-26 01:05:18 +04:00
2000-07-10 09:08:21 +04:00
return result ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_setprinter ( pipes_struct * p , SPOOL_Q_SETPRINTER * q_u , SPOOL_R_SETPRINTER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:38:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 level = q_u - > level ;
SPOOL_PRINTER_INFO_LEVEL * info = & q_u - > info ;
DEVMODE_CTR devmode_ctr = q_u - > devmode_ctr ;
SEC_DESC_BUF * secdesc_ctr = q_u - > secdesc_ctr ;
uint32 command = q_u - > command ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_setprinter: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2000-02-25 02:01:24 +03:00
2000-02-07 19:17:59 +03:00
/* check the level */
2000-02-27 01:22:24 +03:00
switch ( level ) {
2000-02-25 02:01:24 +03:00
case 0 :
2000-07-06 10:53:47 +04:00
return control_printer ( handle , command , p ) ;
2000-02-25 02:01:24 +03:00
case 2 :
2001-03-11 03:32:10 +03:00
return update_printer ( p , handle , level , info , devmode_ctr . devmode ) ;
2000-05-27 13:53:11 +04:00
case 3 :
2000-07-10 09:08:21 +04:00
return update_printer_sec ( handle , level , info , p ,
secdesc_ctr ) ;
2000-03-13 22:34:04 +03:00
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-04 11:13:01 +04:00
WERROR _spoolss_fcpn ( pipes_struct * p , SPOOL_Q_FCPN * q_u , SPOOL_R_FCPN * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:38:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-24 19:27:06 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_fcpn: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2000-09-26 01:05:18 +04:00
if ( Printer - > notify . client_connected = = True )
2001-03-11 03:32:10 +03:00
srv_spoolss_replycloseprinter ( & Printer - > notify . client_hnd ) ;
2000-09-26 01:05:18 +04:00
2000-02-25 02:01:24 +03:00
Printer - > notify . flags = 0 ;
Printer - > notify . options = 0 ;
Printer - > notify . localmachine [ 0 ] = ' \0 ' ;
Printer - > notify . printerlocal = 0 ;
2000-06-07 00:44:58 +04:00
if ( Printer - > notify . option )
2001-03-01 03:14:45 +03:00
free_spool_notify_option ( & Printer - > notify . option ) ;
2000-09-26 01:05:18 +04:00
Printer - > notify . client_connected = False ;
2001-09-04 11:13:01 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_addjob ( pipes_struct * p , SPOOL_Q_ADDJOB * q_u , SPOOL_R_ADDJOB * r_u )
2000-08-28 08:42:31 +04:00
{
2001-02-28 05:38:09 +03:00
/* that's an [in out] buffer (despite appearences to the contrary) */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-02-28 05:38:09 +03:00
r_u - > needed = 0 ;
2001-09-03 14:38:13 +04:00
return WERR_INVALID_PARAM ; /* this is what a NT server
2001-11-22 08:56:09 +03:00
returns for AddJob . AddJob
must fail on non - local
printers */
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-07 19:17:59 +03:00
static void fill_job_info_1 ( JOB_INFO_1 * job_info , print_queue_struct * queue ,
int position , int snum )
{
pstring temp_name ;
struct tm * t ;
2000-10-29 20:27:41 +03:00
t = gmtime ( & queue - > time ) ;
2002-01-08 03:46:56 +03:00
slprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , get_called_name ( ) ) ;
2000-02-07 19:17:59 +03:00
job_info - > jobid = queue - > job ;
2000-07-18 23:25:32 +04:00
init_unistr ( & job_info - > printername , lp_servicename ( snum ) ) ;
init_unistr ( & job_info - > machinename , temp_name ) ;
2002-03-15 11:14:10 +03:00
init_unistr ( & job_info - > username , queue - > fs_user ) ;
init_unistr ( & job_info - > document , queue - > fs_file ) ;
2000-07-18 23:25:32 +04:00
init_unistr ( & job_info - > datatype , " RAW " ) ;
init_unistr ( & job_info - > text_status , " " ) ;
2000-04-16 11:28:06 +04:00
job_info - > status = nt_printj_status ( queue - > status ) ;
2000-02-07 19:17:59 +03:00
job_info - > priority = queue - > priority ;
job_info - > position = position ;
2002-03-19 05:35:12 +03:00
job_info - > totalpages = queue - > page_count ;
2000-02-07 19:17:59 +03:00
job_info - > pagesprinted = 0 ;
2000-08-01 04:41:19 +04:00
make_systemtime ( & job_info - > submitted , t ) ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-07 19:17:59 +03:00
static BOOL fill_job_info_2 ( JOB_INFO_2 * job_info , print_queue_struct * queue ,
2001-01-18 01:55:02 +03:00
int position , int snum ,
2002-07-15 14:35:28 +04:00
NT_PRINTER_INFO_LEVEL * ntprinter ,
2002-02-26 02:18:05 +03:00
DEVICEMODE * devmode )
2000-02-07 19:17:59 +03:00
{
pstring temp_name ;
pstring chaine ;
struct tm * t ;
2000-10-29 20:27:41 +03:00
t = gmtime ( & queue - > time ) ;
2002-01-08 03:46:56 +03:00
slprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , get_called_name ( ) ) ;
2000-02-07 19:17:59 +03:00
job_info - > jobid = queue - > job ;
2002-01-08 03:46:56 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s \\ %s " , get_called_name ( ) , ntprinter - > info_2 - > printername ) ;
2000-06-01 06:35:30 +04:00
2000-07-27 04:47:19 +04:00
init_unistr ( & job_info - > printername , chaine ) ;
2000-02-07 19:17:59 +03:00
2000-07-18 23:25:32 +04:00
init_unistr ( & job_info - > machinename , temp_name ) ;
2002-03-15 11:14:10 +03:00
init_unistr ( & job_info - > username , queue - > fs_user ) ;
init_unistr ( & job_info - > document , queue - > fs_file ) ;
init_unistr ( & job_info - > notifyname , queue - > fs_user ) ;
2000-07-18 23:25:32 +04:00
init_unistr ( & job_info - > datatype , " RAW " ) ;
init_unistr ( & job_info - > printprocessor , " winprint " ) ;
init_unistr ( & job_info - > parameters , " " ) ;
2000-09-13 02:33:41 +04:00
init_unistr ( & job_info - > drivername , ntprinter - > info_2 - > drivername ) ;
2000-07-18 23:25:32 +04:00
init_unistr ( & job_info - > text_status , " " ) ;
2000-02-07 19:17:59 +03:00
/* and here the security descriptor */
2000-04-16 11:28:06 +04:00
job_info - > status = nt_printj_status ( queue - > status ) ;
2000-02-07 19:17:59 +03:00
job_info - > priority = queue - > priority ;
job_info - > position = position ;
job_info - > starttime = 0 ;
job_info - > untiltime = 0 ;
2002-03-19 05:35:12 +03:00
job_info - > totalpages = queue - > page_count ;
2000-02-07 19:17:59 +03:00
job_info - > size = queue - > size ;
make_systemtime ( & ( job_info - > submitted ) , t ) ;
job_info - > timeelapsed = 0 ;
job_info - > pagesprinted = 0 ;
2002-02-26 02:18:05 +03:00
job_info - > devmode = devmode ;
2000-04-07 02:48:53 +04:00
2000-02-07 19:17:59 +03:00
return ( True ) ;
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
Enumjobs at level 1.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumjobs_level1 ( print_queue_struct * queue , int snum ,
2000-11-18 02:10:56 +03:00
NEW_BUFFER * buffer , uint32 offered ,
2000-02-15 21:07:45 +03:00
uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
2000-02-15 21:07:45 +03:00
JOB_INFO_1 * info ;
2000-02-07 19:17:59 +03:00
int i ;
2000-02-15 21:07:45 +03:00
info = ( JOB_INFO_1 * ) malloc ( * returned * sizeof ( JOB_INFO_1 ) ) ;
2000-04-06 20:23:04 +04:00
if ( info = = NULL ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2000-04-06 20:23:04 +04:00
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-06 20:23:04 +04:00
}
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
for ( i = 0 ; i < * returned ; i + + )
2000-07-18 23:25:32 +04:00
fill_job_info_1 ( & info [ i ] , & queue [ i ] , i , snum ) ;
2000-04-06 20:23:04 +04:00
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
/* check the required size. */
for ( i = 0 ; i < * returned ; i + + )
2000-07-18 23:25:32 +04:00
( * needed ) + = spoolss_size_job_info_1 ( & info [ i ] ) ;
2000-02-15 21:07:45 +03:00
2000-04-06 20:23:04 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-04-06 20:23:04 +04:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the structures */
for ( i = 0 ; i < * returned ; i + + )
2001-03-28 20:08:00 +04:00
smb_io_job_info_1 ( " " , buffer , & info [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
/* clear memory */
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
Enumjobs at level 2.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumjobs_level2 ( print_queue_struct * queue , int snum ,
2000-11-18 02:10:56 +03:00
NEW_BUFFER * buffer , uint32 offered ,
2000-02-15 21:07:45 +03:00
uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
2001-01-18 01:55:02 +03:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2002-02-26 02:18:05 +03:00
JOB_INFO_2 * info = NULL ;
2000-02-15 21:07:45 +03:00
int i ;
2001-09-04 11:13:01 +04:00
WERROR result ;
2002-02-26 02:18:05 +03:00
DEVICEMODE * devmode = NULL ;
2000-02-15 21:07:45 +03:00
info = ( JOB_INFO_2 * ) malloc ( * returned * sizeof ( JOB_INFO_2 ) ) ;
2000-04-06 20:23:04 +04:00
if ( info = = NULL ) {
* returned = 0 ;
2002-02-26 02:18:05 +03:00
result = WERR_NOMEM ;
goto done ;
2000-04-06 20:23:04 +04:00
}
2001-01-18 01:55:02 +03:00
2001-09-04 11:13:01 +04:00
result = get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
2001-01-18 01:55:02 +03:00
* returned = 0 ;
2002-02-26 02:18:05 +03:00
goto done ;
2001-01-18 01:55:02 +03:00
}
2002-07-15 14:35:28 +04:00
2002-02-26 02:18:05 +03:00
if ( ! ( devmode = construct_dev_mode ( snum ) ) ) {
* returned = 0 ;
result = WERR_NOMEM ;
goto done ;
}
2000-02-15 21:07:45 +03:00
for ( i = 0 ; i < * returned ; i + + )
2002-02-26 02:18:05 +03:00
fill_job_info_2 ( & ( info [ i ] ) , & queue [ i ] , i , snum , ntprinter ,
devmode ) ;
2000-04-06 20:23:04 +04:00
2001-01-18 01:55:02 +03:00
free_a_printer ( & ntprinter , 2 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
/* check the required size. */
for ( i = 0 ; i < * returned ; i + + )
2000-07-18 23:25:32 +04:00
( * needed ) + = spoolss_size_job_info_2 ( & info [ i ] ) ;
2000-02-15 21:07:45 +03:00
2002-02-26 02:18:05 +03:00
if ( * needed > offered ) {
* returned = 0 ;
result = WERR_INSUFFICIENT_BUFFER ;
goto done ;
}
2000-04-06 20:23:04 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2002-03-15 11:14:10 +03:00
SAFE_FREE ( info ) ;
2002-02-26 02:18:05 +03:00
result = WERR_INSUFFICIENT_BUFFER ;
goto done ;
2000-04-06 20:23:04 +04:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the structures */
for ( i = 0 ; i < * returned ; i + + )
2001-03-28 20:08:00 +04:00
smb_io_job_info_2 ( " " , buffer , & info [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
2002-02-26 02:18:05 +03:00
result = WERR_OK ;
2001-01-18 01:55:02 +03:00
2002-02-26 02:18:05 +03:00
done :
free_a_printer ( & ntprinter , 2 ) ;
free_devmode ( devmode ) ;
SAFE_FREE ( queue ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-02-15 21:07:45 +03:00
2002-02-26 02:18:05 +03:00
return result ;
2002-07-15 14:35:28 +04:00
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumjobs .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumjobs ( pipes_struct * p , SPOOL_Q_ENUMJOBS * q_u , SPOOL_R_ENUMJOBS * r_u )
2000-02-15 21:07:45 +03:00
{
2001-02-28 05:38:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * returned = & r_u - > returned ;
2000-02-15 21:07:45 +03:00
int snum ;
print_status_struct prt_status ;
2001-12-05 05:11:03 +03:00
print_queue_struct * queue = NULL ;
2000-02-15 21:07:45 +03:00
2001-02-28 05:38:09 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-02-28 05:38:09 +03:00
buffer = r_u - > buffer ;
2000-02-15 21:07:45 +03:00
DEBUG ( 4 , ( " _spoolss_enumjobs \n " ) ) ;
* needed = 0 ;
* returned = 0 ;
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-15 21:07:45 +03:00
2000-04-16 10:20:43 +04:00
* returned = print_queue_status ( snum , & queue , & prt_status ) ;
2000-02-15 21:07:45 +03:00
DEBUGADD ( 4 , ( " count:[%d], status:[%d], [%s] \n " , * returned , prt_status . status , prt_status . message ) ) ;
2000-09-12 03:21:16 +04:00
if ( * returned = = 0 ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-09-12 03:21:16 +04:00
}
2000-02-15 21:07:45 +03:00
switch ( level ) {
case 1 :
return enumjobs_level1 ( queue , snum , buffer , offered , needed , returned ) ;
case 2 :
return enumjobs_level2 ( queue , snum , buffer , offered , needed , returned ) ;
default :
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2000-04-06 20:23:04 +04:00
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-15 21:07:45 +03:00
}
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_schedulejob ( pipes_struct * p , SPOOL_Q_SCHEDULEJOB * q_u , SPOOL_R_SCHEDULEJOB * r_u )
2000-02-15 21:07:45 +03:00
{
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_setjob ( pipes_struct * p , SPOOL_Q_SETJOB * q_u , SPOOL_R_SETJOB * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 05:38:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 jobid = q_u - > jobid ;
uint32 command = q_u - > command ;
2000-07-06 10:53:47 +04:00
struct current_user user ;
2001-09-03 14:38:13 +04:00
int snum ;
WERROR errcode = WERR_BADFUNC ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) ) {
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2002-08-17 19:34:15 +04:00
if ( ! print_job_exists ( snum , jobid ) ) {
2001-09-03 12:50:59 +04:00
return WERR_INVALID_PRINTER_NAME ;
2000-02-07 19:17:59 +03:00
}
2000-09-22 01:44:15 +04:00
get_current_user ( & user , p ) ;
2000-07-06 10:53:47 +04:00
2000-04-16 10:20:43 +04:00
switch ( command ) {
case JOB_CONTROL_CANCEL :
case JOB_CONTROL_DELETE :
2002-08-17 19:34:15 +04:00
if ( print_job_delete ( & user , snum , jobid , & errcode ) ) {
2001-09-04 11:13:01 +04:00
errcode = WERR_OK ;
2000-09-26 01:05:18 +04:00
}
2000-04-16 10:20:43 +04:00
break ;
case JOB_CONTROL_PAUSE :
2002-08-17 19:34:15 +04:00
if ( print_job_pause ( & user , snum , jobid , & errcode ) ) {
2001-09-04 11:13:01 +04:00
errcode = WERR_OK ;
2000-09-26 01:05:18 +04:00
}
2000-04-16 10:20:43 +04:00
break ;
2000-11-08 03:20:26 +03:00
case JOB_CONTROL_RESTART :
2000-04-16 10:20:43 +04:00
case JOB_CONTROL_RESUME :
2002-08-17 19:34:15 +04:00
if ( print_job_resume ( & user , snum , jobid , & errcode ) ) {
2001-09-04 11:13:01 +04:00
errcode = WERR_OK ;
2000-09-26 01:05:18 +04:00
}
2000-04-16 10:20:43 +04:00
break ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
2000-11-08 03:20:26 +03:00
return errcode ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
Enumerates all printer drivers at level 1.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprinterdrivers_level1 ( fstring servername , fstring architecture , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
int i ;
2000-07-25 17:15:16 +04:00
int ndrivers ;
uint32 version ;
fstring * list = NULL ;
2001-11-22 08:56:09 +03:00
2000-02-15 21:07:45 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2001-08-12 21:30:01 +04:00
DRIVER_INFO_1 * tdi1 , * driver_info_1 = NULL ;
2000-04-07 02:48:53 +04:00
2000-07-25 17:15:16 +04:00
* returned = 0 ;
2000-05-12 18:28:46 +04:00
2002-07-15 14:35:28 +04:00
for ( version = 0 ; version < DRIVER_MAX_VERSION ; version + + ) {
2000-07-25 17:15:16 +04:00
list = NULL ;
ndrivers = get_ntdrivers ( & list , architecture , version ) ;
DEBUGADD ( 4 , ( " we have:[%d] drivers in environment [%s] and version [%d] \n " , ndrivers , architecture , version ) ) ;
if ( ndrivers = = - 1 )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
if ( ndrivers ! = 0 ) {
2001-08-12 21:30:01 +04:00
if ( ( tdi1 = ( DRIVER_INFO_1 * ) Realloc ( driver_info_1 , ( * returned + ndrivers ) * sizeof ( DRIVER_INFO_1 ) ) ) = = NULL ) {
DEBUG ( 0 , ( " enumprinterdrivers_level1: failed to enlarge driver info buffer! \n " ) ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_1 ) ;
SAFE_FREE ( list ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
}
2001-08-12 21:30:01 +04:00
else driver_info_1 = tdi1 ;
2000-07-25 17:15:16 +04:00
}
for ( i = 0 ; i < ndrivers ; i + + ) {
2001-09-04 11:13:01 +04:00
WERROR status ;
2000-07-25 17:15:16 +04:00
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
2001-09-04 11:13:01 +04:00
status = get_a_printer_driver ( & driver , 3 , list [ i ] ,
architecture , version ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2000-09-15 04:15:10 +04:00
return status ;
}
2000-09-12 03:43:44 +04:00
fill_printer_driver_info_1 ( & driver_info_1 [ * returned + i ] , driver , servername , architecture ) ;
free_a_printer_driver ( driver , 3 ) ;
2000-07-25 17:15:16 +04:00
}
* returned + = ndrivers ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2000-02-15 21:07:45 +03:00
}
/* check the required size. */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding driver [%d]'s size \n " , i ) ) ;
2000-09-12 03:43:44 +04:00
* needed + = spoolss_size_printer_driver_info_1 ( & driver_info_1 [ i ] ) ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
2000-03-16 19:23:38 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_1 ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2000-02-07 19:17:59 +03:00
2001-03-02 05:59:17 +03:00
/* fill the buffer with the driver structures */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-27 01:22:24 +03:00
DEBUGADD ( 6 , ( " adding driver [%d] to buffer \n " , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_1 ( " " , buffer , & driver_info_1 [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_1 ) ;
2000-02-15 21:07:45 +03:00
2000-03-16 19:23:38 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumerates all printer drivers at level 2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprinterdrivers_level2 ( fstring servername , fstring architecture , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
int i ;
2000-07-25 17:15:16 +04:00
int ndrivers ;
uint32 version ;
fstring * list = NULL ;
2001-11-22 08:56:09 +03:00
2000-07-25 17:15:16 +04:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2001-08-12 21:30:01 +04:00
DRIVER_INFO_2 * tdi2 , * driver_info_2 = NULL ;
2000-04-07 02:48:53 +04:00
2000-07-25 17:15:16 +04:00
* returned = 0 ;
2000-02-15 21:07:45 +03:00
2002-07-15 14:35:28 +04:00
for ( version = 0 ; version < DRIVER_MAX_VERSION ; version + + ) {
2000-07-25 17:15:16 +04:00
list = NULL ;
ndrivers = get_ntdrivers ( & list , architecture , version ) ;
DEBUGADD ( 4 , ( " we have:[%d] drivers in environment [%s] and version [%d] \n " , ndrivers , architecture , version ) ) ;
if ( ndrivers = = - 1 )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
if ( ndrivers ! = 0 ) {
2001-08-12 21:30:01 +04:00
if ( ( tdi2 = ( DRIVER_INFO_2 * ) Realloc ( driver_info_2 , ( * returned + ndrivers ) * sizeof ( DRIVER_INFO_2 ) ) ) = = NULL ) {
DEBUG ( 0 , ( " enumprinterdrivers_level2: failed to enlarge driver info buffer! \n " ) ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_2 ) ;
SAFE_FREE ( list ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
}
2001-08-12 21:30:01 +04:00
else driver_info_2 = tdi2 ;
2000-05-29 03:00:23 +04:00
}
2000-07-25 17:15:16 +04:00
for ( i = 0 ; i < ndrivers ; i + + ) {
2001-09-04 11:13:01 +04:00
WERROR status ;
2000-09-15 04:15:10 +04:00
2000-07-25 17:15:16 +04:00
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
2001-09-04 11:13:01 +04:00
status = get_a_printer_driver ( & driver , 3 , list [ i ] ,
architecture , version ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2000-09-15 04:15:10 +04:00
return status ;
}
2000-09-12 03:43:44 +04:00
fill_printer_driver_info_2 ( & driver_info_2 [ * returned + i ] , driver , servername ) ;
free_a_printer_driver ( driver , 3 ) ;
2000-07-25 17:15:16 +04:00
}
* returned + = ndrivers ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2000-02-07 19:17:59 +03:00
}
2000-02-15 21:07:45 +03:00
/* check the required size. */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding driver [%d]'s size \n " , i ) ) ;
* needed + = spoolss_size_printer_driver_info_2 ( & ( driver_info_2 [ i ] ) ) ;
}
2000-03-16 19:23:38 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_2 ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the form structures */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-27 01:22:24 +03:00
DEBUGADD ( 6 , ( " adding driver [%d] to buffer \n " , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_2 ( " " , buffer , & ( driver_info_2 [ i ] ) , 0 ) ;
2000-02-15 21:07:45 +03:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_2 ) ;
2000-02-15 21:07:45 +03:00
2000-03-16 19:23:38 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumerates all printer drivers at level 3.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprinterdrivers_level3 ( fstring servername , fstring architecture , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
int i ;
2000-07-25 17:15:16 +04:00
int ndrivers ;
uint32 version ;
fstring * list = NULL ;
2001-11-22 08:56:09 +03:00
2000-02-15 21:07:45 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2001-08-12 21:30:01 +04:00
DRIVER_INFO_3 * tdi3 , * driver_info_3 = NULL ;
2000-04-07 02:48:53 +04:00
2000-07-25 17:15:16 +04:00
* returned = 0 ;
2000-05-12 18:28:46 +04:00
2002-07-15 14:35:28 +04:00
for ( version = 0 ; version < DRIVER_MAX_VERSION ; version + + ) {
2000-07-25 17:15:16 +04:00
list = NULL ;
ndrivers = get_ntdrivers ( & list , architecture , version ) ;
DEBUGADD ( 4 , ( " we have:[%d] drivers in environment [%s] and version [%d] \n " , ndrivers , architecture , version ) ) ;
if ( ndrivers = = - 1 )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
if ( ndrivers ! = 0 ) {
2001-08-12 21:30:01 +04:00
if ( ( tdi3 = ( DRIVER_INFO_3 * ) Realloc ( driver_info_3 , ( * returned + ndrivers ) * sizeof ( DRIVER_INFO_3 ) ) ) = = NULL ) {
DEBUG ( 0 , ( " enumprinterdrivers_level3: failed to enlarge driver info buffer! \n " ) ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_3 ) ;
SAFE_FREE ( list ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
}
2001-08-12 21:30:01 +04:00
else driver_info_3 = tdi3 ;
2000-07-25 17:15:16 +04:00
}
for ( i = 0 ; i < ndrivers ; i + + ) {
2001-09-04 11:13:01 +04:00
WERROR status ;
2000-09-15 04:15:10 +04:00
2000-07-25 17:15:16 +04:00
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
2001-09-04 11:13:01 +04:00
status = get_a_printer_driver ( & driver , 3 , list [ i ] ,
architecture , version ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2000-09-15 04:15:10 +04:00
return status ;
}
2000-09-12 03:43:44 +04:00
fill_printer_driver_info_3 ( & driver_info_3 [ * returned + i ] , driver , servername ) ;
free_a_printer_driver ( driver , 3 ) ;
2000-07-25 17:15:16 +04:00
}
* returned + = ndrivers ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2000-02-15 21:07:45 +03:00
}
2000-07-25 17:15:16 +04:00
2000-02-15 21:07:45 +03:00
/* check the required size. */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding driver [%d]'s size \n " , i ) ) ;
2000-06-30 05:07:26 +04:00
* needed + = spoolss_size_printer_driver_info_3 ( & driver_info_3 [ i ] ) ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
2000-03-29 16:36:44 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_3 ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-29 16:36:44 +04:00
}
2000-07-12 18:10:40 +04:00
/* fill the buffer with the driver structures */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-07-12 18:10:40 +04:00
DEBUGADD ( 6 , ( " adding driver [%d] to buffer \n " , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_printer_driver_info_3 ( " " , buffer , & driver_info_3 [ i ] , 0 ) ;
2000-02-07 19:17:59 +03:00
}
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * returned ; i + + )
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_3 [ i ] . dependentfiles ) ;
2000-03-29 16:36:44 +04:00
2001-09-17 14:26:23 +04:00
SAFE_FREE ( driver_info_3 ) ;
2000-03-29 16:36:44 +04:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-29 16:36:44 +04:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumerates all printer drivers .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumprinterdrivers ( pipes_struct * p , SPOOL_Q_ENUMPRINTERDRIVERS * q_u , SPOOL_R_ENUMPRINTERDRIVERS * r_u )
2000-02-15 21:07:45 +03:00
{
2001-02-28 05:38:09 +03:00
UNISTR2 * environment = & q_u - > environment ;
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * returned = & r_u - > returned ;
2000-05-27 07:12:06 +04:00
fstring * list = NULL ;
2000-02-15 21:07:45 +03:00
fstring servername ;
fstring architecture ;
2001-02-28 05:38:09 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-02-28 05:38:09 +03:00
buffer = r_u - > buffer ;
2000-02-15 21:07:45 +03:00
DEBUG ( 4 , ( " _spoolss_enumprinterdrivers \n " ) ) ;
2002-01-08 03:46:56 +03:00
fstrcpy ( servername , get_called_name ( ) ) ;
2000-02-15 21:07:45 +03:00
* needed = 0 ;
* returned = 0 ;
unistr2_to_ascii ( architecture , environment , sizeof ( architecture ) - 1 ) ;
2000-04-07 02:48:53 +04:00
2000-02-15 21:07:45 +03:00
switch ( level ) {
case 1 :
2000-07-25 17:15:16 +04:00
return enumprinterdrivers_level1 ( servername , architecture , buffer , offered , needed , returned ) ;
2000-02-15 21:07:45 +03:00
case 2 :
2000-07-25 17:15:16 +04:00
return enumprinterdrivers_level2 ( servername , architecture , buffer , offered , needed , returned ) ;
2000-02-15 21:07:45 +03:00
case 3 :
2000-07-25 17:15:16 +04:00
return enumprinterdrivers_level3 ( servername , architecture , buffer , offered , needed , returned ) ;
2000-02-15 21:07:45 +03:00
default :
2000-07-12 18:10:40 +04:00
* returned = 0 ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2000-09-06 00:56:09 +04:00
static void fill_form_1 ( FORM_1 * form , nt_forms_struct * list )
2000-02-07 19:17:59 +03:00
{
form - > flag = list - > flag ;
2000-07-07 03:31:46 +04:00
init_unistr ( & form - > name , list - > name ) ;
2000-02-07 19:17:59 +03:00
form - > width = list - > width ;
form - > length = list - > length ;
form - > left = list - > left ;
form - > top = list - > top ;
form - > right = list - > right ;
form - > bottom = list - > bottom ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumforms ( pipes_struct * p , SPOOL_Q_ENUMFORMS * q_u , SPOOL_R_ENUMFORMS * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * numofforms = & r_u - > numofforms ;
2001-04-04 03:09:04 +04:00
uint32 numbuiltinforms ;
2001-03-01 00:19:31 +03:00
2000-02-07 19:17:59 +03:00
nt_forms_struct * list = NULL ;
2001-04-04 03:09:04 +04:00
nt_forms_struct * builtinlist = NULL ;
2000-02-07 19:17:59 +03:00
FORM_1 * forms_1 ;
int buffer_size = 0 ;
int i ;
2001-03-01 00:19:31 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2001-03-27 22:19:01 +04:00
DEBUG ( 4 , ( " _spoolss_enumforms \n " ) ) ;
2000-02-07 19:17:59 +03:00
DEBUGADD ( 5 , ( " Offered buffer size [%d] \n " , offered ) ) ;
DEBUGADD ( 5 , ( " Info level [%d] \n " , level ) ) ;
2001-04-04 03:09:04 +04:00
numbuiltinforms = get_builtin_ntforms ( & builtinlist ) ;
DEBUGADD ( 5 , ( " Number of builtin forms [%d] \n " , numbuiltinforms ) ) ;
2001-03-03 08:27:26 +03:00
* numofforms = get_ntforms ( & list ) ;
2001-04-04 03:09:04 +04:00
DEBUGADD ( 5 , ( " Number of user forms [%d] \n " , * numofforms ) ) ;
* numofforms + = numbuiltinforms ;
2000-02-07 19:17:59 +03:00
2001-09-04 11:13:01 +04:00
if ( * numofforms = = 0 ) return WERR_NO_MORE_ITEMS ;
2000-05-29 05:09:14 +04:00
2000-02-07 19:17:59 +03:00
switch ( level ) {
case 1 :
2001-03-03 08:27:26 +03:00
if ( ( forms_1 = ( FORM_1 * ) malloc ( * numofforms * sizeof ( FORM_1 ) ) ) = = NULL ) {
2000-04-07 02:48:53 +04:00
* numofforms = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
}
2000-02-07 19:17:59 +03:00
/* construct the list of form structures */
2001-04-04 03:09:04 +04:00
for ( i = 0 ; i < numbuiltinforms ; i + + ) {
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " Filling form number [%d] \n " , i ) ) ;
2001-04-04 03:09:04 +04:00
fill_form_1 ( & forms_1 [ i ] , & builtinlist [ i ] ) ;
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( builtinlist ) ;
2001-04-04 03:09:04 +04:00
for ( ; i < * numofforms ; i + + ) {
DEBUGADD ( 6 , ( " Filling form number [%d] \n " , i ) ) ;
fill_form_1 ( & forms_1 [ i ] , & list [ i - numbuiltinforms ] ) ;
2000-02-07 19:17:59 +03:00
}
2000-03-29 16:36:44 +04:00
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-03-03 08:27:26 +03:00
2000-02-07 19:17:59 +03:00
/* check the required size. */
2001-04-04 03:09:04 +04:00
for ( i = 0 ; i < numbuiltinforms ; i + + ) {
DEBUGADD ( 6 , ( " adding form [%d]'s size \n " , i ) ) ;
buffer_size + = spoolss_size_form_1 ( & forms_1 [ i ] ) ;
}
for ( ; i < * numofforms ; i + + ) {
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " adding form [%d]'s size \n " , i ) ) ;
2000-07-07 03:31:46 +04:00
buffer_size + = spoolss_size_form_1 ( & forms_1 [ i ] ) ;
2000-02-07 19:17:59 +03:00
}
* needed = buffer_size ;
2001-03-03 08:27:26 +03:00
if ( ! alloc_buffer_size ( buffer , buffer_size ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( forms_1 ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2001-03-03 08:27:26 +03:00
}
2000-02-07 19:17:59 +03:00
/* fill the buffer with the form structures */
2001-04-04 03:09:04 +04:00
for ( i = 0 ; i < numbuiltinforms ; i + + ) {
DEBUGADD ( 6 , ( " adding form [%d] to buffer \n " , i ) ) ;
smb_io_form_1 ( " " , buffer , & forms_1 [ i ] , 0 ) ;
}
for ( ; i < * numofforms ; i + + ) {
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " adding form [%d] to buffer \n " , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_form_1 ( " " , buffer , & forms_1 [ i ] , 0 ) ;
2000-02-07 19:17:59 +03:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( forms_1 ) ;
2001-03-03 08:27:26 +03:00
2000-03-29 16:36:44 +04:00
if ( * needed > offered ) {
* numofforms = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-29 16:36:44 +04:00
}
2000-02-07 19:17:59 +03:00
else
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
default :
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
SAFE_FREE ( builtinlist ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
2001-03-03 08:27:26 +03:00
2000-02-07 19:17:59 +03:00
}
2000-09-06 00:56:09 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_getform ( pipes_struct * p , SPOOL_Q_GETFORM * q_u , SPOOL_R_GETFORM * r_u )
2000-09-06 00:56:09 +04:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
UNISTR2 * uni_formname = & q_u - > formname ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
2000-09-06 00:56:09 +04:00
nt_forms_struct * list = NULL ;
2001-04-04 03:09:04 +04:00
nt_forms_struct builtin_form ;
BOOL foundBuiltin ;
2000-09-06 00:56:09 +04:00
FORM_1 form_1 ;
fstring form_name ;
int buffer_size = 0 ;
2001-04-16 06:35:35 +04:00
int numofforms = 0 , i = 0 ;
2000-09-06 00:56:09 +04:00
2001-03-01 00:19:31 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-09-06 00:56:09 +04:00
unistr2_to_ascii ( form_name , uni_formname , sizeof ( form_name ) - 1 ) ;
DEBUG ( 4 , ( " _spoolss_getform \n " ) ) ;
DEBUGADD ( 5 , ( " Offered buffer size [%d] \n " , offered ) ) ;
DEBUGADD ( 5 , ( " Info level [%d] \n " , level ) ) ;
2001-04-04 03:09:04 +04:00
foundBuiltin = get_a_builtin_ntform ( uni_formname , & builtin_form ) ;
if ( ! foundBuiltin ) {
numofforms = get_ntforms ( & list ) ;
DEBUGADD ( 5 , ( " Number of forms [%d] \n " , numofforms ) ) ;
2000-09-06 00:56:09 +04:00
2001-04-04 03:09:04 +04:00
if ( numofforms = = 0 )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2001-04-04 03:09:04 +04:00
}
2000-09-06 00:56:09 +04:00
switch ( level ) {
case 1 :
2001-04-04 03:09:04 +04:00
if ( foundBuiltin ) {
fill_form_1 ( & form_1 , & builtin_form ) ;
} else {
2000-09-06 00:56:09 +04:00
2001-04-04 03:09:04 +04:00
/* Check if the requested name is in the list of form structures */
for ( i = 0 ; i < numofforms ; i + + ) {
2000-09-06 00:56:09 +04:00
2001-04-04 03:09:04 +04:00
DEBUG ( 4 , ( " _spoolss_getform: checking form %s (want %s) \n " , list [ i ] . name , form_name ) ) ;
2000-09-06 00:56:09 +04:00
2001-04-04 03:09:04 +04:00
if ( strequal ( form_name , list [ i ] . name ) ) {
DEBUGADD ( 6 , ( " Found form %s number [%d] \n " , form_name , i ) ) ;
fill_form_1 ( & form_1 , & list [ i ] ) ;
break ;
}
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-04-04 03:09:04 +04:00
if ( i = = numofforms ) {
2001-09-04 11:13:01 +04:00
return WERR_BADFID ;
2000-09-06 00:56:09 +04:00
}
}
/* check the required size. */
* needed = spoolss_size_form_1 ( & form_1 ) ;
if ( ! alloc_buffer_size ( buffer , buffer_size ) ) {
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-09-06 00:56:09 +04:00
}
if ( * needed > offered ) {
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-09-06 00:56:09 +04:00
}
/* fill the buffer with the form structures */
DEBUGADD ( 6 , ( " adding form %s [%d] to buffer \n " , form_name , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_form_1 ( " " , buffer , & form_1 , 0 ) ;
2000-09-06 00:56:09 +04:00
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-09-06 00:56:09 +04:00
default :
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-09-06 00:56:09 +04:00
}
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-15 21:07:45 +03:00
static void fill_port_1 ( PORT_INFO_1 * port , char * name )
2000-02-07 19:17:59 +03:00
{
2000-06-23 03:59:22 +04:00
init_unistr ( & port - > port_name , name ) ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-07 19:17:59 +03:00
static void fill_port_2 ( PORT_INFO_2 * port , char * name )
{
2000-06-23 03:59:22 +04:00
init_unistr ( & port - > port_name , name ) ;
init_unistr ( & port - > monitor_name , " Local Monitor " ) ;
init_unistr ( & port - > description , " Local Port " ) ;
2000-02-07 19:17:59 +03:00
# define PORT_TYPE_WRITE 1
port - > port_type = PORT_TYPE_WRITE ;
port - > reserved = 0x0 ;
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
enumports level 1.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumports_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
2000-02-15 21:07:45 +03:00
PORT_INFO_1 * ports = NULL ;
2000-08-01 00:41:51 +04:00
int i = 0 ;
if ( * lp_enumports_cmd ( ) ) {
char * cmd = lp_enumports_cmd ( ) ;
char * * qlines ;
pstring command ;
int numlines ;
int ret ;
2001-04-13 04:37:00 +04:00
int fd ;
2000-08-01 00:41:51 +04:00
2001-02-16 22:21:18 +03:00
slprintf ( command , sizeof ( command ) - 1 , " %s \" %d \" " , cmd , 1 ) ;
2000-08-01 00:41:51 +04:00
2001-04-13 23:12:06 +04:00
DEBUG ( 10 , ( " Running [%s] \n " , command ) ) ;
ret = smbrun ( command , & fd ) ;
2000-08-01 00:41:51 +04:00
DEBUG ( 10 , ( " Returned [%d] \n " , ret ) ) ;
if ( ret ! = 0 ) {
2001-04-13 04:37:00 +04:00
if ( fd ! = - 1 )
close ( fd ) ;
2000-09-26 04:54:18 +04:00
/* Is this the best error to return here? */
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-08-01 00:41:51 +04:00
}
2000-02-07 19:17:59 +03:00
2000-08-01 00:41:51 +04:00
numlines = 0 ;
2001-07-04 11:15:53 +04:00
qlines = fd_lines_load ( fd , & numlines ) ;
2000-08-01 00:41:51 +04:00
DEBUGADD ( 10 , ( " Lines returned = [%d] \n " , numlines ) ) ;
2001-04-13 04:37:00 +04:00
close ( fd ) ;
2000-08-01 00:41:51 +04:00
if ( numlines ) {
if ( ( ports = ( PORT_INFO_1 * ) malloc ( numlines * sizeof ( PORT_INFO_1 ) ) ) = = NULL ) {
2001-09-04 11:13:01 +04:00
DEBUG ( 10 , ( " Returning WERR_NOMEM [%s] \n " ,
2002-03-17 09:04:15 +03:00
dos_errstr ( WERR_NOMEM ) ) ) ;
2000-08-01 00:41:51 +04:00
file_lines_free ( qlines ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-08-01 00:41:51 +04:00
}
2000-02-15 21:07:45 +03:00
2000-08-01 00:41:51 +04:00
for ( i = 0 ; i < numlines ; i + + ) {
DEBUG ( 6 , ( " Filling port number [%d] with port [%s] \n " , i , qlines [ i ] ) ) ;
fill_port_1 ( & ports [ i ] , qlines [ i ] ) ;
}
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
file_lines_free ( qlines ) ;
}
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
* returned = numlines ;
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
} else {
* returned = 1 ; /* Sole Samba port returned. */
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
if ( ( ports = ( PORT_INFO_1 * ) malloc ( sizeof ( PORT_INFO_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-08-01 00:41:51 +04:00
DEBUG ( 10 , ( " enumports_level_1: port name %s \n " , SAMBA_PRINTER_PORT_NAME ) ) ;
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
fill_port_1 ( & ports [ 0 ] , SAMBA_PRINTER_PORT_NAME ) ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
/* check the required size. */
2000-03-13 14:09:20 +03:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding port [%d]'s size \n " , i ) ) ;
2000-06-23 03:59:22 +04:00
* needed + = spoolss_size_port_info_1 ( & ports [ i ] ) ;
2000-02-15 21:07:45 +03:00
}
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( ports ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the ports structures */
2000-03-13 14:09:20 +03:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding port [%d] to buffer \n " , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_port_1 ( " " , buffer , & ports [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( ports ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-07 19:17:59 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
enumports level 2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 03:59:22 +04:00
2001-09-03 14:38:13 +04:00
static WERROR enumports_level_2 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
PORT_INFO_2 * ports = NULL ;
2000-08-01 00:41:51 +04:00
int i = 0 ;
2000-02-15 21:07:45 +03:00
2000-08-01 00:41:51 +04:00
if ( * lp_enumports_cmd ( ) ) {
char * cmd = lp_enumports_cmd ( ) ;
char * path ;
char * * qlines ;
pstring tmp_file ;
pstring command ;
int numlines ;
int ret ;
2001-04-13 04:37:00 +04:00
int fd ;
2000-08-01 00:41:51 +04:00
if ( * lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) )
path = lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) ;
else
2001-04-12 11:00:08 +04:00
path = lp_lockdir ( ) ;
2000-08-01 00:41:51 +04:00
2001-04-28 01:49:22 +04:00
slprintf ( tmp_file , sizeof ( tmp_file ) - 1 , " %s/smbcmd.%u. " , path , ( unsigned int ) sys_getpid ( ) ) ;
2001-02-16 22:21:18 +03:00
slprintf ( command , sizeof ( command ) - 1 , " %s \" %d \" " , cmd , 2 ) ;
2000-08-01 00:41:51 +04:00
unlink ( tmp_file ) ;
DEBUG ( 10 , ( " Running [%s > %s] \n " , command , tmp_file ) ) ;
2001-04-13 23:12:06 +04:00
ret = smbrun ( command , & fd ) ;
2000-08-01 00:41:51 +04:00
DEBUGADD ( 10 , ( " returned [%d] \n " , ret ) ) ;
if ( ret ! = 0 ) {
2001-04-13 04:37:00 +04:00
if ( fd ! = - 1 )
close ( fd ) ;
2000-09-26 04:54:18 +04:00
/* Is this the best error to return here? */
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-08-01 00:41:51 +04:00
}
2000-02-15 21:07:45 +03:00
2000-08-01 00:41:51 +04:00
numlines = 0 ;
2001-07-04 11:15:53 +04:00
qlines = fd_lines_load ( fd , & numlines ) ;
2000-08-01 00:41:51 +04:00
DEBUGADD ( 10 , ( " Lines returned = [%d] \n " , numlines ) ) ;
2001-04-13 04:37:00 +04:00
close ( fd ) ;
2000-08-01 00:41:51 +04:00
if ( numlines ) {
if ( ( ports = ( PORT_INFO_2 * ) malloc ( numlines * sizeof ( PORT_INFO_2 ) ) ) = = NULL ) {
file_lines_free ( qlines ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-08-01 00:41:51 +04:00
}
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
for ( i = 0 ; i < numlines ; i + + ) {
DEBUG ( 6 , ( " Filling port number [%d] with port [%s] \n " , i , qlines [ i ] ) ) ;
fill_port_2 ( & ( ports [ i ] ) , qlines [ i ] ) ;
}
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
file_lines_free ( qlines ) ;
}
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
* returned = numlines ;
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
} else {
2000-06-23 03:59:22 +04:00
2000-08-01 00:41:51 +04:00
* returned = 1 ;
2000-02-15 21:07:45 +03:00
2000-08-01 00:41:51 +04:00
if ( ( ports = ( PORT_INFO_2 * ) malloc ( sizeof ( PORT_INFO_2 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-08-01 00:41:51 +04:00
DEBUG ( 10 , ( " enumports_level_2: port name %s \n " , SAMBA_PRINTER_PORT_NAME ) ) ;
fill_port_2 ( & ports [ 0 ] , SAMBA_PRINTER_PORT_NAME ) ;
}
2000-06-23 03:59:22 +04:00
2000-02-15 21:07:45 +03:00
/* check the required size. */
2000-03-13 14:09:20 +03:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding port [%d]'s size \n " , i ) ) ;
2000-06-23 03:59:22 +04:00
* needed + = spoolss_size_port_info_2 ( & ports [ i ] ) ;
2000-02-15 21:07:45 +03:00
}
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( ports ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the ports structures */
2000-03-13 14:09:20 +03:00
for ( i = 0 ; i < * returned ; i + + ) {
2000-02-15 21:07:45 +03:00
DEBUGADD ( 6 , ( " adding port [%d] to buffer \n " , i ) ) ;
2001-03-28 20:08:00 +04:00
smb_io_port_2 ( " " , buffer , & ports [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( ports ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
enumports .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumports ( pipes_struct * p , SPOOL_Q_ENUMPORTS * q_u , SPOOL_R_ENUMPORTS * r_u )
2000-02-15 21:07:45 +03:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * returned = & r_u - > returned ;
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-02-21 04:58:13 +03:00
DEBUG ( 4 , ( " _spoolss_enumports \n " ) ) ;
2000-02-15 21:07:45 +03:00
* returned = 0 ;
* needed = 0 ;
switch ( level ) {
case 1 :
return enumports_level_1 ( buffer , offered , needed , returned ) ;
case 2 :
return enumports_level_2 ( buffer , offered , needed , returned ) ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR spoolss_addprinterex_level_2 ( pipes_struct * p , const UNISTR2 * uni_srv_name ,
2000-02-07 19:17:59 +03:00
const SPOOL_PRINTER_INFO_LEVEL * info ,
2002-01-26 04:20:38 +03:00
DEVICEMODE * devmode , SEC_DESC_BUF * sec_desc_buf ,
2000-03-13 14:09:20 +03:00
uint32 user_switch , const SPOOL_USER_CTR * user ,
2000-02-07 19:17:59 +03:00
POLICY_HND * handle )
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2001-11-27 23:01:23 +03:00
fstring name ;
int snum ;
WERROR err = WERR_OK ;
2000-02-07 19:17:59 +03:00
2000-06-02 22:38:49 +04:00
if ( ( printer = ( NT_PRINTER_INFO_LEVEL * ) malloc ( sizeof ( NT_PRINTER_INFO_LEVEL ) ) ) = = NULL ) {
DEBUG ( 0 , ( " spoolss_addprinterex_level_2: malloc fail. \n " ) ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-06-02 22:38:49 +04:00
}
ZERO_STRUCTP ( printer ) ;
/* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
2001-11-30 06:45:21 +03:00
if ( ! convert_printer_info ( info , printer , 2 ) ) {
free_a_printer ( & printer , 2 ) ;
return WERR_NOMEM ;
}
2000-02-07 19:17:59 +03:00
2001-11-27 23:01:23 +03:00
/* check to see if the printer already exists */
2001-11-30 06:38:59 +03:00
if ( ( snum = print_queue_snum ( printer - > info_2 - > sharename ) ) ! = - 1 ) {
2001-11-27 23:01:23 +03:00
DEBUG ( 5 , ( " _spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed! \n " ,
printer - > info_2 - > sharename ) ) ;
2001-11-30 06:38:59 +03:00
free_a_printer ( & printer , 2 ) ;
2001-11-27 23:01:23 +03:00
return WERR_PRINTER_ALREADY_EXISTS ;
}
2000-08-01 00:41:51 +04:00
if ( * lp_addprinter_cmd ( ) )
2000-09-06 05:55:36 +04:00
if ( ! add_printer_hook ( printer ) ) {
free_a_printer ( & printer , 2 ) ;
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-09-06 05:55:36 +04:00
}
2002-01-08 03:46:56 +03:00
slprintf ( name , sizeof ( name ) - 1 , " \\ \\ %s \\ %s " , get_called_name ( ) ,
2000-08-01 00:41:51 +04:00
printer - > info_2 - > sharename ) ;
2000-02-21 04:58:13 +03:00
2000-08-01 00:41:51 +04:00
if ( ( snum = print_queue_snum ( printer - > info_2 - > sharename ) ) = = - 1 ) {
2000-07-25 05:50:53 +04:00
free_a_printer ( & printer , 2 ) ;
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-07-25 05:50:53 +04:00
}
2000-08-09 08:19:18 +04:00
/* you must be a printer admin to add a new printer */
2000-09-01 22:49:26 +04:00
if ( ! print_access_check ( NULL , snum , PRINTER_ACCESS_ADMINISTER ) ) {
2000-08-09 08:19:18 +04:00
free_a_printer ( & printer , 2 ) ;
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-08-09 08:19:18 +04:00
}
2000-07-25 05:50:53 +04:00
/*
* Do sanity check on the requested changes for Samba .
*/
if ( ! check_printer_ok ( printer - > info_2 , snum ) ) {
free_a_printer ( & printer , 2 ) ;
2001-09-03 14:38:13 +04:00
return WERR_INVALID_PARAM ;
2000-07-25 05:50:53 +04:00
}
2002-02-09 07:10:24 +03:00
/*
2001-08-10 23:38:53 +04:00
* When a printer is created , the drivername bound to the printer is used
2001-11-22 08:56:09 +03:00
* to lookup previously saved driver initialization info , which is then
2001-08-10 23:38:53 +04:00
* bound to the new printer , simulating what happens in the Windows arch .
*/
2002-02-09 07:10:24 +03:00
if ( ! devmode )
2002-09-25 19:19:00 +04:00
{
2002-02-09 07:10:24 +03:00
set_driver_init ( printer , 2 ) ;
2002-09-25 19:19:00 +04:00
}
else
{
2002-02-09 07:10:24 +03:00
/* A valid devmode was included, convert and link it
*/
DEBUGADD ( 10 , ( " spoolss_addprinterex_level_2: devmode included, converting \n " ) ) ;
if ( ! convert_devicemode ( printer - > info_2 - > printername , devmode ,
& printer - > info_2 - > devmode ) )
return WERR_NOMEM ;
}
2000-03-13 18:53:02 +03:00
/* write the ASCII on disk */
2002-01-27 01:27:12 +03:00
err = mod_a_printer ( * printer , 2 ) ;
2001-09-04 11:13:01 +04:00
if ( ! W_ERROR_IS_OK ( err ) ) {
2000-06-02 22:38:49 +04:00
free_a_printer ( & printer , 2 ) ;
2001-09-04 11:13:01 +04:00
return err ;
2000-06-02 22:38:49 +04:00
}
2000-03-13 18:53:02 +03:00
2002-03-07 04:02:48 +03:00
if ( ! open_printer_hnd ( p , handle , name , PRINTER_ACCESS_ADMINISTER ) ) {
2000-07-25 05:50:53 +04:00
/* Handle open failed - remove addition. */
2000-08-01 00:41:51 +04:00
del_a_printer ( printer - > info_2 - > sharename ) ;
2000-06-02 22:38:49 +04:00
free_a_printer ( & printer , 2 ) ;
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-02-07 19:17:59 +03:00
}
2002-03-26 06:15:30 +03:00
update_c_setprinter ( False ) ;
2000-06-02 22:38:49 +04:00
free_a_printer ( & printer , 2 ) ;
2000-09-26 01:05:18 +04:00
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-03-29 18:49:05 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_addprinterex ( pipes_struct * p , SPOOL_Q_ADDPRINTEREX * q_u , SPOOL_R_ADDPRINTEREX * r_u )
2000-03-29 18:49:05 +04:00
{
2001-03-01 00:19:31 +03:00
UNISTR2 * uni_srv_name = & q_u - > server_name ;
uint32 level = q_u - > level ;
SPOOL_PRINTER_INFO_LEVEL * info = & q_u - > info ;
2002-01-26 04:20:38 +03:00
DEVICEMODE * devmode = q_u - > devmode_ctr . devmode ;
SEC_DESC_BUF * sdb = q_u - > secdesc_ctr ;
2001-03-01 00:19:31 +03:00
uint32 user_switch = q_u - > user_switch ;
SPOOL_USER_CTR * user = & q_u - > user_ctr ;
POLICY_HND * handle = & r_u - > handle ;
2000-03-29 18:49:05 +04:00
switch ( level ) {
case 1 :
/* we don't handle yet */
/* but I know what to do ... */
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-03-29 18:49:05 +04:00
case 2 :
2001-03-11 03:32:10 +03:00
return spoolss_addprinterex_level_2 ( p , uni_srv_name , info ,
2002-01-26 04:20:38 +03:00
devmode , sdb ,
2000-03-29 18:49:05 +04:00
user_switch , user , handle ) ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-03-29 18:49:05 +04:00
}
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_addprinterdriver ( pipes_struct * p , SPOOL_Q_ADDPRINTERDRIVER * q_u , SPOOL_R_ADDPRINTERDRIVER * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
SPOOL_PRINTER_DRIVER_INFO_LEVEL * info = & q_u - > info ;
2001-09-03 14:38:13 +04:00
WERROR err = WERR_OK ;
2000-02-07 19:17:59 +03:00
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2000-07-25 17:15:16 +04:00
struct current_user user ;
2002-07-15 14:35:28 +04:00
fstring driver_name ;
uint32 version ;
2000-05-12 18:28:46 +04:00
ZERO_STRUCT ( driver ) ;
2000-09-22 01:44:15 +04:00
2002-07-15 14:35:28 +04:00
get_current_user ( & user , p ) ;
2000-07-25 17:15:16 +04:00
2001-08-12 21:30:01 +04:00
if ( ! convert_printer_driver_info ( info , & driver , level ) ) {
2001-09-03 12:50:59 +04:00
err = WERR_NOMEM ;
2001-08-12 21:30:01 +04:00
goto done ;
}
2000-02-21 04:58:13 +03:00
2000-07-25 17:15:16 +04:00
DEBUG ( 5 , ( " Cleaning driver's information \n " ) ) ;
2001-09-04 11:13:01 +04:00
err = clean_up_driver_struct ( driver , level , & user ) ;
if ( ! W_ERROR_IS_OK ( err ) )
2000-10-27 02:09:22 +04:00
goto done ;
2000-07-25 17:15:16 +04:00
DEBUG ( 5 , ( " Moving driver to final destination \n " ) ) ;
2000-08-31 01:09:21 +04:00
if ( ! move_driver_to_download_area ( driver , level , & user , & err ) ) {
2001-09-04 11:13:01 +04:00
if ( W_ERROR_IS_OK ( err ) )
2001-09-03 14:38:13 +04:00
err = WERR_ACCESS_DENIED ;
2000-07-26 07:38:30 +04:00
goto done ;
}
2000-07-25 17:15:16 +04:00
2000-07-26 07:38:30 +04:00
if ( add_a_printer_driver ( driver , level ) ! = 0 ) {
2001-09-03 14:38:13 +04:00
err = WERR_ACCESS_DENIED ;
2000-07-26 07:38:30 +04:00
goto done ;
}
2000-02-21 04:58:13 +03:00
2002-07-15 14:35:28 +04:00
/* BEGIN_ADMIN_LOG */
switch ( level ) {
case 3 :
sys_adminlog ( LOG_INFO , " Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s. " ,
driver . info_3 - > name , drv_ver_to_os [ driver . info_3 - > cversion ] , uidtoname ( user . uid ) ) ;
fstrcpy ( driver_name , driver . info_3 - > name ) ;
break ;
case 6 :
sys_adminlog ( LOG_INFO , " Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s. " ,
driver . info_6 - > name , drv_ver_to_os [ driver . info_6 - > version ] , uidtoname ( user . uid ) ) ;
fstrcpy ( driver_name , driver . info_6 - > name ) ;
break ;
}
/* END_ADMIN_LOG */
/*
* I think this is where he DrvUpgradePrinter ( ) hook would be
* be called in a driver ' s interface DLL on a Windows NT 4.0 / 2 k
* server . Right now , we just need to send ourselves a message
* to update each printer bound to this driver . - - jerry
*/
if ( ! srv_spoolss_drv_upgrade_printer ( driver_name ) ) {
DEBUG ( 0 , ( " _spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]! \n " ,
driver_name ) ) ;
}
/*
* Based on the version ( e . g . driver destination dir : 0 = 9 x , 2 = Nt / 2 k , 3 = 2 k / Xp ) ,
* decide if the driver init data should be deleted . The rules are :
* 1 ) never delete init data if it is a 9 x driver , they don ' t use it anyway
* 2 ) delete init data only if there is no 2 k / Xp driver
* 3 ) always delete init data
* The generalized rule is always use init data from the highest order driver .
* It is necessary to follow the driver install by an initialization step to
* finish off this process .
*/
if ( level = = 3 )
version = driver . info_3 - > cversion ;
else if ( level = = 6 )
version = driver . info_6 - > version ;
else
version = - 1 ;
switch ( version ) {
/*
* 9 x printer driver - never delete init data
*/
case 0 :
DEBUG ( 10 , ( " _spoolss_addprinterdriver: init data not deleted for 9x driver [%s] \n " ,
driver_name ) ) ;
break ;
/*
* Nt or 2 k ( compatiblity mode ) printer driver - only delete init data if
* there is no 2 k / Xp driver init data for this driver name .
*/
case 2 :
{
NT_PRINTER_DRIVER_INFO_LEVEL driver1 ;
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & driver1 , 3 , driver_name , " Windows NT x86 " , 3 ) ) ) {
/*
* No 2 k / Xp driver found , delete init data ( if any ) for the new Nt driver .
*/
if ( ! del_driver_init ( driver_name ) )
DEBUG ( 6 , ( " _spoolss_addprinterdriver: del_driver_init(%s) Nt failed! \n " , driver_name ) ) ;
} else {
/*
* a 2 k / Xp driver was found , don ' t delete init data because Nt driver will use it .
*/
free_a_printer_driver ( driver1 , 3 ) ;
DEBUG ( 10 , ( " _spoolss_addprinterdriver: init data not deleted for Nt driver [%s] \n " ,
driver_name ) ) ;
}
}
break ;
/*
* 2 k or Xp printer driver - always delete init data
*/
case 3 :
if ( ! del_driver_init ( driver_name ) )
DEBUG ( 6 , ( " _spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed! \n " , driver_name ) ) ;
break ;
default :
DEBUG ( 0 , ( " _spoolss_addprinterdriver: invalid level=%d \n " , level ) ) ;
break ;
}
done :
2000-06-02 01:52:49 +04:00
free_a_printer_driver ( driver , level ) ;
2000-06-04 04:26:08 +04:00
return err ;
2000-02-07 19:17:59 +03:00
}
2002-07-15 14:35:28 +04:00
/********************************************************************
* spoolss_addprinterdriverex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_addprinterdriverex ( pipes_struct * p , SPOOL_Q_ADDPRINTERDRIVEREX * q_u , SPOOL_R_ADDPRINTERDRIVEREX * r_u )
{
SPOOL_Q_ADDPRINTERDRIVER q_u_local ;
SPOOL_R_ADDPRINTERDRIVER r_u_local ;
/*
* we only support the semantics of AddPrinterDriver ( )
* i . e . only copy files that are newer than existing ones
*/
if ( q_u - > copy_flags ! = APD_COPY_NEW_FILES )
return WERR_ACCESS_DENIED ;
ZERO_STRUCT ( q_u_local ) ;
ZERO_STRUCT ( r_u_local ) ;
2002-08-17 19:34:15 +04:00
/* just pass the information off to _spoolss_addprinterdriver() */
2002-07-15 14:35:28 +04:00
q_u_local . server_name_ptr = q_u - > server_name_ptr ;
copy_unistr2 ( & q_u_local . server_name , & q_u - > server_name ) ;
q_u_local . level = q_u - > level ;
memcpy ( & q_u_local . info , & q_u - > info , sizeof ( SPOOL_PRINTER_DRIVER_INFO_LEVEL ) ) ;
return _spoolss_addprinterdriver ( p , & q_u_local , & r_u_local ) ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2000-02-21 04:58:13 +03:00
static void fill_driverdir_1 ( DRIVER_DIRECTORY_1 * info , char * name )
{
2000-07-25 21:09:29 +04:00
init_unistr ( & info - > name , name ) ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR getprinterdriverdir_level_1 ( UNISTR2 * name , UNISTR2 * uni_environment , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-07 19:17:59 +03:00
{
2000-05-23 00:04:50 +04:00
pstring path ;
2000-02-07 19:17:59 +03:00
pstring long_archi ;
2000-02-21 04:58:13 +03:00
pstring short_archi ;
DRIVER_DIRECTORY_1 * info = NULL ;
2002-03-15 11:14:10 +03:00
2000-07-25 17:15:16 +04:00
unistr2_to_ascii ( long_archi , uni_environment , sizeof ( long_archi ) - 1 ) ;
2001-11-15 08:26:22 +03:00
if ( get_short_archi ( short_archi , long_archi ) = = False )
2001-09-03 12:50:59 +04:00
return WERR_INVALID_ENVIRONMENT ;
2000-07-25 17:15:16 +04:00
2000-04-07 02:48:53 +04:00
if ( ( info = ( DRIVER_DIRECTORY_1 * ) malloc ( sizeof ( DRIVER_DIRECTORY_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-07-25 17:15:16 +04:00
2002-01-08 03:46:56 +03:00
slprintf ( path , sizeof ( path ) - 1 , " \\ \\ %s \\ print$ \\ %s " , get_called_name ( ) , short_archi ) ;
2000-07-25 17:15:16 +04:00
2000-05-23 00:04:50 +04:00
DEBUG ( 4 , ( " printer driver directory: [%s] \n " , path ) ) ;
2000-02-07 19:17:59 +03:00
2000-05-23 00:04:50 +04:00
fill_driverdir_1 ( info , path ) ;
2000-02-21 04:58:13 +03:00
2000-05-12 18:28:46 +04:00
* needed + = spoolss_size_driverdir_info_1 ( info ) ;
2000-02-21 04:58:13 +03:00
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
2001-03-28 20:08:00 +04:00
smb_io_driverdir_1 ( " " , buffer , info , 0 ) ;
2000-02-21 04:58:13 +03:00
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info ) ;
2000-02-21 04:58:13 +03:00
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_getprinterdriverdirectory ( pipes_struct * p , SPOOL_Q_GETPRINTERDRIVERDIR * q_u , SPOOL_R_GETPRINTERDRIVERDIR * r_u )
2000-02-21 04:58:13 +03:00
{
2001-03-01 00:19:31 +03:00
UNISTR2 * name = & q_u - > name ;
UNISTR2 * uni_environment = & q_u - > environment ;
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-02-21 04:58:13 +03:00
DEBUG ( 4 , ( " _spoolss_getprinterdriverdirectory \n " ) ) ;
* needed = 0 ;
switch ( level ) {
case 1 :
return getprinterdriverdir_level_1 ( name , uni_environment , buffer , offered , needed ) ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-21 04:58:13 +03:00
}
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumprinterdata ( pipes_struct * p , SPOOL_Q_ENUMPRINTERDATA * q_u , SPOOL_R_ENUMPRINTERDATA * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
POLICY_HND * handle = & q_u - > handle ;
2002-08-17 19:34:15 +04:00
uint32 idx = q_u - > index ;
uint32 in_value_len = q_u - > valuesize ;
uint32 in_data_len = q_u - > datasize ;
2002-09-25 19:19:00 +04:00
uint32 * out_max_value_len = & r_u - > valuesize ;
2002-08-17 19:34:15 +04:00
uint16 * * out_value = & r_u - > value ;
uint32 * out_value_len = & r_u - > realvaluesize ;
uint32 * out_type = & r_u - > type ;
2001-03-01 00:19:31 +03:00
uint32 * out_max_data_len = & r_u - > datasize ;
2002-08-17 19:34:15 +04:00
uint8 * * data_out = & r_u - > data ;
uint32 * out_data_len = & r_u - > realdatasize ;
2001-03-01 00:19:31 +03:00
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-07 19:17:59 +03:00
2002-08-17 19:34:15 +04:00
uint32 param_index ;
uint32 biggest_valuesize ;
uint32 biggest_datasize ;
uint32 data_len ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
int snum ;
WERROR result ;
REGISTRY_VALUE * val ;
NT_PRINTER_DATA * p_data ;
int i , key_index , num_values ;
int name_length ;
2000-02-07 19:17:59 +03:00
2002-08-17 19:34:15 +04:00
ZERO_STRUCT ( printer ) ;
2000-02-27 01:22:24 +03:00
2002-08-17 19:34:15 +04:00
* out_type = 0 ;
2000-02-27 01:22:24 +03:00
2002-08-17 19:34:15 +04:00
* out_max_data_len = 0 ;
* data_out = NULL ;
* out_data_len = 0 ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_enumprinterdata \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_enumprinterdata: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2000-02-25 02:01:24 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-25 02:01:24 +03:00
2001-09-04 11:13:01 +04:00
result = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( result ) )
return result ;
2002-08-17 19:34:15 +04:00
p_data = & printer - > info_2 - > data ;
key_index = lookup_printerkey ( p_data , SPOOL_PRINTERDATA_KEY ) ;
result = WERR_OK ;
2000-02-07 19:17:59 +03:00
2000-11-18 02:10:56 +03:00
/*
2000-02-27 01:22:24 +03:00
* The NT machine wants to know the biggest size of value and data
*
* cf : MSDN EnumPrinterData remark section
*/
2002-08-17 19:34:15 +04:00
if ( ! in_value_len & & ! in_data_len )
{
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " Activating NT mega-hack to find sizes \n " ) ) ;
2000-09-08 00:56:24 +04:00
2002-08-17 19:34:15 +04:00
param_index = 0 ;
biggest_valuesize = 0 ;
biggest_datasize = 0 ;
num_values = regval_ctr_numvals ( & p_data - > keys [ key_index ] . values ) ;
2000-02-07 19:17:59 +03:00
2002-08-17 19:34:15 +04:00
for ( i = 0 ; i < num_values ; i + + )
{
val = regval_ctr_specific_value ( & p_data - > keys [ key_index ] . values , i ) ;
name_length = strlen ( val - > valuename ) ;
if ( strlen ( val - > valuename ) > biggest_valuesize )
biggest_valuesize = name_length ;
if ( val - > size > biggest_datasize )
biggest_datasize = val - > size ;
DEBUG ( 6 , ( " current values: [%d], [%d] \n " , biggest_valuesize ,
biggest_datasize ) ) ;
2000-02-07 19:17:59 +03:00
}
2000-02-27 01:22:24 +03:00
2002-08-17 19:34:15 +04:00
/* the value is an UNICODE string but real_value_size is the length
in bytes including the trailing 0 */
* out_value_len = 2 * ( 1 + biggest_valuesize ) ;
* out_data_len = biggest_datasize ;
2000-02-27 01:22:24 +03:00
DEBUG ( 6 , ( " final values: [%d], [%d] \n " , * out_value_len , * out_data_len ) ) ;
2002-08-17 19:34:15 +04:00
goto done ;
2000-02-07 19:17:59 +03:00
}
2000-02-27 01:22:24 +03:00
2000-11-18 02:10:56 +03:00
/*
2000-02-27 01:22:24 +03:00
* the value len is wrong in NT sp3
* that ' s the number of bytes not the number of unicode chars
*/
2002-08-17 19:34:15 +04:00
val = regval_ctr_specific_value ( & p_data - > keys [ key_index ] . values , idx ) ;
2000-03-13 14:09:20 +03:00
2002-08-17 19:34:15 +04:00
if ( ! val )
{
2001-11-30 23:33:35 +03:00
/* out_value should default to "" or else NT4 has
problems unmarshalling the response */
2002-08-17 19:34:15 +04:00
* out_max_value_len = ( in_value_len / sizeof ( uint16 ) ) ;
if ( ( * out_value = ( uint16 * ) talloc_zero ( p - > mem_ctx , in_value_len * sizeof ( uint8 ) ) ) = = NULL )
{
result = WERR_NOMEM ;
goto done ;
}
2001-11-30 23:33:35 +03:00
2002-07-15 14:35:28 +04:00
* out_value_len = ( uint32 ) rpcstr_push ( ( char * ) * out_value , " " , in_value_len , 0 ) ;
2001-11-30 23:33:35 +03:00
/* the data is counted in bytes */
2002-08-17 19:34:15 +04:00
2001-11-30 23:33:35 +03:00
* out_max_data_len = in_data_len ;
2002-08-17 19:34:15 +04:00
* out_data_len = in_data_len ;
/* only allocate when given a non-zero data_len */
if ( in_data_len & & ( ( * data_out = ( uint8 * ) talloc_zero ( p - > mem_ctx , in_data_len * sizeof ( uint8 ) ) ) = = NULL ) )
{
result = WERR_NOMEM ;
goto done ;
}
2001-11-30 23:33:35 +03:00
2002-08-17 19:34:15 +04:00
result = WERR_NO_MORE_ITEMS ;
2000-02-07 19:17:59 +03:00
}
2002-08-17 19:34:15 +04:00
else
{
/*
* the value is :
* - counted in bytes in the request
* - counted in UNICODE chars in the max reply
* - counted in bytes in the real size
*
* take a pause * before * coding not * during * coding
*/
2000-11-18 02:10:56 +03:00
2002-08-17 19:34:15 +04:00
/* name */
* out_max_value_len = ( in_value_len / sizeof ( uint16 ) ) ;
if ( ( * out_value = ( uint16 * ) talloc_zero ( p - > mem_ctx , in_value_len * sizeof ( uint8 ) ) ) = = NULL )
{
result = WERR_NOMEM ;
goto done ;
}
2000-07-12 18:10:40 +04:00
2002-08-17 19:34:15 +04:00
* out_value_len = ( uint32 ) rpcstr_push ( ( char * ) * out_value , regval_name ( val ) , in_value_len , 0 ) ;
2000-02-27 01:22:24 +03:00
2002-08-17 19:34:15 +04:00
/* type */
* out_type = regval_type ( val ) ;
2000-02-27 01:22:24 +03:00
2002-08-17 19:34:15 +04:00
/* data - counted in bytes */
* out_max_data_len = in_data_len ;
if ( ( * data_out = ( uint8 * ) talloc_zero ( p - > mem_ctx , in_data_len * sizeof ( uint8 ) ) ) = = NULL )
{
result = WERR_NOMEM ;
goto done ;
}
data_len = ( size_t ) regval_size ( val ) ;
memcpy ( * data_out , regval_data_p ( val ) , data_len ) ;
* out_data_len = data_len ;
2000-04-07 02:48:53 +04:00
}
2000-02-27 01:22:24 +03:00
2002-08-17 19:34:15 +04:00
done :
free_a_printer ( & printer , 2 ) ;
return result ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_setprinterdata ( pipes_struct * p , SPOOL_Q_SETPRINTERDATA * q_u , SPOOL_R_SETPRINTERDATA * r_u )
2000-02-07 19:17:59 +03:00
{
2002-08-17 19:34:15 +04:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * value = & q_u - > value ;
uint32 type = q_u - > type ;
uint8 * data = q_u - > data ;
uint32 real_len = q_u - > real_len ;
2001-03-01 00:19:31 +03:00
2002-08-17 19:34:15 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status = WERR_OK ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
fstring valuename ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_setprinterdata \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_setprinterdata: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2000-02-25 02:01:24 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
2001-09-10 23:29:00 +04:00
/*
* Access check : NT returns " access denied " if you make a
* SetPrinterData call without the necessary privildge .
* we were originally returning OK if nothing changed
* which made Win2k issue * * a lot * * of SetPrinterData
* when connecting to a printer - - jerry
*/
2002-09-25 19:19:00 +04:00
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER )
{
2002-03-07 04:02:48 +03:00
DEBUG ( 3 , ( " _spoolss_setprinterdata: change denied by handle access permissions \n " ) ) ;
2001-09-10 23:30:34 +04:00
status = WERR_ACCESS_DENIED ;
2001-09-10 23:29:00 +04:00
goto done ;
}
2001-09-14 19:22:49 +04:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
return status ;
2002-08-17 19:34:15 +04:00
unistr2_to_ascii ( valuename , value , sizeof ( valuename ) - 1 ) ;
2001-11-22 08:56:09 +03:00
2002-09-25 19:19:00 +04:00
/*
* When client side code sets a magic printer data key , detect it and save
* the current printer data and the magic key ' s data ( its the DEVMODE ) for
* future printer / driver initializations .
*/
if ( ( type = = REG_BINARY ) & & strequal ( valuename , PHANTOM_DEVMODE_KEY ) )
{
/* Set devmode and printer initialization info */
status = save_driver_init ( printer , 2 , data , real_len ) ;
srv_spoolss_reset_printerdata ( printer - > info_2 - > drivername ) ;
}
else
{
status = set_printer_dataex ( printer , SPOOL_PRINTERDATA_KEY , valuename ,
type , data , real_len ) ;
if ( W_ERROR_IS_OK ( status ) )
status = mod_a_printer ( * printer , 2 ) ;
}
2001-11-22 08:56:09 +03:00
2002-08-17 19:34:15 +04:00
done :
2000-06-03 04:53:07 +04:00
free_a_printer ( & printer , 2 ) ;
2000-11-07 05:54:50 +03:00
2000-02-07 19:17:59 +03:00
return status ;
}
2000-09-09 04:19:35 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2002-03-15 11:14:10 +03:00
WERROR _spoolss_resetprinter ( pipes_struct * p , SPOOL_Q_RESETPRINTER * q_u , SPOOL_R_RESETPRINTER * r_u )
{
2002-08-17 19:34:15 +04:00
POLICY_HND * handle = & q_u - > handle ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
int snum ;
2002-03-20 06:37:27 +03:00
DEBUG ( 5 , ( " _spoolss_resetprinter \n " ) ) ;
/*
* All we do is to check to see if the handle and queue is valid .
* This call really doesn ' t mean anything to us because we only
* support RAW printing . - - jerry
*/
if ( ! Printer ) {
DEBUG ( 2 , ( " _spoolss_resetprinter: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
return WERR_BADFID ;
}
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
/* blindly return success */
2002-03-15 11:14:10 +03:00
return WERR_OK ;
}
2002-08-17 19:34:15 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-03 14:38:13 +04:00
WERROR _spoolss_deleteprinterdata ( pipes_struct * p , SPOOL_Q_DELETEPRINTERDATA * q_u , SPOOL_R_DELETEPRINTERDATA * r_u )
2000-09-09 04:19:35 +04:00
{
2002-08-17 19:34:15 +04:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * value = & q_u - > valuename ;
2001-02-28 04:24:55 +03:00
2002-08-17 19:34:15 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status = WERR_OK ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
pstring valuename ;
2000-09-09 04:19:35 +04:00
DEBUG ( 5 , ( " spoolss_deleteprinterdata \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_deleteprinterdata: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-09-09 04:19:35 +04:00
}
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-09-09 04:19:35 +04:00
2002-03-07 04:02:48 +03:00
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER ) {
DEBUG ( 3 , ( " _spoolss_deleteprinterdata: printer properties change denied by handle \n " ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_ACCESS_DENIED ;
2000-09-09 04:19:35 +04:00
}
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
2001-09-04 11:13:01 +04:00
if ( ! W_ERROR_IS_OK ( status ) )
return status ;
2000-09-09 04:19:35 +04:00
2002-08-17 19:34:15 +04:00
unistr2_to_ascii ( valuename , value , sizeof ( valuename ) - 1 ) ;
2000-09-09 04:19:35 +04:00
2002-09-25 19:19:00 +04:00
status = delete_printer_dataex ( printer , SPOOL_PRINTERDATA_KEY , valuename ) ;
2000-09-09 04:19:35 +04:00
free_a_printer ( & printer , 2 ) ;
2002-08-17 19:34:15 +04:00
2000-09-09 04:19:35 +04:00
return status ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_addform ( pipes_struct * p , SPOOL_Q_ADDFORM * q_u , SPOOL_R_ADDFORM * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
POLICY_HND * handle = & q_u - > handle ;
FORM * form = & q_u - > form ;
2001-04-04 03:09:04 +04:00
nt_forms_struct tmpForm ;
2002-02-09 07:10:24 +03:00
int snum ;
WERROR status = WERR_OK ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int count = 0 ;
2000-02-07 19:17:59 +03:00
nt_forms_struct * list = NULL ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_addform \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_addform: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-07-07 03:31:46 +04:00
}
2002-09-25 19:19:00 +04:00
/* forms can be added on printer of on the print server handle */
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
{
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
goto done ;
}
2000-02-07 19:17:59 +03:00
2002-09-25 19:19:00 +04:00
if ( ! ( Printer - > access_granted & ( PRINTER_ACCESS_ADMINISTER | SERVER_ACCESS_ADMINISTER ) ) ) {
2002-03-07 04:02:48 +03:00
DEBUG ( 2 , ( " _spoolss_addform: denied by handle permissions. \n " ) ) ;
2002-02-13 01:31:18 +03:00
status = WERR_ACCESS_DENIED ;
goto done ;
}
2002-09-25 19:19:00 +04:00
2001-04-04 03:09:04 +04:00
/* can't add if builtin */
2002-09-25 19:19:00 +04:00
2001-04-04 03:09:04 +04:00
if ( get_a_builtin_ntform ( & form - > name , & tmpForm ) ) {
2002-09-25 19:19:00 +04:00
status = WERR_ALREADY_EXISTS ;
goto done ;
2001-04-04 03:09:04 +04:00
}
2002-09-25 19:19:00 +04:00
count = get_ntforms ( & list ) ;
if ( ! add_a_form ( & list , form , & count ) ) {
status = WERR_NOMEM ;
goto done ;
}
2000-02-07 19:17:59 +03:00
write_ntforms ( & list , count ) ;
2002-02-09 07:10:24 +03:00
/*
2002-09-25 19:19:00 +04:00
* ChangeID must always be set if this is a printer
2002-02-09 07:10:24 +03:00
*/
2002-09-25 19:19:00 +04:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
status = mod_a_printer ( * printer , 2 ) ;
2002-02-09 07:10:24 +03:00
done :
2002-09-25 19:19:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-03-03 08:27:26 +03:00
2002-02-09 07:10:24 +03:00
return status ;
2000-02-07 19:17:59 +03:00
}
2000-08-31 23:04:51 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_deleteform ( pipes_struct * p , SPOOL_Q_DELETEFORM * q_u , SPOOL_R_DELETEFORM * r_u )
2000-08-31 23:04:51 +04:00
{
2001-03-01 00:19:31 +03:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * form_name = & q_u - > name ;
2001-04-04 03:09:04 +04:00
nt_forms_struct tmpForm ;
2002-02-09 07:10:24 +03:00
int count = 0 ;
2000-08-31 23:04:51 +04:00
nt_forms_struct * list = NULL ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2002-02-09 07:10:24 +03:00
int snum ;
WERROR status = WERR_OK ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-08-31 23:04:51 +04:00
DEBUG ( 5 , ( " spoolss_deleteform \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_deleteform: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-08-31 23:04:51 +04:00
}
2002-09-25 19:19:00 +04:00
/* forms can be deleted on printer of on the print server handle */
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
{
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
goto done ;
}
2002-01-31 14:44:00 +03:00
2002-09-25 19:19:00 +04:00
if ( ! ( Printer - > access_granted & ( PRINTER_ACCESS_ADMINISTER | SERVER_ACCESS_ADMINISTER ) ) ) {
DEBUG ( 2 , ( " _spoolss_deleteform: denied by handle permissions. \n " ) ) ;
status = WERR_ACCESS_DENIED ;
goto done ;
2002-01-31 14:44:00 +03:00
}
2001-04-04 03:09:04 +04:00
/* can't delete if builtin */
2002-09-25 19:19:00 +04:00
2001-04-04 03:09:04 +04:00
if ( get_a_builtin_ntform ( form_name , & tmpForm ) ) {
2002-09-25 19:19:00 +04:00
status = WERR_INVALID_PARAM ;
goto done ;
2001-04-04 03:09:04 +04:00
}
2001-03-03 08:27:26 +03:00
count = get_ntforms ( & list ) ;
2002-09-25 19:19:00 +04:00
if ( ! delete_a_form ( & list , form_name , & count , & status ) )
goto done ;
2000-08-31 23:04:51 +04:00
2002-02-09 07:10:24 +03:00
/*
2002-09-25 19:19:00 +04:00
* ChangeID must always be set if this is a printer
2002-02-09 07:10:24 +03:00
*/
2002-09-25 19:19:00 +04:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
status = mod_a_printer ( * printer , 2 ) ;
2002-02-09 07:10:24 +03:00
done :
2002-09-25 19:19:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-03-03 08:27:26 +03:00
2002-09-25 19:19:00 +04:00
return status ;
2000-08-31 23:04:51 +04:00
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_setform ( pipes_struct * p , SPOOL_Q_SETFORM * q_u , SPOOL_R_SETFORM * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
POLICY_HND * handle = & q_u - > handle ;
FORM * form = & q_u - > form ;
2001-04-04 03:09:04 +04:00
nt_forms_struct tmpForm ;
2002-02-09 07:10:24 +03:00
int snum ;
WERROR status = WERR_OK ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int count = 0 ;
2000-02-07 19:17:59 +03:00
nt_forms_struct * list = NULL ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_setform \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_setform: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-07 19:17:59 +03:00
}
2002-01-31 14:44:00 +03:00
2002-09-25 19:19:00 +04:00
/* forms can be modified on printer of on the print server handle */
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
{
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
goto done ;
}
2002-01-31 14:44:00 +03:00
2002-09-25 19:19:00 +04:00
if ( ! ( Printer - > access_granted & ( PRINTER_ACCESS_ADMINISTER | SERVER_ACCESS_ADMINISTER ) ) ) {
2002-03-07 04:02:48 +03:00
DEBUG ( 2 , ( " _spoolss_setform: denied by handle permissions \n " ) ) ;
2002-09-25 19:19:00 +04:00
status = WERR_ACCESS_DENIED ;
goto done ;
2002-01-31 14:44:00 +03:00
}
2001-04-04 03:09:04 +04:00
/* can't set if builtin */
if ( get_a_builtin_ntform ( & form - > name , & tmpForm ) ) {
2002-09-25 19:19:00 +04:00
status = WERR_INVALID_PARAM ;
goto done ;
2001-04-04 03:09:04 +04:00
}
2002-09-25 19:19:00 +04:00
count = get_ntforms ( & list ) ;
2000-02-07 19:17:59 +03:00
update_a_form ( & list , form , count ) ;
write_ntforms ( & list , count ) ;
2002-02-09 07:10:24 +03:00
/*
2002-09-25 19:19:00 +04:00
* ChangeID must always be set if this is a printer
2002-02-09 07:10:24 +03:00
*/
2002-09-25 19:19:00 +04:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
status = mod_a_printer ( * printer , 2 ) ;
2002-02-09 07:10:24 +03:00
done :
2002-09-25 19:19:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( list ) ;
2001-03-03 08:27:26 +03:00
2002-09-25 19:19:00 +04:00
return status ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
enumprintprocessors level 1.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprintprocessors_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
PRINTPROCESSOR_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_1 = ( PRINTPROCESSOR_1 * ) malloc ( sizeof ( PRINTPROCESSOR_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
2000-02-15 21:07:45 +03:00
( * returned ) = 0x1 ;
2000-07-27 04:47:19 +04:00
init_unistr ( & info_1 - > name , " winprint " ) ;
2000-02-15 21:07:45 +03:00
* needed + = spoolss_size_printprocessor_info_1 ( info_1 ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
smb_io_printprocessor_info_1 ( " " , buffer , info_1 , 0 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info_1 ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumprintprocessors ( pipes_struct * p , SPOOL_Q_ENUMPRINTPROCESSORS * q_u , SPOOL_R_ENUMPRINTPROCESSORS * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
2002-07-15 14:35:28 +04:00
NEW_BUFFER * buffer = NULL ;
2001-03-01 00:19:31 +03:00
uint32 offered = q_u - > offered ;
2002-07-15 14:35:28 +04:00
uint32 * needed = & r_u - > needed ;
2001-03-01 00:19:31 +03:00
uint32 * returned = & r_u - > returned ;
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_enumprintprocessors \n " ) ) ;
2000-11-18 02:10:56 +03:00
/*
2000-02-07 19:17:59 +03:00
* Enumerate the print processors . . .
*
* Just reply with " winprint " , to keep NT happy
* and I can use my nice printer checker .
*/
2000-02-15 21:07:45 +03:00
* returned = 0 ;
* needed = 0 ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
switch ( level ) {
case 1 :
return enumprintprocessors_level_1 ( buffer , offered , needed , returned ) ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
2000-02-27 02:01:02 +03:00
}
/****************************************************************************
enumprintprocdatatypes level 1.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprintprocdatatypes_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-27 02:01:02 +03:00
{
PRINTPROCDATATYPE_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_1 = ( PRINTPROCDATATYPE_1 * ) malloc ( sizeof ( PRINTPROCDATATYPE_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
2000-02-27 02:01:02 +03:00
( * returned ) = 0x1 ;
2000-07-27 04:47:19 +04:00
init_unistr ( & info_1 - > name , " RAW " ) ;
2000-02-27 02:01:02 +03:00
* needed + = spoolss_size_printprocdatatype_info_1 ( info_1 ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-27 02:01:02 +03:00
smb_io_printprocdatatype_info_1 ( " " , buffer , info_1 , 0 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info_1 ) ;
2000-02-27 02:01:02 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-27 02:01:02 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-27 02:01:02 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-27 02:01:02 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumprintprocdatatypes ( pipes_struct * p , SPOOL_Q_ENUMPRINTPROCDATATYPES * q_u , SPOOL_R_ENUMPRINTPROCDATATYPES * r_u )
2000-02-27 02:01:02 +03:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
uint32 * returned = & r_u - > returned ;
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-02-27 02:01:02 +03:00
DEBUG ( 5 , ( " _spoolss_enumprintprocdatatypes \n " ) ) ;
* returned = 0 ;
* needed = 0 ;
switch ( level ) {
case 1 :
return enumprintprocdatatypes_level_1 ( buffer , offered , needed , returned ) ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-27 02:01:02 +03:00
}
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
/****************************************************************************
enumprintmonitors level 1.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprintmonitors_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
PRINTMONITOR_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_1 = ( PRINTMONITOR_1 * ) malloc ( sizeof ( PRINTMONITOR_1 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
2000-02-15 21:07:45 +03:00
( * returned ) = 0x1 ;
2000-07-27 04:47:19 +04:00
init_unistr ( & info_1 - > name , " Local Port " ) ;
2000-02-15 21:07:45 +03:00
* needed + = spoolss_size_printmonitor_info_1 ( info_1 ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
smb_io_printmonitor_info_1 ( " " , buffer , info_1 , 0 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info_1 ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
enumprintmonitors level 2.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR enumprintmonitors_level_2 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-02-15 21:07:45 +03:00
{
PRINTMONITOR_2 * info_2 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_2 = ( PRINTMONITOR_2 * ) malloc ( sizeof ( PRINTMONITOR_2 ) ) ) = = NULL )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
2000-02-15 21:07:45 +03:00
( * returned ) = 0x1 ;
2000-07-27 04:47:19 +04:00
init_unistr ( & info_2 - > name , " Local Port " ) ;
init_unistr ( & info_2 - > environment , " Windows NT X86 " ) ;
init_unistr ( & info_2 - > dll_name , " localmon.dll " ) ;
2000-02-15 21:07:45 +03:00
* needed + = spoolss_size_printmonitor_info_2 ( info_2 ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
smb_io_printmonitor_info_2 ( " " , buffer , info_2 , 0 ) ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info_2 ) ;
2000-02-15 21:07:45 +03:00
if ( * needed > offered ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-15 21:07:45 +03:00
}
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_enumprintmonitors ( pipes_struct * p , SPOOL_Q_ENUMPRINTMONITORS * q_u , SPOOL_R_ENUMPRINTMONITORS * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
uint32 level = q_u - > level ;
2002-07-15 14:35:28 +04:00
NEW_BUFFER * buffer = NULL ;
2001-03-01 00:19:31 +03:00
uint32 offered = q_u - > offered ;
2002-07-15 14:35:28 +04:00
uint32 * needed = & r_u - > needed ;
2001-03-01 00:19:31 +03:00
uint32 * returned = & r_u - > returned ;
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_enumprintmonitors \n " ) ) ;
2000-11-18 02:10:56 +03:00
/*
2000-02-07 19:17:59 +03:00
* Enumerate the print monitors . . .
*
* Just reply with " Local Port " , to keep NT happy
* and I can use my nice printer checker .
*/
2000-02-15 21:07:45 +03:00
* returned = 0 ;
* needed = 0 ;
2000-02-07 19:17:59 +03:00
2000-02-15 21:07:45 +03:00
switch ( level ) {
case 1 :
return enumprintmonitors_level_1 ( buffer , offered , needed , returned ) ;
case 2 :
return enumprintmonitors_level_2 ( buffer , offered , needed , returned ) ;
default :
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-15 21:07:45 +03:00
}
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR getjob_level_1 ( print_queue_struct * queue , int count , int snum , uint32 jobid , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
int i = 0 ;
BOOL found = False ;
JOB_INFO_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
2000-02-21 04:58:13 +03:00
info_1 = ( JOB_INFO_1 * ) malloc ( sizeof ( JOB_INFO_1 ) ) ;
if ( info_1 = = NULL ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-02-21 04:58:13 +03:00
}
2002-09-25 19:19:00 +04:00
for ( i = 0 ; i < count & & found = = False ; i + + ) {
2000-02-21 04:58:13 +03:00
if ( queue [ i ] . job = = ( int ) jobid )
found = True ;
}
if ( found = = False ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( queue ) ;
SAFE_FREE ( info_1 ) ;
2001-11-22 08:56:09 +03:00
/* NT treats not found as bad param... yet another bad choice */
return WERR_INVALID_PARAM ;
2000-02-21 04:58:13 +03:00
}
2000-04-06 20:23:04 +04:00
fill_job_info_1 ( info_1 , & ( queue [ i - 1 ] ) , i , snum ) ;
2000-02-21 04:58:13 +03:00
* needed + = spoolss_size_job_info_1 ( info_1 ) ;
2000-04-06 20:23:04 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info_1 ) ;
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-04-06 20:23:04 +04:00
}
2000-02-21 04:58:13 +03:00
2001-03-28 20:08:00 +04:00
smb_io_job_info_1 ( " " , buffer , info_1 , 0 ) ;
2000-02-21 04:58:13 +03:00
2001-09-17 14:26:23 +04:00
SAFE_FREE ( info_1 ) ;
2000-02-21 04:58:13 +03:00
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2001-09-03 14:38:13 +04:00
return WERR_OK ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-07 04:02:48 +03:00
2001-09-03 14:38:13 +04:00
static WERROR getjob_level_2 ( print_queue_struct * queue , int count , int snum , uint32 jobid , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
2002-09-25 19:19:00 +04:00
int i = 0 ;
BOOL found = False ;
JOB_INFO_2 * info_2 ;
2001-01-18 01:55:02 +03:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2002-09-25 19:19:00 +04:00
WERROR ret ;
DEVICEMODE * devmode = NULL ;
NT_DEVICEMODE * nt_devmode = NULL ;
2001-01-18 01:55:02 +03:00
2000-02-21 04:58:13 +03:00
info_2 = ( JOB_INFO_2 * ) malloc ( sizeof ( JOB_INFO_2 ) ) ;
2000-06-16 12:18:09 +04:00
ZERO_STRUCTP ( info_2 ) ;
2000-02-21 04:58:13 +03:00
if ( info_2 = = NULL ) {
2002-02-26 02:18:05 +03:00
ret = WERR_NOMEM ;
goto done ;
2000-02-21 04:58:13 +03:00
}
2002-09-25 19:19:00 +04:00
for ( i = 0 ; i < count & & found = = False ; i + + )
{
if ( queue [ i ] . job = = ( int ) jobid )
found = True ;
2000-02-21 04:58:13 +03:00
}
2002-09-25 19:19:00 +04:00
if ( ! found )
{
2002-02-26 02:18:05 +03:00
/* NT treats not found as bad param... yet another bad
choice */
ret = WERR_INVALID_PARAM ;
goto done ;
2000-02-21 04:58:13 +03:00
}
2001-09-04 11:13:01 +04:00
ret = get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ;
2002-02-26 02:18:05 +03:00
if ( ! W_ERROR_IS_OK ( ret ) )
goto done ;
2002-09-25 19:19:00 +04:00
/*
* if the print job does not have a DEVMODE associated with it ,
* just use the one for the printer
*/
if ( ! ( nt_devmode = print_job_devmode ( snum , jobid ) ) )
devmode = construct_dev_mode ( snum ) ;
else {
if ( ( devmode = ( DEVICEMODE * ) malloc ( sizeof ( DEVICEMODE ) ) ) ! = NULL ) {
ZERO_STRUCTP ( devmode ) ;
convert_nt_devicemode ( devmode , nt_devmode ) ;
}
}
if ( ! devmode ) {
2002-02-26 02:18:05 +03:00
ret = WERR_NOMEM ;
goto done ;
2001-01-18 01:55:02 +03:00
}
2002-02-26 02:18:05 +03:00
fill_job_info_2 ( info_2 , & ( queue [ i - 1 ] ) , i , snum , ntprinter , devmode ) ;
2000-02-21 04:58:13 +03:00
* needed + = spoolss_size_job_info_2 ( info_2 ) ;
2000-04-06 20:23:04 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
2002-02-26 02:18:05 +03:00
ret = WERR_INSUFFICIENT_BUFFER ;
goto done ;
2000-04-06 20:23:04 +04:00
}
2000-02-21 04:58:13 +03:00
2001-03-28 20:08:00 +04:00
smb_io_job_info_2 ( " " , buffer , info_2 , 0 ) ;
2000-02-21 04:58:13 +03:00
2002-02-26 02:18:05 +03:00
if ( * needed > offered ) {
ret = WERR_INSUFFICIENT_BUFFER ;
goto done ;
}
2000-02-21 04:58:13 +03:00
2002-02-26 02:18:05 +03:00
ret = WERR_OK ;
done :
/* Cleanup allocated memory */
2001-09-03 14:38:13 +04:00
2002-02-26 02:18:05 +03:00
free_job_info_2 ( info_2 ) ; /* Also frees devmode */
SAFE_FREE ( info_2 ) ;
free_a_printer ( & ntprinter , 2 ) ;
2002-07-15 14:35:28 +04:00
2002-02-26 02:18:05 +03:00
return ret ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-09-03 14:38:13 +04:00
WERROR _spoolss_getjob ( pipes_struct * p , SPOOL_Q_GETJOB * q_u , SPOOL_R_GETJOB * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 jobid = q_u - > jobid ;
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
2002-09-25 19:19:00 +04:00
WERROR wstatus = WERR_OK ;
2001-03-01 00:19:31 +03:00
2000-02-07 19:17:59 +03:00
int snum ;
int count ;
2002-09-25 19:19:00 +04:00
print_queue_struct * queue = NULL ;
2000-02-07 19:17:59 +03:00
print_status_struct prt_status ;
2001-03-01 00:19:31 +03:00
/* that's an [in out] buffer */
2001-03-27 22:19:01 +04:00
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
2001-03-01 00:19:31 +03:00
buffer = r_u - > buffer ;
2000-02-21 04:58:13 +03:00
DEBUG ( 5 , ( " spoolss_getjob \n " ) ) ;
2000-02-07 19:17:59 +03:00
2002-09-25 19:19:00 +04:00
* needed = 0 ;
2000-02-21 04:58:13 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-09-03 14:38:13 +04:00
return WERR_BADFID ;
2000-02-21 04:58:13 +03:00
2000-04-16 10:20:43 +04:00
count = print_queue_status ( snum , & queue , & prt_status ) ;
2000-02-07 19:17:59 +03:00
DEBUGADD ( 4 , ( " count:[%d], prt_status:[%d], [%s] \n " ,
count , prt_status . status , prt_status . message ) ) ;
2000-02-21 04:58:13 +03:00
2002-09-25 19:19:00 +04:00
switch ( level ) {
2000-02-21 04:58:13 +03:00
case 1 :
2002-09-25 19:19:00 +04:00
wstatus = getjob_level_1 ( queue , count , snum , jobid ,
buffer , offered , needed ) ;
break ;
2000-02-21 04:58:13 +03:00
case 2 :
2002-09-25 19:19:00 +04:00
wstatus = getjob_level_2 ( queue , count , snum , jobid ,
buffer , offered , needed ) ;
break ;
2000-02-21 04:58:13 +03:00
default :
2002-09-25 19:19:00 +04:00
wstatus = WERR_UNKNOWN_LEVEL ;
break ;
2000-02-07 19:17:59 +03:00
}
2002-09-25 19:19:00 +04:00
SAFE_FREE ( queue ) ;
return wstatus ;
2000-02-07 19:17:59 +03:00
}
2001-11-05 09:15:02 +03:00
/********************************************************************
2002-09-25 19:19:00 +04:00
spoolss_getprinterdataex
From MSDN documentation of GetPrinterDataEx : pass request
to GetPrinterData if key is " PrinterDriverData " .
2001-11-05 09:15:02 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_getprinterdataex ( pipes_struct * p , SPOOL_Q_GETPRINTERDATAEX * q_u , SPOOL_R_GETPRINTERDATAEX * r_u )
{
2001-11-22 08:56:09 +03:00
POLICY_HND * handle = & q_u - > handle ;
uint32 in_size = q_u - > size ;
uint32 * type = & r_u - > type ;
uint32 * out_size = & r_u - > size ;
uint8 * * data = & r_u - > data ;
uint32 * needed = & r_u - > needed ;
2002-09-25 19:19:00 +04:00
fstring keyname , valuename ;
2001-11-22 08:56:09 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2002-09-25 19:19:00 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status = WERR_OK ;
2001-11-22 08:56:09 +03:00
DEBUG ( 4 , ( " _spoolss_getprinterdataex \n " ) ) ;
2001-11-05 09:15:02 +03:00
2002-09-25 19:19:00 +04:00
unistr2_to_ascii ( keyname , & q_u - > keyname , sizeof ( keyname ) - 1 ) ;
unistr2_to_ascii ( valuename , & q_u - > valuename , sizeof ( valuename ) - 1 ) ;
DEBUG ( 10 , ( " _spoolss_getprinterdataex: key => [%s], value => [%s] \n " ,
keyname , valuename ) ) ;
2001-11-05 09:15:02 +03:00
2001-11-22 08:56:09 +03:00
/* in case of problem, return some default values */
2002-09-25 19:19:00 +04:00
* needed = 0 ;
* type = 0 ;
* out_size = in_size ;
2001-11-22 08:56:09 +03:00
if ( ! Printer ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 2 , ( " _spoolss_getprinterdataex: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
status = WERR_BADFID ;
goto done ;
2001-11-22 08:56:09 +03:00
}
/* Is the handle to a printer or to the server? */
2002-09-25 19:19:00 +04:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTSERVER ) {
2001-11-22 08:56:09 +03:00
DEBUG ( 10 , ( " _spoolss_getprinterdatex: Not implemented for server handles yet \n " ) ) ;
2002-09-25 19:19:00 +04:00
status = WERR_INVALID_PARAM ;
goto done ;
2001-11-22 08:56:09 +03:00
}
2002-09-25 19:19:00 +04:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
2001-11-22 08:56:09 +03:00
2002-09-25 19:19:00 +04:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
goto done ;
/* check to see if the keyname is valid */
if ( ! strlen ( keyname ) ) {
status = WERR_INVALID_PARAM ;
goto done ;
2001-11-22 08:56:09 +03:00
}
2002-09-25 19:19:00 +04:00
if ( lookup_printerkey ( & printer - > info_2 - > data , keyname ) = = - 1 ) {
DEBUG ( 4 , ( " _spoolss_getprinterdataex: Invalid keyname [%s] \n " , keyname ) ) ;
free_a_printer ( & printer , 2 ) ;
status = WERR_BADFILE ;
goto done ;
}
/* When given a new keyname, we should just create it */
status = get_printer_dataex ( p - > mem_ctx , printer , keyname , valuename , type , data , needed , in_size ) ;
if ( * needed > * out_size )
status = WERR_MORE_DATA ;
done :
if ( ! W_ERROR_IS_OK ( status ) )
{
DEBUG ( 5 , ( " error: allocating %d \n " , * out_size ) ) ;
2001-11-22 08:56:09 +03:00
/* reply this param doesn't exist */
2002-09-25 19:19:00 +04:00
if ( * out_size )
{
if ( ( * data = ( uint8 * ) talloc_zero ( p - > mem_ctx , * out_size * sizeof ( uint8 ) ) ) = = NULL ) {
status = WERR_NOMEM ;
goto done ;
}
}
else {
2001-11-22 08:56:09 +03:00
* data = NULL ;
2002-09-25 19:19:00 +04:00
}
2001-11-22 08:56:09 +03:00
}
2002-09-25 19:19:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
return status ;
2001-11-05 09:15:02 +03:00
}
/********************************************************************
2002-09-25 19:19:00 +04:00
* spoolss_setprinterdataex
2001-11-05 09:15:02 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_setprinterdataex ( pipes_struct * p , SPOOL_Q_SETPRINTERDATAEX * q_u , SPOOL_R_SETPRINTERDATAEX * r_u )
{
2002-09-25 19:19:00 +04:00
POLICY_HND * handle = & q_u - > handle ;
uint32 type = q_u - > type ;
uint8 * data = q_u - > data ;
uint32 real_len = q_u - > real_len ;
2001-11-05 09:15:02 +03:00
2002-09-25 19:19:00 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status = WERR_OK ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
fstring valuename ;
fstring keyname ;
char * oid_string ;
2001-11-22 08:56:09 +03:00
DEBUG ( 4 , ( " _spoolss_setprinterdataex \n " ) ) ;
2001-11-05 09:15:02 +03:00
/* From MSDN documentation of SetPrinterDataEx: pass request to
SetPrinterData if key is " PrinterDriverData " */
2002-09-25 19:19:00 +04:00
if ( ! Printer ) {
DEBUG ( 2 , ( " _spoolss_setprinterdata: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
return WERR_BADFID ;
}
2001-11-05 09:15:02 +03:00
2002-09-25 19:19:00 +04:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
/*
* Access check : NT returns " access denied " if you make a
* SetPrinterData call without the necessary privildge .
* we were originally returning OK if nothing changed
* which made Win2k issue * * a lot * * of SetPrinterData
* when connecting to a printer - - jerry
*/
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER )
{
DEBUG ( 3 , ( " _spoolss_setprinterdataex: change denied by handle access permissions \n " ) ) ;
return WERR_ACCESS_DENIED ;
}
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
return status ;
unistr2_to_ascii ( valuename , & q_u - > value , sizeof ( valuename ) - 1 ) ;
unistr2_to_ascii ( keyname , & q_u - > key , sizeof ( keyname ) - 1 ) ;
/* check for OID in valuename */
if ( ( oid_string = strchr ( valuename , ' , ' ) ) ! = NULL )
{
* oid_string = ' \0 ' ;
oid_string + + ;
}
/* save the registry data */
status = set_printer_dataex ( printer , keyname , valuename , type , data , real_len ) ;
/* save the OID if one was specified and the previous set call succeeded */
if ( W_ERROR_IS_OK ( status ) & & oid_string )
{
fstrcat ( keyname , " \\ " ) ;
fstrcat ( keyname , SPOOL_OID_KEY ) ;
2001-11-22 08:56:09 +03:00
2002-09-25 19:19:00 +04:00
/*
* I ' m not checking the status here on purpose . Don ' t know
* if this is right , but I ' m returning the status from the
* previous set_printer_dataex ( ) call . I have no idea if
* this is right . - - jerry
*/
set_printer_dataex ( printer , keyname , valuename ,
REG_SZ , ( void * ) oid_string , strlen ( oid_string ) + 1 ) ;
}
free_a_printer ( & printer , 2 ) ;
return status ;
2001-11-22 08:56:09 +03:00
}
2002-07-15 14:35:28 +04:00
/********************************************************************
* spoolss_deleteprinterdataex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_deleteprinterdataex ( pipes_struct * p , SPOOL_Q_DELETEPRINTERDATAEX * q_u , SPOOL_R_DELETEPRINTERDATAEX * r_u )
{
2002-09-25 19:19:00 +04:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * value = & q_u - > valuename ;
UNISTR2 * key = & q_u - > keyname ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status = WERR_OK ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
pstring valuename , keyname ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
DEBUG ( 5 , ( " spoolss_deleteprinterdataex \n " ) ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( ! Printer ) {
DEBUG ( 2 , ( " _spoolss_deleteprinterdata: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
return WERR_BADFID ;
}
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER ) {
DEBUG ( 3 , ( " _spoolss_deleteprinterdataex: printer properties change denied by handle \n " ) ) ;
return WERR_ACCESS_DENIED ;
}
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
return status ;
unistr2_to_ascii ( valuename , value , sizeof ( valuename ) - 1 ) ;
unistr2_to_ascii ( keyname , key , sizeof ( keyname ) - 1 ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
status = delete_printer_dataex ( printer , keyname , valuename ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
free_a_printer ( & printer , 2 ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
return status ;
}
2002-07-15 14:35:28 +04:00
2001-11-22 08:56:09 +03:00
/********************************************************************
* spoolss_enumprinterkey
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_enumprinterkey ( pipes_struct * p , SPOOL_Q_ENUMPRINTERKEY * q_u , SPOOL_R_ENUMPRINTERKEY * r_u )
{
2002-09-25 19:19:00 +04:00
fstring key ;
fstring * keynames = NULL ;
uint16 * enumkeys = NULL ;
int num_keys ;
int printerkey_len ;
POLICY_HND * handle = & q_u - > handle ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
NT_PRINTER_DATA * data ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status = WERR_BADFILE ;
2001-11-22 08:56:09 +03:00
DEBUG ( 4 , ( " _spoolss_enumprinterkey \n " ) ) ;
2001-11-05 09:15:02 +03:00
2002-09-25 19:19:00 +04:00
if ( ! Printer ) {
DEBUG ( 2 , ( " _spoolss_enumprinterkey: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
return WERR_BADFID ;
}
2001-11-22 08:56:09 +03:00
2002-09-25 19:19:00 +04:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
return status ;
2002-08-17 19:34:15 +04:00
2002-09-25 19:19:00 +04:00
/* get the list of subkey names */
2001-11-22 08:56:09 +03:00
2002-09-25 19:19:00 +04:00
unistr2_to_ascii ( key , & q_u - > key , sizeof ( key ) - 1 ) ;
data = & printer - > info_2 - > data ;
2001-12-13 19:35:43 +03:00
2002-09-25 19:19:00 +04:00
num_keys = get_printer_subkeys ( data , key , & keynames ) ;
if ( num_keys = = - 1 ) {
status = WERR_BADFILE ;
goto done ;
2001-11-22 08:56:09 +03:00
}
2002-09-25 19:19:00 +04:00
printerkey_len = init_unistr_array ( & enumkeys , keynames , NULL ) ;
r_u - > needed = printerkey_len * 2 ;
if ( q_u - > size < r_u - > needed ) {
status = WERR_MORE_DATA ;
goto done ;
2001-11-22 08:56:09 +03:00
}
2002-09-25 19:19:00 +04:00
if ( ! make_spoolss_buffer5 ( p - > mem_ctx , & r_u - > keys , printerkey_len , enumkeys ) ) {
status = WERR_NOMEM ;
goto done ;
}
status = WERR_OK ;
if ( q_u - > size < r_u - > needed )
status = WERR_MORE_DATA ;
done :
free_a_printer ( & printer , 2 ) ;
SAFE_FREE ( keynames ) ;
return status ;
2001-11-22 08:56:09 +03:00
}
2002-07-15 14:35:28 +04:00
/********************************************************************
* spoolss_deleteprinterkey
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_deleteprinterkey ( pipes_struct * p , SPOOL_Q_DELETEPRINTERKEY * q_u , SPOOL_R_DELETEPRINTERKEY * r_u )
{
2002-09-25 19:19:00 +04:00
POLICY_HND * handle = & q_u - > handle ;
Printer_entry * Printer = find_printer_index_by_hnd ( p , & q_u - > handle ) ;
fstring key ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
int snum = 0 ;
WERROR status ;
DEBUG ( 5 , ( " spoolss_deleteprinterkey \n " ) ) ;
2002-07-15 14:35:28 +04:00
if ( ! Printer ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 2 , ( " _spoolss_deleteprinterkey: Invalid handle (%s:%u:%u). \n " , OUR_HANDLE ( handle ) ) ) ;
2002-07-15 14:35:28 +04:00
return WERR_BADFID ;
}
2002-09-25 19:19:00 +04:00
/* if keyname == NULL, return error */
if ( ! q_u - > keyname . buffer )
return WERR_INVALID_PARAM ;
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
if ( Printer - > access_granted ! = PRINTER_ACCESS_ADMINISTER ) {
DEBUG ( 3 , ( " _spoolss_deleteprinterkey: printer properties change denied by handle \n " ) ) ;
return WERR_ACCESS_DENIED ;
}
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
return status ;
/* delete the key and all subneys */
2002-07-15 14:35:28 +04:00
unistr2_to_ascii ( key , & q_u - > keyname , sizeof ( key ) - 1 ) ;
2002-09-25 19:19:00 +04:00
status = delete_all_printer_data ( printer - > info_2 , key ) ;
2002-07-15 14:35:28 +04:00
2002-09-25 19:19:00 +04:00
if ( W_ERROR_IS_OK ( status ) )
status = mod_a_printer ( * printer , 2 ) ;
free_a_printer ( & printer , 2 ) ;
return status ;
2002-07-15 14:35:28 +04:00
}
2001-11-22 08:56:09 +03:00
/********************************************************************
* spoolss_enumprinterdataex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _spoolss_enumprinterdataex ( pipes_struct * p , SPOOL_Q_ENUMPRINTERDATAEX * q_u , SPOOL_R_ENUMPRINTERDATAEX * r_u )
{
POLICY_HND * handle = & q_u - > handle ;
uint32 in_size = q_u - > size ;
uint32 num_entries ,
needed ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
PRINTER_ENUM_VALUES * enum_values = NULL ;
2002-08-17 19:34:15 +04:00
NT_PRINTER_DATA * p_data ;
fstring key ;
2001-11-22 08:56:09 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
int snum ;
WERROR result ;
2002-08-17 19:34:15 +04:00
int key_index ;
int i ;
REGISTRY_VALUE * val ;
char * value_name ;
int data_len ;
2001-11-22 08:56:09 +03:00
DEBUG ( 4 , ( " _spoolss_enumprinterdataex \n " ) ) ;
if ( ! Printer ) {
2002-02-09 07:10:24 +03:00
DEBUG ( 2 , ( " _spoolss_enumprinterdata: Invalid handle (%s:%u:%u1<). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-11-22 08:56:09 +03:00
return WERR_BADFID ;
}
2002-08-17 19:34:15 +04:00
/* first get the printer off of disk */
2001-11-22 08:56:09 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
return WERR_BADFID ;
ZERO_STRUCT ( printer ) ;
result = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( ! W_ERROR_IS_OK ( result ) )
return result ;
2002-08-17 19:34:15 +04:00
/* now look for a match on the key name */
p_data = & printer - > info_2 - > data ;
unistr2_to_ascii ( key , & q_u - > key , sizeof ( key ) - 1 ) ;
if ( ( key_index = lookup_printerkey ( p_data , key ) ) = = - 1 )
{
DEBUG ( 10 , ( " _spoolss_enumprinterdataex: Unknown keyname [%s] \n " , key ) ) ;
result = WERR_INVALID_PARAM ;
goto done ;
}
2001-11-22 08:56:09 +03:00
result = WERR_OK ;
2002-08-17 19:34:15 +04:00
needed = 0 ;
2001-11-22 08:56:09 +03:00
2002-08-17 19:34:15 +04:00
/* allocate the memory for the array of pointers -- if necessary */
num_entries = regval_ctr_numvals ( & p_data - > keys [ key_index ] . values ) ;
if ( num_entries )
2001-11-22 08:56:09 +03:00
{
2002-08-17 19:34:15 +04:00
if ( ( enum_values = talloc ( p - > mem_ctx , num_entries * sizeof ( PRINTER_ENUM_VALUES ) ) ) = = NULL )
2001-11-22 08:56:09 +03:00
{
2002-08-17 19:34:15 +04:00
DEBUG ( 0 , ( " _spoolss_enumprinterdataex: talloc() failed to allocate memory for [%d] bytes! \n " ,
num_entries * sizeof ( PRINTER_ENUM_VALUES ) ) ) ;
2001-11-22 08:56:09 +03:00
result = WERR_NOMEM ;
goto done ;
}
2002-08-17 19:34:15 +04:00
memset ( enum_values , 0x0 , num_entries * sizeof ( PRINTER_ENUM_VALUES ) ) ;
}
/*
* loop through all params and build the array to pass
* back to the client
*/
for ( i = 0 ; i < num_entries ; i + + )
{
/* lookup the registry value */
val = regval_ctr_specific_value ( & p_data - > keys [ key_index ] . values , i ) ;
DEBUG ( 10 , ( " retrieved value number [%d] [%s] \n " , i , regval_name ( val ) ) ) ;
2001-11-22 08:56:09 +03:00
/* copy the data */
2002-08-17 19:34:15 +04:00
value_name = regval_name ( val ) ;
init_unistr ( & enum_values [ i ] . valuename , value_name ) ;
enum_values [ i ] . value_len = ( strlen ( value_name ) + 1 ) * 2 ;
enum_values [ i ] . type = regval_type ( val ) ;
data_len = regval_size ( val ) ;
if ( data_len ) {
if ( ! ( enum_values [ i ] . data = talloc_memdup ( p - > mem_ctx , regval_data_p ( val ) , data_len ) ) )
{
DEBUG ( 0 , ( " talloc_memdup failed to allocate memory [data_len=%d] for data! \n " ,
data_len ) ) ;
result = WERR_NOMEM ;
goto done ;
}
2001-11-22 08:56:09 +03:00
}
2002-08-17 19:34:15 +04:00
enum_values [ i ] . data_len = data_len ;
2001-11-22 08:56:09 +03:00
/* keep track of the size of the array in bytes */
2002-08-17 19:34:15 +04:00
needed + = spoolss_size_printer_enum_values ( & enum_values [ i ] ) ;
2001-11-22 08:56:09 +03:00
}
2002-08-17 19:34:15 +04:00
/* housekeeping information in the reply */
r_u - > needed = needed ;
r_u - > returned = num_entries ;
2001-11-22 08:56:09 +03:00
if ( needed > in_size ) {
result = WERR_MORE_DATA ;
goto done ;
}
/* copy data into the reply */
r_u - > ctr . size = r_u - > needed ;
r_u - > ctr . size_of_array = r_u - > returned ;
r_u - > ctr . values = enum_values ;
done :
free_a_printer ( & printer , 2 ) ;
return result ;
2001-11-05 09:15:02 +03:00
}
2001-11-22 08:56:09 +03:00
2001-12-10 08:03:17 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void fill_printprocessordirectory_1 ( PRINTPROCESSOR_DIRECTORY_1 * info , char * name )
{
init_unistr ( & info - > name , name ) ;
}
static WERROR getprintprocessordirectory_level_1 ( UNISTR2 * name ,
UNISTR2 * environment ,
NEW_BUFFER * buffer ,
uint32 offered ,
uint32 * needed )
{
pstring path ;
pstring long_archi ;
pstring short_archi ;
PRINTPROCESSOR_DIRECTORY_1 * info = NULL ;
unistr2_to_ascii ( long_archi , environment , sizeof ( long_archi ) - 1 ) ;
2002-07-15 14:35:28 +04:00
if ( get_short_archi ( short_archi , long_archi ) = = False )
2001-12-10 08:03:17 +03:00
return WERR_INVALID_ENVIRONMENT ;
if ( ( info = ( PRINTPROCESSOR_DIRECTORY_1 * ) malloc ( sizeof ( PRINTPROCESSOR_DIRECTORY_1 ) ) ) = = NULL )
return WERR_NOMEM ;
2002-04-22 22:48:45 +04:00
pstrcpy ( path , " C: \\ WINNT \\ System32 \\ spool \\ PRTPROCS \\ W32X86 " ) ;
2001-12-10 08:03:17 +03:00
fill_printprocessordirectory_1 ( info , path ) ;
* needed + = spoolss_size_printprocessordirectory_info_1 ( info ) ;
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
safe_free ( info ) ;
return WERR_INSUFFICIENT_BUFFER ;
}
smb_io_printprocessordirectory_1 ( " " , buffer , info , 0 ) ;
2001-11-22 08:56:09 +03:00
2001-12-10 08:03:17 +03:00
safe_free ( info ) ;
if ( * needed > offered )
return WERR_INSUFFICIENT_BUFFER ;
else
return WERR_OK ;
}
WERROR _spoolss_getprintprocessordirectory ( pipes_struct * p , SPOOL_Q_GETPRINTPROCESSORDIRECTORY * q_u , SPOOL_R_GETPRINTPROCESSORDIRECTORY * r_u )
{
uint32 level = q_u - > level ;
NEW_BUFFER * buffer = NULL ;
uint32 offered = q_u - > offered ;
uint32 * needed = & r_u - > needed ;
2002-07-15 14:35:28 +04:00
WERROR result ;
2001-12-10 08:03:17 +03:00
/* that's an [in out] buffer */
spoolss_move_buffer ( q_u - > buffer , & r_u - > buffer ) ;
buffer = r_u - > buffer ;
DEBUG ( 5 , ( " _spoolss_getprintprocessordirectory \n " ) ) ;
* needed = 0 ;
switch ( level ) {
case 1 :
2002-07-15 14:35:28 +04:00
result = getprintprocessordirectory_level_1
2001-12-10 08:03:17 +03:00
( & q_u - > name , & q_u - > environment , buffer , offered , needed ) ;
2002-10-03 02:55:28 +04:00
break ;
2001-12-10 08:03:17 +03:00
default :
2002-07-15 14:35:28 +04:00
result = WERR_UNKNOWN_LEVEL ;
2001-12-10 08:03:17 +03:00
}
2002-07-15 14:35:28 +04:00
return result ;
2001-12-10 08:03:17 +03:00
}
2002-08-17 19:34:15 +04:00
#if 0
WERROR _spoolss_replyopenprinter ( pipes_struct * p , SPOOL_Q_REPLYOPENPRINTER * q_u ,
SPOOL_R_REPLYOPENPRINTER * r_u )
{
DEBUG ( 5 , ( " _spoolss_replyopenprinter \n " ) ) ;
DEBUG ( 10 , ( " replyopenprinter for localprinter %d \n " , q_u - > printer ) ) ;
return WERR_OK ;
}
WERROR _spoolss_replycloseprinter ( pipes_struct * p , SPOOL_Q_REPLYCLOSEPRINTER * q_u ,
SPOOL_R_REPLYCLOSEPRINTER * r_u )
{
DEBUG ( 5 , ( " _spoolss_replycloseprinter \n " ) ) ;
return WERR_OK ;
}
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
# endif