2000-11-18 02:10:56 +03:00
/*
2000-02-07 19:17:59 +03:00
* Unix SMB / Netbios implementation .
* Version 1.9 .
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 2000 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 2000 ,
* Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998 - 2000.
2001-02-28 04:38:12 +03:00
* Copyright ( C ) Jeremy Allison 2001.
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"
extern int DEBUGLEVEL ;
extern pstring global_myname ;
# ifndef MAX_OPEN_PRINTER_EXS
# define MAX_OPEN_PRINTER_EXS 50
# endif
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
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 {
2000-02-24 19:27:06 +03:00
BOOL document_started ;
BOOL page_started ;
2001-04-04 03:09:04 +04:00
int 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 ;
uint32 access ;
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 ;
2000-02-24 19:27:06 +03:00
} notify ;
2000-02-27 01:22:24 +03:00
struct {
fstring machine ;
fstring user ;
} client ;
2000-02-25 02:01:24 +03:00
} Printer_entry ;
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 ;
2000-09-26 01:05:18 +04:00
static struct cli_state cli ;
static uint32 smb_connections = 0 ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
# define OUR_HANDLE(hnd) ((hnd==NULL)?"NULL":(IVAL(hnd->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER"))
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 )
{
SPOOL_NOTIFY_OPTION * sp = * pp ;
* pp = NULL ;
if ( ! sp )
return ;
if ( sp - > ctr . type )
safe_free ( sp - > ctr . type ) ;
free ( sp ) ;
}
2001-03-11 03:32:10 +03:00
/***************************************************************************
Disconnect from the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void srv_spoolss_replycloseprinter ( POLICY_HND * handle )
{
2001-08-27 23:46:22 +04:00
NTSTATUS status ;
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 ;
}
if ( ! cli_spoolss_reply_close_printer ( & cli , handle , & status ) )
DEBUG ( 0 , ( " srv_spoolss_replycloseprinter: reply_close_printer failed. \n " ) ) ;
/* if it's the last connection, deconnect the IPC$ share */
if ( smb_connections = = 1 ) {
if ( ! spoolss_disconnect_from_client ( & cli ) )
return ;
message_deregister ( MSG_PRINTER_NOTIFY ) ;
}
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 ;
safe_free ( Printer ) ;
}
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 ) {
safe_free ( new_sp ) ;
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 ) ) {
DEBUG ( 3 , ( " find_printer_index_by_hnd: Printer handle not found: " ) ) ;
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
/****************************************************************************
close printer index by handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " close_printer_handle: Invalid handle (%s) \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
/****************************************************************************
delete a printer given a handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " delete_printer_handle: Invalid handle (%s) \n " , OUR_HANDLE ( hnd ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-05-02 19:31:55 +04:00
}
2000-07-22 04:48:29 +04:00
if ( del_a_printer ( Printer - > dev . handlename ) ! = 0 ) {
DEBUG ( 3 , ( " Error deleting printer %s \n " , Printer - > dev . handlename ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-05-02 19:31:55 +04:00
}
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ; /* 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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-08-01 00:41:51 +04:00
} else
2001-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-08-01 00:41:51 +04:00
}
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-05-02 19:31:55 +04:00
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
return the snum of a printer corresponding to an handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " get_printer_snum: Invalid handle (%s) \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 ;
}
}
/****************************************************************************
set printer handle type .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL set_printer_hnd_accesstype ( pipes_struct * p , POLICY_HND * hnd , uint32 access_required )
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " set_printer_hnd_accesstype: Invalid handle (%s) " , OUR_HANDLE ( hnd ) ) ) ;
2000-02-07 19:17:59 +03:00
return False ;
}
2000-02-25 02:01:24 +03:00
DEBUG ( 4 , ( " Setting printer access=%x \n " , access_required ) ) ;
Printer - > access = access_required ;
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
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
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
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 ;
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
/*
* store the Samba share name in it
* in back we have the long printer name
* need to iterate all the snum and do a
* get_a_printer each time to find the printer
* faster to do it here than later .
*/
for ( snum = 0 ; snum < n_services & & found = = False ; snum + + ) {
2000-11-14 05:14:58 +03:00
char * printername ;
2000-02-15 21:07:45 +03:00
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 ;
DEBUGADD ( 5 , ( " share:%s \n " , lp_servicename ( snum ) ) ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
2000-02-15 21:07:45 +03:00
continue ;
2001-07-04 11:36:09 +04:00
printername = strchr_m ( printer - > info_2 - > printername + 2 , ' \\ ' ) ;
2000-11-14 05:14:58 +03:00
printername + + ;
2000-11-18 02:10:56 +03:00
DEBUG ( 10 , ( " set_printer_hnd_name: name [%s], aprinter [%s] \n " ,
2000-06-01 06:35:30 +04:00
printer - > info_2 - > printername , aprinter ) ) ;
2000-04-07 02:48:53 +04:00
2000-11-14 05:14:58 +03:00
if ( strlen ( printername ) ! = strlen ( aprinter ) ) {
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-02-15 21:07:45 +03:00
continue ;
}
2000-11-14 05:14:58 +03:00
if ( strncasecmp ( printername , aprinter , strlen ( aprinter ) ) ) {
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-02-15 21:07:45 +03:00
continue ;
}
found = True ;
}
2000-11-18 02:10:56 +03:00
/*
2000-07-22 04:48:29 +04:00
* if we haven ' t found a printer with the given handlename
2000-04-11 01:47:46 +04:00
* then it can be a share name as you can open both \ \ server \ printer and
* \ \ server \ share
*/
/*
* we still check if the printer description file exists as NT won ' t be happy
* if we reply OK in the openprinter call and can ' t reply in the subsequent RPC calls
*/
if ( found = = False ) {
DEBUGADD ( 5 , ( " Printer not found, checking for share now \n " ) ) ;
for ( snum = 0 ; snum < n_services & & found = = False ; snum + + ) {
2000-04-16 10:20:43 +04:00
if ( ! ( lp_snum_ok ( snum ) & & lp_print_ok ( snum ) ) )
2000-04-11 01:47:46 +04:00
continue ;
2000-07-22 04:48:29 +04:00
DEBUGADD ( 5 , ( " set_printer_hnd_name: share:%s \n " , lp_servicename ( snum ) ) ) ;
2000-04-11 01:47:46 +04:00
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
2000-04-11 01:47:46 +04:00
continue ;
2000-11-18 02:10:56 +03:00
DEBUG ( 10 , ( " set_printer_hnd_name: printername [%s], aprinter [%s] \n " ,
2000-06-01 06:35:30 +04:00
printer - > info_2 - > printername , aprinter ) ) ;
2000-04-11 01:47:46 +04:00
if ( strlen ( lp_servicename ( snum ) ) ! = strlen ( aprinter ) ) {
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-04-11 01:47:46 +04:00
continue ;
}
if ( strncasecmp ( lp_servicename ( snum ) , aprinter , strlen ( aprinter ) ) ) {
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-04-11 01:47:46 +04:00
continue ;
}
found = True ;
}
}
if ( found = = False ) {
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
}
2000-02-24 19:27:06 +03:00
snum - - ;
2000-07-22 04:48:29 +04:00
DEBUGADD ( 4 , ( " set_printer_hnd_name: Printer found: %s -> %s[%x] \n " ,
2000-06-24 04:15:08 +04:00
printer - > info_2 - > printername , lp_servicename ( snum ) , snum ) ) ;
2000-07-22 04:48:29 +04:00
ZERO_STRUCT ( Printer - > dev . handlename ) ;
strncpy ( Printer - > dev . handlename , lp_servicename ( snum ) , strlen ( lp_servicename ( snum ) ) ) ;
2000-02-15 21:07:45 +03:00
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
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
/****************************************************************************
find first available printer slot . creates a printer handle for you .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL open_printer_hnd ( pipes_struct * p , POLICY_HND * hnd , char * name )
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 ;
2001-03-11 03:32:10 +03:00
if ( ! create_policy_hnd ( p , hnd , free_printer_entry , new_printer ) ) {
safe_free ( new_printer ) ;
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 ;
}
2001-03-13 23:18:45 +03:00
DEBUG ( 5 , ( " %d printer handles active \n " , ( int ) p - > pipe_handles - > count ) ) ;
2001-01-15 21:36:50 +03:00
2000-07-22 04:48:29 +04:00
return True ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-02-15 21:07:45 +03:00
Return True is the handle is a print server .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL handle_is_printserver ( pipes_struct * p , POLICY_HND * handle )
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 , handle ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer )
2000-02-07 19:17:59 +03:00
return False ;
2000-02-25 02:01:24 +03:00
if ( Printer - > printer_type ! = PRINTER_HANDLE_IS_PRINTSERVER )
2000-02-07 19:17:59 +03:00
return False ;
return True ;
}
2000-02-15 21:07:45 +03:00
/****************************************************************************
allocate more memory for a BUFFER .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
2000-09-26 01:05:18 +04:00
/***************************************************************************
receive the notify message
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
2001-06-13 05:08:27 +04:00
static void srv_spoolss_receive_message ( int msg_type , pid_t src , void * buf , size_t len )
2000-11-18 02:10:56 +03:00
{
2000-09-30 01:15:45 +04:00
fstring printer ;
2001-08-27 23:46:22 +04:00
NTSTATUS status ;
2001-03-11 03:32:10 +03:00
struct pipes_struct * p ;
2001-03-13 23:18:45 +03:00
struct policy * pol ;
struct handle_list * hl ;
2000-09-26 01:05:18 +04:00
2000-09-30 01:15:45 +04:00
* printer = ' \0 ' ;
fstrcpy ( printer , buf ) ;
2000-09-26 14:15:12 +04:00
2000-10-02 23:28:26 +04:00
if ( len = = 0 ) {
DEBUG ( 0 , ( " srv_spoolss_receive_message: got null message ! \n " ) ) ;
return ;
}
DEBUG ( 10 , ( " srv_spoolss_receive_message: Got message about printer %s \n " , printer ) ) ;
2001-03-13 23:18:45 +03:00
/*
* We need to enumerate all printers . The handle list is shared
* across pipes of the same name , so just find the first open
* spoolss pipe .
*/
hl = NULL ;
2001-03-11 03:32:10 +03:00
for ( p = get_first_pipe ( ) ; p ; get_next_pipe ( p ) ) {
2001-03-13 23:18:45 +03:00
if ( strequal ( p - > name , " spoolss " ) ) {
hl = p - > pipe_handles ;
break ;
}
}
2000-09-26 01:05:18 +04:00
2001-03-13 23:18:45 +03:00
if ( ! hl ) {
DEBUG ( 0 , ( " srv_spoolss_receive_message: no handle list on spoolss pipe ! \n " ) ) ;
return ;
}
2000-09-26 01:05:18 +04:00
2001-03-13 23:18:45 +03:00
/* Iterate the printer list on this pipe. */
for ( pol = hl - > Policy ; pol ; pol = pol - > next ) {
Printer_entry * find_printer = ( Printer_entry * ) pol - > data_ptr ;
2000-09-26 01:05:18 +04:00
2001-03-13 23:18:45 +03:00
if ( ! find_printer )
continue ;
2000-09-26 01:05:18 +04:00
2001-03-13 23:18:45 +03:00
/*
* if the entry is the given printer or if it ' s a printerserver
* we send the message
*/
2001-03-11 03:32:10 +03:00
2001-03-13 23:18:45 +03:00
if ( find_printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
if ( strcmp ( find_printer - > dev . handlename , printer ) )
continue ;
2000-09-26 01:05:18 +04:00
2001-03-13 23:18:45 +03:00
if ( find_printer - > notify . client_connected = = True )
cli_spoolss_reply_rrpcn ( & cli , & find_printer - > notify . client_hnd , PRINTER_CHANGE_ALL , 0x0 , & status ) ;
2000-09-26 01:05:18 +04:00
}
}
/***************************************************************************
send a notify event
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL srv_spoolss_sendnotify ( pipes_struct * p , POLICY_HND * handle )
2000-09-26 01:05:18 +04:00
{
fstring printer ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-09-26 01:05:18 +04:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2000-09-26 01:05:18 +04:00
DEBUG ( 0 , ( " srv_spoolss_sendnotify: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
return False ;
}
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTER )
fstrcpy ( printer , Printer - > dev . handlename ) ;
else
fstrcpy ( printer , " " ) ;
2000-09-26 14:15:12 +04:00
/*srv_spoolss_receive_message(printer);*/
2000-10-02 23:28:26 +04:00
DEBUG ( 10 , ( " srv_spoolss_sendnotify: Sending message about printer %s \n " , printer ) ) ;
2000-12-15 04:02:11 +03:00
message_send_all ( conn_tdb_ctx ( ) , MSG_PRINTER_NOTIFY , printer , strlen ( printer ) + 1 , False ) ; /* Null terminate... */
2000-09-26 04:54:18 +04:00
return True ;
2000-09-26 01:05:18 +04:00
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* spoolss_open_printer
*
* called from the spoolss dispatcher
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _spoolss_open_printer_ex ( pipes_struct * p , SPOOL_Q_OPEN_PRINTER_EX * q_u , SPOOL_R_OPEN_PRINTER_EX * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-16 22:21:18 +03:00
#if 0
2001-08-27 23:46:22 +04:00
uint32 result = NT_STATUS_OK ;
2001-02-16 22:21:18 +03:00
# endif
2001-02-28 04:24:55 +03:00
UNISTR2 * printername = NULL ;
PRINTER_DEFAULT * printer_default = & q_u - > printer_default ;
/* uint32 user_switch = q_u->user_switch; - notused */
/* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
POLICY_HND * handle = & r_u - > handle ;
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 ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OBJECT_NAME_INVALID ;
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 ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! open_printer_hnd ( p , handle , name ) )
2001-08-27 23:46:22 +04:00
return NT_STATUS_OBJECT_NAME_INVALID ;
2000-02-07 19:17:59 +03:00
/*
if ( printer_default - > datatype_ptr ! = NULL )
{
unistr2_to_ascii ( datatype , printer_default - > datatype , sizeof ( datatype ) - 1 ) ;
set_printer_hnd_datatype ( handle , datatype ) ;
}
else
set_printer_hnd_datatype ( handle , " " ) ;
*/
2001-03-11 03:32:10 +03:00
if ( ! set_printer_hnd_accesstype ( p , handle , printer_default - > access_required ) ) {
close_printer_handle ( p , handle ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-02-07 19:17:59 +03:00
}
2000-02-15 21:07:45 +03:00
2001-01-31 21:34:49 +03:00
/*
First case : the user is opening the print server :
Disallow MS AddPrinterWizard if parameter disables it . A Win2k
2000-10-07 00:03:17 +04:00
client 1 st tries an OpenPrinterEx with access = = 0 , MUST be allowed .
2001-01-31 21:34:49 +03:00
2000-10-07 00:03:17 +04:00
Then both Win2k and WinNT clients try an OpenPrinterEx with
2001-01-31 21:34:49 +03:00
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
2000-10-07 00:03:17 +04:00
client view printer folder , but does not show the MSAPW .
Note : this test needs code to check access rights here too . Jeremy
2001-01-31 21:34:49 +03:00
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 .
*/
2000-10-07 00:03:17 +04:00
2001-01-31 21:34:49 +03:00
get_current_user ( & user , p ) ;
2001-02-16 22:21:18 +03:00
2001-03-11 03:32:10 +03:00
if ( handle_is_printserver ( p , handle ) ) {
2001-01-05 22:01:11 +03:00
if ( printer_default - > access_required = = 0 ) {
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-01-05 22:01:11 +03:00
}
2001-02-16 22:21:18 +03:00
else if ( ( printer_default - > access_required & SERVER_ACCESS_ADMINISTER ) = = SERVER_ACCESS_ADMINISTER ) {
2001-01-05 22:01:11 +03:00
2001-03-01 06:36:02 +03:00
/* Printserver handles use global struct... */
snum = - 1 ;
2001-03-01 06:04:13 +03:00
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-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2001-01-31 21:34:49 +03:00
}
else if ( user . uid = = 0 | | user_in_list ( uidtoname ( user . uid ) , lp_printer_admin ( snum ) ) ) {
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-02-16 22:21:18 +03:00
}
else {
2001-03-11 03:32:10 +03:00
close_printer_handle ( p , handle ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2001-01-31 21:34:49 +03:00
}
}
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2001-03-03 08:27:26 +03:00
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 ;
}
2001-01-31 21:34:49 +03:00
if ( ! 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-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2001-01-25 23:15:32 +03:00
}
2001-01-30 00:34:08 +03:00
/*
* If we have a default device pointer in the
* printer_default struct , then we need to get
* the printer info from the tdb and if there is
* no default devicemode there then we do a * SET *
* here ! This is insanity . . . . JRA .
*/
2001-02-16 22:21:18 +03: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 .
*/
#if 0
2001-01-30 00:34:08 +03:00
if ( printer_default - > devmode_cont . devmode ! = NULL ) {
result = printer_write_default_dev ( snum , printer_default ) ;
if ( result ! = 0 ) {
2001-03-11 03:32:10 +03:00
close_printer_handle ( p , handle ) ;
2001-01-31 21:34:49 +03:00
return result ;
2001-01-30 00:34:08 +03:00
}
}
2001-02-16 22:21:18 +03:00
# endif
2001-01-05 22:01:11 +03:00
}
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-07 19:17:59 +03:00
}
2000-02-21 04:58:13 +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
{
2000-02-21 04:58:13 +03:00
switch ( level ) {
2000-11-18 02:10:56 +03:00
case 2 :
2000-06-02 22:38:49 +04:00
uni_2_asc_printer_info_2 ( uni - > info_2 , & printer - > info_2 ) ;
2000-02-07 19:17:59 +03:00
break ;
default :
break ;
}
return True ;
}
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 ) ) {
safe_free ( nt_devmode - > private ) ;
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-08-27 23:46:22 +04:00
static NTSTATUS _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 ) ;
2001-02-28 05:38:09 +03:00
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2001-02-28 05:38:09 +03:00
DEBUG ( 0 , ( " _spoolss_enddocprinter_internal: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2001-02-28 05:38:09 +03:00
}
Printer - > document_started = False ;
print_job_end ( Printer - > jobid , True ) ;
/* error codes unhandled so far ... */
2001-08-27 23:46:22 +04:00
return NT_STATUS_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-08-27 23:46:22 +04:00
NTSTATUS _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-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
if ( ! close_printer_handle ( p , handle ) )
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_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-08-27 23:46:22 +04:00
NTSTATUS _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-08-27 23:46:22 +04:00
NTSTATUS 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
2001-08-27 23:46:22 +04:00
if ( NT_STATUS_IS_OK ( result ) ) {
2001-03-11 03:32:10 +03:00
srv_spoolss_sendnotify ( p , handle ) ;
2001-01-23 23:25:25 +03:00
}
2000-05-02 19:31:55 +04: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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
*
* We currently delete the driver for the architecture only .
* This can leave the driver for other archtectures . However ,
* since every printer associates a " Windows NT x86 " driver name
* and we cannot delete that one while it is in use , * * and * * since
* it is impossible to assign a driver to a Samba printer without
* having the " Windows NT x86 " driver installed , . . .
*
* . . . . we should not get into trouble here .
*
* - - jerry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _spoolss_deleteprinterdriver ( pipes_struct * p , SPOOL_Q_DELETEPRINTERDRIVER * q_u ,
2001-05-18 08:11:17 +04:00
SPOOL_R_DELETEPRINTERDRIVER * r_u )
{
fstring driver ;
fstring arch ;
NT_PRINTER_DRIVER_INFO_LEVEL info ;
int version ;
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 ) {
2001-08-27 23:46:22 +04:00
return NT_STATUS_REVISION_MISMATCH ;
2001-05-18 08:11:17 +04:00
}
ZERO_STRUCT ( info ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer_driver ( & info , 3 , driver , arch , version ) ) ) {
2001-08-27 23:46:22 +04:00
return NT_STATUS_DRIVER_ORDINAL_NOT_FOUND ;
2001-05-18 08:11:17 +04:00
}
if ( printer_driver_in_use ( arch , driver ) )
{
2001-08-27 23:46:22 +04:00
return NT_STATUS_NETWORK_BUSY ;
2001-05-18 08:11:17 +04:00
}
return delete_printer_driver ( info . info_3 ) ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-02-15 21:07:45 +03:00
GetPrinterData on a printer server Handle .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 07:00:45 +03:00
static BOOL 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
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 )
2000-04-07 02:48:53 +04:00
return False ;
2000-02-07 21:06:54 +03:00
SIVAL ( * data , 0 , 0x01 ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
return True ;
}
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 )
2000-04-07 02:48:53 +04:00
return False ;
2000-02-07 21:06:54 +03:00
SIVAL ( * data , 0 , 0x1B ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
return True ;
}
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 )
2000-04-07 02:48:53 +04:00
return False ;
2000-02-07 21:06:54 +03:00
SIVAL ( * data , 0 , 0x01 ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
return True ;
}
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 )
2000-04-07 02:48:53 +04:00
return False ;
2000-02-07 21:06:54 +03:00
SIVAL ( * data , 0 , 0x02 ) ;
2000-02-07 19:17:59 +03:00
* needed = 0x4 ;
return True ;
}
2001-01-30 00:34:08 +03:00
if ( ! strcmp ( value , " DefaultSpoolDirectory " ) ) {
2000-02-07 21:06:54 +03:00
pstring string = " You are using a Samba server " ;
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 )
2000-04-07 02:48:53 +04:00
return False ;
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 ' ;
}
return True ;
}
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 )
2000-04-07 02:48:53 +04:00
return False ;
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 ' ;
}
return True ;
}
return False ;
}
/********************************************************************
2000-02-15 21:07:45 +03:00
GetPrinterData on a printer Handle .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL getprinterdata_printer ( pipes_struct * p , TALLOC_CTX * ctx , POLICY_HND * handle ,
2000-11-18 02:10:56 +03:00
fstring value , uint32 * type ,
2000-02-07 21:06:54 +03:00
uint8 * * data , uint32 * needed , uint32 in_size )
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
int snum = 0 ;
uint8 * idata = NULL ;
uint32 len ;
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 , ( " getprinterdata_printer \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " getprinterdata_printer: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-03-29 16:36:44 +04:00
return False ;
2000-07-07 03:31:46 +04:00
}
2000-03-29 16:36:44 +04:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2000-04-07 02:48:53 +04:00
return False ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
2000-04-07 02:48:53 +04:00
return False ;
2000-03-29 16:36:44 +04:00
2000-06-01 06:35:30 +04:00
if ( ! get_specific_param ( * printer , 2 , value , & idata , type , & len ) ) {
free_a_printer ( & printer , 2 ) ;
2000-03-29 16:36:44 +04:00
return False ;
2000-02-07 19:17:59 +03:00
}
2000-06-01 06:35:30 +04:00
free_a_printer ( & printer , 2 ) ;
2000-03-29 16:36:44 +04:00
DEBUG ( 5 , ( " getprinterdata_printer:allocating %d \n " , in_size ) ) ;
2000-06-06 00:55:57 +04:00
if ( in_size ) {
2001-03-03 08:27:26 +03:00
if ( ( * data = ( uint8 * ) talloc ( ctx , in_size * sizeof ( uint8 ) ) ) = = NULL ) {
2000-06-06 00:55:57 +04:00
return False ;
}
2000-04-07 02:48:53 +04:00
2001-03-03 08:27:26 +03:00
memset ( * data , 0 , in_size * sizeof ( uint8 ) ) ;
2000-06-06 00:55:57 +04:00
/* copy the min(in_size, len) */
memcpy ( * data , idata , ( len > in_size ) ? in_size : len * sizeof ( uint8 ) ) ;
} else {
* data = NULL ;
}
2000-03-29 16:36:44 +04:00
* needed = len ;
DEBUG ( 5 , ( " getprinterdata_printer:copy done \n " ) ) ;
safe_free ( idata ) ;
return True ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* spoolss_getprinterdata
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 04:24:55 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _spoolss_getprinterdata ( pipes_struct * p , SPOOL_Q_GETPRINTERDATA * q_u , SPOOL_R_GETPRINTERDATA * r_u )
2000-02-07 19:17:59 +03:00
{
2001-02-28 04:24:55 +03: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 ;
2000-02-07 19:17:59 +03:00
fstring value ;
2000-02-07 21:06:54 +03:00
BOOL found = False ;
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
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
*/
* out_size = in_size ;
/* in case of problem, return some default values */
2000-02-15 21:07:45 +03: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
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2001-03-03 08:27:26 +03:00
if ( ( * data = ( uint8 * ) malloc ( 4 * sizeof ( uint8 ) ) ) = = NULL )
2001-08-27 23:46:22 +04:00
return NT_STATUS_NO_MEMORY ;
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_getprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
unistr2_to_ascii ( value , valuename , sizeof ( value ) - 1 ) ;
2001-03-11 03:32:10 +03:00
if ( Printer - > printer_type = = PRINTER_HANDLE_IS_PRINTSERVER )
2001-03-01 07:00:45 +03:00
found = getprinterdata_printer_server ( p - > mem_ctx , value , type , data , needed , * out_size ) ;
2000-02-07 19:17:59 +03:00
else
2001-03-11 03:32:10 +03:00
found = getprinterdata_printer ( p , p - > mem_ctx , handle , value , type , data , needed , * out_size ) ;
2000-02-07 19:17:59 +03:00
if ( found = = False ) {
2000-03-29 16:36:44 +04:00
DEBUG ( 5 , ( " value not found, allocating %d \n " , * out_size ) ) ;
2000-02-07 19:17:59 +03:00
/* reply this param doesn't exist */
2000-06-06 00:55:57 +04:00
if ( * out_size ) {
2001-02-28 03:51:02 +03:00
if ( ( * data = ( uint8 * ) talloc_zero ( p - > mem_ctx , * out_size * sizeof ( uint8 ) ) ) = = NULL )
2001-08-27 23:46:22 +04:00
return NT_STATUS_NO_MEMORY ;
2000-06-06 00:55:57 +04:00
} else {
* data = NULL ;
}
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2000-02-07 19:17:59 +03:00
}
if ( * needed > * out_size )
2001-08-27 23:46:22 +04:00
return STATUS_MORE_ENTRIES ;
2001-01-30 00:34:08 +03:00
else {
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-01-30 00:34:08 +03:00
}
2000-02-07 19:17:59 +03:00
}
2000-09-26 01:05:18 +04:00
/***************************************************************************
connect to the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL srv_spoolss_replyopenprinter ( char * printer , uint32 localprinter , uint32 type , POLICY_HND * handle )
{
2001-08-27 23:46:22 +04:00
NTSTATUS status ;
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 */
if ( ! spoolss_connect_to_client ( & cli , unix_printer ) )
2000-09-26 01:05:18 +04:00
return False ;
2000-09-26 14:15:12 +04:00
message_register ( MSG_PRINTER_NOTIFY , srv_spoolss_receive_message ) ;
}
2000-09-26 01:05:18 +04:00
smb_connections + + ;
if ( ! cli_spoolss_reply_open_printer ( & cli , printer , localprinter , type , & status , handle ) )
return False ;
2000-09-26 04:54:18 +04:00
return True ;
2000-09-26 01:05:18 +04:00
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* _spoolss_rffpcnex
* ReplyFindFirstPrinterChangeNotifyEx
*
* jfmxxxx : before replying OK : status = 0
* should do a rpc call to the workstation asking ReplyOpenPrinter
* have to code it , later .
*
* 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-08-27 23:46:22 +04:00
NTSTATUS _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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_rffpcnex: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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 ) ;
2000-02-25 02:01:24 +03:00
unistr2_to_ascii ( Printer - > notify . localmachine , localmachine , sizeof ( Printer - > notify . localmachine ) - 1 ) ;
2000-02-07 19:17:59 +03:00
2000-09-26 01:05:18 +04:00
/* connect to the client machine and send a ReplyOpenPrinter */
2000-11-18 02:10:56 +03:00
if ( srv_spoolss_replyopenprinter ( Printer - > notify . localmachine ,
Printer - > notify . printerlocal , 1 ,
2000-09-26 01:05:18 +04:00
& Printer - > notify . client_hnd ) )
Printer - > notify . client_connected = True ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_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
2001-01-18 01:55:02 +03:00
static void spoolss_notify_server_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_name , temp ;
uint32 len ;
2000-02-07 19:17:59 +03:00
2001-02-16 22:21:18 +03:00
slprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , global_myname ) ;
2000-02-07 19:17:59 +03:00
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , temp_name , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_printer_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 ;
2000-11-08 06:12:16 +03:00
/* the notify name should not contain the \\server\ part */
2001-07-04 11:36:09 +04:00
char * p = strrchr_m ( 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-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , p , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_share_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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , lp_servicename ( snum ) , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_port_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 ;
2000-02-07 19:17:59 +03:00
/* even if it's strange, that's consistant in all the code */
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > portname , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* jfmxxxx : it ' s incorrect , should be lp_printerdrivername ( )
* but it doesn ' t exist , have to see what to do
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_driver_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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > drivername , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_comment ( 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 ;
2000-07-26 14:31:05 +04:00
if ( * printer - > info_2 - > comment = = ' \0 ' )
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , lp_comment ( snum ) , sizeof ( temp ) - 2 , 0 ) ;
2000-07-26 14:31:05 +04:00
else
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > comment , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* jfm : xxxx incorrect , have to create a new smb . conf option
* location = " Room 1, floor 2, building 3 "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_location ( 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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > location , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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 ! ! !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
* jfm : xxxx just return no file could add an option to smb . conf
* separator file = " separator.txt "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_sepfile ( 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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > sepfile , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_print_processor ( 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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > printprocessor , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_parameters ( 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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > parameters , sizeof ( temp ) -
2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_datatype ( 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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , printer - > info_2 - > datatype , sizeof ( pstring ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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 !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
{
data - > notify_data . data . length = 0 ;
2001-01-18 19:13:03 +03:00
data - > notify_data . data . string = NULL ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the attributes
* jfm : xxxx a samba printer is always shared
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_attributes ( 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-11-14 05:14:58 +03:00
data - > notify_data . value [ 0 ] = printer - > info_2 - > attributes ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the priority
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
/*******************************************************************
* fill a notify_info_data with the default priority
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
/*******************************************************************
* fill a notify_info_data with the start time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
/*******************************************************************
* fill a notify_info_data with the until time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
/*******************************************************************
* fill a notify_info_data with the status
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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_queue_struct * q = NULL ;
print_status_struct status ;
2000-02-24 19:27:06 +03:00
memset ( & status , 0 , sizeof ( status ) ) ;
2001-03-11 03:32:10 +03:00
print_queue_status ( snum , & q , & status ) ;
2000-02-07 19:17:59 +03:00
data - > notify_data . value [ 0 ] = ( uint32 ) status . status ;
2000-03-29 16:36:44 +04:00
safe_free ( q ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the number of jobs queued
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-18 01:55:02 +03:00
static void spoolss_notify_cjobs ( 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_queue_struct * q = NULL ;
print_status_struct status ;
2000-02-24 19:27:06 +03:00
memset ( & status , 0 , sizeof ( status ) ) ;
2000-04-16 10:20:43 +04:00
data - > notify_data . value [ 0 ] = print_queue_status ( snum , & q , & status ) ;
2000-03-29 16:36:44 +04:00
safe_free ( q ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the average ppm
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with username
2000-02-07 19:17:59 +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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , queue - > user , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
2001-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , queue - > file , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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-07-04 11:15:53 +04:00
len = rpcstr_push ( temp , p , sizeof ( temp ) - 2 , 0 ) ;
2001-01-18 01:55:02 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job size
2000-02-07 19:17:59 +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 ;
}
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with job position
2000-02-07 19:17:59 +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 ;
}
2000-10-29 20:27:41 +03:00
/*******************************************************************
2000-10-31 00:55:30 +03:00
* fill a notify_info_data with submitted time
2000-10-29 20:27:41 +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 ;
2000-10-29 20:27:41 +03:00
t = gmtime ( & queue - > time ) ;
2001-01-18 01:55:02 +03:00
len = sizeof ( SYSTEMTIME ) ;
2001-03-03 09:47:37 +03:00
data - > notify_data . data . length = len / 2 - 1 ;
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 ) ;
memcpy ( data - > notify_data . data . string , & st , len ) ;
2000-10-29 20:27:41 +03:00
}
2000-02-07 19:17:59 +03:00
# define END 65535
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
} ;
2000-02-07 19:17:59 +03:00
struct s_notify_info_data_table notify_info_data_table [ ] =
{
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SERVER_NAME , " PRINTER_NOTIFY_SERVER_NAME " , POINTER , spoolss_notify_server_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRINTER_NAME , " PRINTER_NOTIFY_PRINTER_NAME " , POINTER , spoolss_notify_printer_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SHARE_NAME , " PRINTER_NOTIFY_SHARE_NAME " , POINTER , spoolss_notify_share_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PORT_NAME , " PRINTER_NOTIFY_PORT_NAME " , POINTER , spoolss_notify_port_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DRIVER_NAME , " PRINTER_NOTIFY_DRIVER_NAME " , POINTER , spoolss_notify_driver_name } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_COMMENT , " PRINTER_NOTIFY_COMMENT " , POINTER , spoolss_notify_comment } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_LOCATION , " PRINTER_NOTIFY_LOCATION " , POINTER , spoolss_notify_location } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DEVMODE , " PRINTER_NOTIFY_DEVMODE " , POINTER , spoolss_notify_devmode } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SEPFILE , " PRINTER_NOTIFY_SEPFILE " , POINTER , spoolss_notify_sepfile } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRINT_PROCESSOR , " PRINTER_NOTIFY_PRINT_PROCESSOR " , POINTER , spoolss_notify_print_processor } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PARAMETERS , " PRINTER_NOTIFY_PARAMETERS " , POINTER , spoolss_notify_parameters } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DATATYPE , " PRINTER_NOTIFY_DATATYPE " , POINTER , spoolss_notify_datatype } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_SECURITY_DESCRIPTOR , " PRINTER_NOTIFY_SECURITY_DESCRIPTOR " , POINTER , spoolss_notify_security_desc } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_ATTRIBUTES , " PRINTER_NOTIFY_ATTRIBUTES " , ONE_VALUE , spoolss_notify_attributes } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PRIORITY , " PRINTER_NOTIFY_PRIORITY " , ONE_VALUE , spoolss_notify_priority } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_DEFAULT_PRIORITY , " PRINTER_NOTIFY_DEFAULT_PRIORITY " , ONE_VALUE , spoolss_notify_default_priority } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_START_TIME , " PRINTER_NOTIFY_START_TIME " , ONE_VALUE , spoolss_notify_start_time } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_UNTIL_TIME , " PRINTER_NOTIFY_UNTIL_TIME " , ONE_VALUE , spoolss_notify_until_time } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_STATUS , " PRINTER_NOTIFY_STATUS " , ONE_VALUE , spoolss_notify_status } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_STATUS_STRING , " PRINTER_NOTIFY_STATUS_STRING " , POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_CJOBS , " PRINTER_NOTIFY_CJOBS " , ONE_VALUE , spoolss_notify_cjobs } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_AVERAGE_PPM , " PRINTER_NOTIFY_AVERAGE_PPM " , ONE_VALUE , spoolss_notify_average_ppm } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_TOTAL_PAGES , " PRINTER_NOTIFY_TOTAL_PAGES " , POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_PAGES_PRINTED , " PRINTER_NOTIFY_PAGES_PRINTED " , POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_TOTAL_BYTES , " PRINTER_NOTIFY_TOTAL_BYTES " , POINTER , NULL } ,
{ PRINTER_NOTIFY_TYPE , PRINTER_NOTIFY_BYTES_PRINTED , " PRINTER_NOTIFY_BYTES_PRINTED " , POINTER , NULL } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PRINTER_NAME , " JOB_NOTIFY_PRINTER_NAME " , POINTER , spoolss_notify_printer_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_MACHINE_NAME , " JOB_NOTIFY_MACHINE_NAME " , POINTER , spoolss_notify_server_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PORT_NAME , " JOB_NOTIFY_PORT_NAME " , POINTER , spoolss_notify_port_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_USER_NAME , " JOB_NOTIFY_USER_NAME " , POINTER , spoolss_notify_username } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_NOTIFY_NAME , " JOB_NOTIFY_NOTIFY_NAME " , POINTER , spoolss_notify_username } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DATATYPE , " JOB_NOTIFY_DATATYPE " , POINTER , spoolss_notify_datatype } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PRINT_PROCESSOR , " JOB_NOTIFY_PRINT_PROCESSOR " , POINTER , spoolss_notify_print_processor } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PARAMETERS , " JOB_NOTIFY_PARAMETERS " , POINTER , spoolss_notify_parameters } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DRIVER_NAME , " JOB_NOTIFY_DRIVER_NAME " , POINTER , spoolss_notify_driver_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DEVMODE , " JOB_NOTIFY_DEVMODE " , POINTER , spoolss_notify_devmode } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_STATUS , " JOB_NOTIFY_STATUS " , ONE_VALUE , spoolss_notify_job_status } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_STATUS_STRING , " JOB_NOTIFY_STATUS_STRING " , POINTER , spoolss_notify_job_status_string } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_SECURITY_DESCRIPTOR , " JOB_NOTIFY_SECURITY_DESCRIPTOR " , POINTER , NULL } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_DOCUMENT , " JOB_NOTIFY_DOCUMENT " , POINTER , spoolss_notify_job_name } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PRIORITY , " JOB_NOTIFY_PRIORITY " , ONE_VALUE , spoolss_notify_priority } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_POSITION , " JOB_NOTIFY_POSITION " , ONE_VALUE , spoolss_notify_job_position } ,
2000-10-29 20:27:41 +03:00
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_SUBMITTED , " JOB_NOTIFY_SUBMITTED " , POINTER , spoolss_notify_submitted_time } ,
2000-02-07 19:17:59 +03:00
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_START_TIME , " JOB_NOTIFY_START_TIME " , ONE_VALUE , spoolss_notify_start_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_UNTIL_TIME , " JOB_NOTIFY_UNTIL_TIME " , ONE_VALUE , spoolss_notify_until_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_TIME , " JOB_NOTIFY_TIME " , ONE_VALUE , spoolss_notify_job_time } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_TOTAL_PAGES , " JOB_NOTIFY_TOTAL_PAGES " , ONE_VALUE , NULL } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_PAGES_PRINTED , " JOB_NOTIFY_PAGES_PRINTED " , ONE_VALUE , NULL } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_TOTAL_BYTES , " JOB_NOTIFY_TOTAL_BYTES " , ONE_VALUE , spoolss_notify_job_size } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_BYTES_PRINTED , " JOB_NOTIFY_BYTES_PRINTED " , ONE_VALUE , NULL } ,
{ END , END , " " , END , NULL }
} ;
/*******************************************************************
return the size of info_data structure
2000-11-18 02:10:56 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-07 19:17:59 +03:00
static uint32 size_of_notify_info_data ( uint16 type , uint16 field )
{
int i = 0 ;
while ( notify_info_data_table [ i ] . type ! = END )
{
if ( ( notify_info_data_table [ i ] . type = = type ) & &
( notify_info_data_table [ i ] . field = = field ) )
{
return ( notify_info_data_table [ i ] . size ) ;
}
i + + ;
}
return ( 65535 ) ;
}
/*******************************************************************
return the type of notify_info_data
2000-11-18 02:10:56 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-07 19:17:59 +03:00
static BOOL type_of_notify_info_data ( uint16 type , uint16 field )
{
int i = 0 ;
while ( notify_info_data_table [ i ] . type ! = END )
{
if ( ( notify_info_data_table [ i ] . type = = type ) & &
( notify_info_data_table [ i ] . field = = field ) )
{
if ( notify_info_data_table [ i ] . size = = POINTER )
{
return ( False ) ;
}
else
{
return ( True ) ;
}
}
i + + ;
}
return ( False ) ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int search_notify ( uint16 type , uint16 field , int * value )
{
int j ;
BOOL found ;
for ( j = 0 , found = False ; found = = False & & notify_info_data_table [ j ] . type ! = END ; j + + )
{
if ( ( notify_info_data_table [ j ] . type = = type ) & &
( notify_info_data_table [ j ] . field = = field ) )
found = True ;
}
* value = - - j ;
if ( found & & ( notify_info_data_table [ j ] . fn ! = NULL ) )
2000-02-24 19:27:06 +03:00
return True ;
2000-02-07 19:17:59 +03:00
else
2000-02-24 19:27:06 +03:00
return False ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void construct_info_data ( SPOOL_NOTIFY_INFO_DATA * info_data , uint16 type , uint16 field , int id )
{
info_data - > type = type ;
info_data - > field = field ;
2000-02-24 19:27:06 +03:00
info_data - > reserved = 0 ;
2000-02-07 19:17:59 +03:00
info_data - > id = id ;
info_data - > size = size_of_notify_info_data ( type , field ) ;
info_data - > enc_type = type_of_notify_info_data ( type , field ) ;
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
2000-06-29 04:52:40 +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 ] ;
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 ;
2000-02-07 19:17:59 +03:00
2001-08-12 21:30:01 +04:00
if ( ( tid = ( SPOOL_NOTIFY_INFO_DATA * ) Realloc ( info - > data , ( info - > count + 1 ) * sizeof ( SPOOL_NOTIFY_INFO_DATA ) ) ) = = NULL ) {
DEBUG ( 0 , ( " construct_notify_printer_info: failed to enlarge 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 ;
2001-03-02 05:59:17 +03:00
current_data = & info - > data [ info - > count ] ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03: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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) {
DEBUG ( 0 , ( " 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 " ) ) ;
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 + + )
if ( lp_browseable ( snum ) & & lp_snum_ok ( snum ) & & lp_print_ok ( snum ) )
2001-03-03 08:27:26 +03:00
if ( construct_notify_printer_info
( info , snum , option_type , id , mem_ctx ) )
2000-02-24 19:27:06 +03:00
id + + ;
2000-02-07 19:17:59 +03:00
}
2000-02-24 19:27:06 +03:00
/*
* Debugging information , don ' t delete .
*/
2000-11-18 02:10:56 +03: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
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 " ) ) ;
2000-02-25 02:01:24 +03:00
option = Printer - > notify . option ;
2000-04-05 14:05:32 +04:00
id = 0xffffffff ;
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-02-24 19:27:06 +03:00
memset ( & status , 0 , sizeof ( status ) ) ;
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 :
2000-02-24 19:27:06 +03:00
safe_free ( queue ) ;
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 ;
/* uint32 change = q_u->change; - notused. */
/* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
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 ) {
2001-01-18 01:55:02 +03:00
DEBUG ( 0 , ( " _spoolss_rfnpcnex: Invalid handle (%s). \n " ,
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
/* jfm: the change value isn't used right now.
* we will honour it when
* a ) we ' ll be able to send notification to the client
* b ) we ' ll have a way to communicate between the spoolss process .
*
* same thing for option - > flags
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
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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-03-10 20:12:24 +03:00
2000-02-07 19:17:59 +03:00
print_queue_struct * queue = NULL ;
print_status_struct status ;
2000-03-10 20:12:24 +03:00
2000-02-24 19:27:06 +03:00
memset ( & status , 0 , sizeof ( status ) ) ;
2000-02-07 19:17:59 +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
2000-04-16 10:20:43 +04:00
count = print_queue_status ( snum , & queue , & 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
2000-11-10 22:36:34 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s " , global_myname ) ;
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 ;
printer - > major_version = 0x0004 ; /* NT 4 */
printer - > build_version = 0x0565 ; /* build 1381 */
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 ;
2000-06-01 06:35:30 +04:00
printer - > c_setprinter = ntprinter - > info_2 - > c_setprinter ; /* how many times setprinter has been called */
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-02-07 19:17:59 +03:00
safe_free ( queue ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-11-10 22:36:34 +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 ) ) ;
2001-02-16 22:21:18 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " %s%s,%s,%s " , global_myname , ntprinter - > info_2 - > printername ,
2000-07-26 14:31:05 +04:00
ntprinter - > info_2 - > drivername , lp_comment ( snum ) ) ;
}
else {
init_unistr ( & printer - > comment , ntprinter - > info_2 - > comment ) ; /* saved comment. */
2001-02-16 22:21:18 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " %s%s,%s,%s " , global_myname , ntprinter - > info_2 - > printername ,
2000-07-26 14:31:05 +04:00
ntprinter - > info_2 - > drivername , ntprinter - > info_2 - > comment ) ;
}
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 ;
if ( dev - > private )
safe_free ( dev - > private ) ;
safe_free ( dev ) ;
}
/****************************************************************************
Create a DEVMODE struct . Returns malloced memory .
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
2000-11-10 22:36:34 +03:00
static DEVICEMODE * construct_dev_mode ( int snum )
2000-02-07 19:17:59 +03:00
{
char adevice [ 32 ] ;
char aform [ 32 ] ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_DEVICEMODE * ntdevmode = NULL ;
DEVICEMODE * devmode = NULL ;
2000-02-07 19:17:59 +03:00
DEBUG ( 7 , ( " construct_dev_mode \n " ) ) ;
DEBUGADD ( 8 , ( " getting printer characteristics \n " ) ) ;
2000-06-01 06:35:30 +04:00
if ( ( devmode = ( DEVICEMODE * ) malloc ( sizeof ( DEVICEMODE ) ) ) = = NULL ) {
DEBUG ( 0 , ( " construct_dev_mode: malloc fail. \n " ) ) ;
return NULL ;
2000-05-29 05:09:14 +04:00
}
2000-02-07 19:17:59 +03:00
2000-06-01 06:35:30 +04:00
ZERO_STRUCTP ( devmode ) ;
2001-09-03 12:50:59 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ) )
2000-06-01 06:35:30 +04:00
goto fail ;
if ( printer - > info_2 - > devmode )
ntdevmode = dup_nt_devicemode ( printer - > info_2 - > devmode ) ;
2000-09-15 04:15:10 +04:00
2000-06-01 06:35:30 +04:00
if ( ntdevmode = = NULL )
goto fail ;
2000-02-07 19:17:59 +03:00
DEBUGADD ( 8 , ( " loading DEVICEMODE \n " ) ) ;
2000-06-24 04:15:08 +04:00
2001-02-16 22:21:18 +03:00
slprintf ( adevice , sizeof ( adevice ) - 1 , printer - > info_2 - > printername ) ;
2000-06-01 06:35:30 +04:00
init_unistr ( & devmode - > devicename , adevice ) ;
2000-02-07 19:17:59 +03:00
2001-02-16 22:21:18 +03:00
slprintf ( aform , sizeof ( aform ) - 1 , ntdevmode - > formname ) ;
2000-06-01 06:35:30 +04:00
init_unistr ( & devmode - > formname , aform ) ;
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 )
goto fail ;
}
2000-06-02 23:42:11 +04:00
free_nt_devicemode ( & ntdevmode ) ;
free_a_printer ( & printer , 2 ) ;
2000-06-01 06:35:30 +04:00
return devmode ;
fail :
if ( ntdevmode )
free_nt_devicemode ( & ntdevmode ) ;
if ( printer )
free_a_printer ( & printer , 2 ) ;
free_dev_mode ( devmode ) ;
2000-02-07 19:17:59 +03:00
2000-06-01 06:35:30 +04:00
return NULL ;
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_queue_struct * queue = NULL ;
print_status_struct status ;
2000-02-24 19:27:06 +03:00
memset ( & status , 0 , sizeof ( status ) ) ;
2000-02-07 19:17:59 +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 ;
memset ( & status , 0 , sizeof ( status ) ) ;
2000-04-16 10:20:43 +04:00
count = print_queue_status ( snum , & queue , & 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-02-07 19:17:59 +03:00
safe_free ( queue ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) {
DEBUG ( 0 , ( " construct_printer_info_3: malloc fail. \n " ) ) ;
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 ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-03-07 21:10:20 +03:00
Spoolss_enumprinters .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ) ;
2000-11-10 22:36:34 +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 ) {
DEBUG ( 0 , ( " enum_all_printers_info_1: failed to enlarge printers buffer! \n " ) ) ;
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 ) ) ;
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 */
2000-03-07 21:10:20 +03: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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
{
fstring temp ;
DEBUG ( 4 , ( " enum_all_printers_info_1_name \n " ) ) ;
2000-02-15 21:07:45 +03:00
2000-03-07 21:10:20 +03:00
fstrcpy ( temp , " \\ \\ " ) ;
fstrcat ( temp , global_myname ) ;
2000-02-15 21:07:45 +03:00
2000-11-10 22:36:34 +03:00
if ( strequal ( name , temp ) ) {
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
2001-02-16 22:21:18 +03:00
slprintf ( printername , sizeof ( printername ) - 1 , " Windows NT Remote Printers!! \\ \\ %s " , global_myname ) ;
slprintf ( desc , sizeof ( desc ) - 1 , " %s " , global_myname ) ;
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 ) ) {
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 */
2000-03-07 21:10:20 +03: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
2001-09-03 12:50:59 +04:00
static WERROR enum_all_printers_info_1_network ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
2000-03-07 21:10:20 +03:00
{
DEBUG ( 4 , ( " enum_all_printers_info_1_network \n " ) ) ;
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 ) {
DEBUG ( 0 , ( " enum_all_printers_info_2: failed to enlarge printers buffer! \n " ) ) ;
safe_free ( printers ) ;
* 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. */
for ( i = 0 ; i < * returned ; i + + )
2000-06-02 23:42:11 +04:00
( * needed ) + = spoolss_size_printer_info_2 ( & printers [ i ] ) ;
2000-03-06 14:13:40 +03: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
}
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
}
2000-03-10 20:12:24 +03: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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 )
2000-11-10 22:36:34 +03:00
return enum_all_printers_info_1_network ( 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 )
{
2000-03-10 20:12:24 +03:00
fstring temp ;
fstrcpy ( temp , " \\ \\ " ) ;
fstrcat ( temp , global_myname ) ;
if ( flags & PRINTER_ENUM_LOCAL ) {
2000-11-10 22:36:34 +03:00
if ( strequal ( servername , temp ) )
return enum_all_printers_info_2 ( buffer , offered , needed , returned ) ;
2000-03-10 20:12:24 +03:00
else
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 ) {
2000-11-10 22:36:34 +03:00
if ( strequal ( servername , temp ) )
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
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 :
default :
}
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +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 ) ) {
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 */
safe_free ( printer ) ;
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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
2000-11-10 22:36:34 +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 ) ) {
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 */
safe_free ( printer ) ;
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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ;
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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
}
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 ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static void 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
2000-05-24 10:34:47 +04:00
while ( 1 ) {
2000-06-03 00:08:28 +04:00
if ( char_array = = NULL )
v = " " ;
else {
v = char_array [ i ] ;
if ( ! v ) v = " " ; /* hack to handle null lists */
}
2000-06-27 02:08:20 +04:00
if ( strlen ( v ) = = 0 ) break ;
2001-02-16 22:21:18 +03:00
slprintf ( line , sizeof ( line ) - 1 , " \\ \\ %s%s " , servername , v ) ;
2000-03-29 16:36:44 +04:00
DEBUGADD ( 6 , ( " %d:%s:%d \n " , i , line , strlen ( line ) ) ) ;
2001-08-12 21:30:01 +04:00
if ( ( tuary = Realloc ( * uni_array , ( j + strlen ( line ) + 2 ) * sizeof ( uint16 ) ) ) = = NULL ) {
2000-04-07 02:48:53 +04:00
DEBUG ( 0 , ( " init_unistr_array: Realloc error \n " ) ) ;
return ;
}
2001-08-12 21:30:01 +04:00
else * uni_array = tuary ;
2001-07-04 11:15:53 +04:00
j + = ( rpcstr_push ( ( * uni_array + j ) , line , sizeof ( uint16 ) * strlen ( line ) + 2 , 0 ) / 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 " ) ) ;
}
/********************************************************************
* construct_printer_info_3
* fill a printer_info_3 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ;
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-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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ) ;
2001-09-03 12:50:59 +04:00
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %s \n " , werror_str ( status ) ) ) ;
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 ) ;
2001-09-03 12:50:59 +04:00
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %s \n " , werror_str ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2000-07-26 02:35:57 +04:00
free_a_printer ( & printer , 2 ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_PRINTER_DRIVER ;
2000-07-26 02:35:57 +04:00
}
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 ) ;
info - > dependentfiles = NULL ;
init_unistr_array ( & info - > dependentfiles , driver . info_3 - > dependentfiles , servername ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-03 12:50:59 +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
{
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_PRINTER_DRIVER_INFO_LEVEL driver ;
2001-09-03 12:50:59 +04:00
WERROR status ;
2000-09-15 04:15:10 +04:00
ZERO_STRUCT ( driver ) ;
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
2001-09-03 12:50:59 +04:00
DEBUG ( 8 , ( " construct_printer_driver_info_6: status: %s \n " , werror_str ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( status ) )
return WERR_INVALID_PRINTER_NAME ;
2000-09-15 04:15:10 +04:00
status = get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ;
2001-09-03 12:50:59 +04:00
DEBUG ( 8 , ( " construct_printer_driver_info_6: status: %s \n " , werror_str ( status ) ) ) ;
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 ) ;
2001-09-03 12:50:59 +04:00
DEBUG ( 8 , ( " construct_printer_driver_info_6: status: %s \n " , werror_str ( status ) ) ) ;
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 )
{
safe_free ( info - > dependentfiles ) ;
}
2000-09-15 04:15:10 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_printer_driver_info_6 ( DRIVER_INFO_6 * info )
{
safe_free ( info - > dependentfiles ) ;
}
2000-02-07 19:17:59 +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 ) ) {
2000-07-25 17:15:16 +04:00
safe_free ( info ) ;
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 ) ) {
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 */
safe_free ( 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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ) {
2000-07-25 17:15:16 +04:00
safe_free ( info ) ;
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 ) ) {
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 */
safe_free ( 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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
/* uint32 clientminorversion = q_u->clientminorversion; - notused. */
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 " ) ) ;
* needed = 0 ;
2000-03-13 14:09:20 +03:00
* servermajorversion = 0 ;
* serverminorversion = 0 ;
2000-02-07 19:17:59 +03:00
pstrcpy ( servername , global_myname ) ;
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-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-08-27 23:46:22 +04:00
NTSTATUS _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
2001-03-11 03:32:10 +03:00
if ( Printer ) {
2000-02-25 02:01:24 +03:00
Printer - > page_started = True ;
2001-09-03 12:50:59 +04:00
return NT_STATUS_OK ;
2000-02-07 19:17:59 +03:00
}
2000-02-25 02:01:24 +03:00
DEBUG ( 3 , ( " Error in startpageprinter printer handle \n " ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:03:02 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 ;
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_endpageprinter: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2000-02-25 02:01:24 +03:00
Printer - > page_started = False ;
2000-02-07 19:17:59 +03:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_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 ;
/* uint32 level = q_u->doc_info_container.level; - notused. */
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_startdocprinter: Invalid handle (%s) \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 . . .
*
* lkclXXXX jean - francois , i love this kind of thing . oh , well ,
* there ' s a bug in NT client - side code , so we ' ll fix it in the
* server - side code . * nnnnnggggh ! *
*/
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
2000-07-06 10:53:47 +04:00
Printer - > jobid = print_job_start ( & user , snum , jobname ) ;
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 ) {
2000-09-01 22:49:26 +04:00
return map_nt_error_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-08-27 23:46:22 +04:00
NTSTATUS _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-08-27 23:46:22 +04:00
NTSTATUS _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 ;
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_writeprinter: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-02-28 05:38:09 +03:00
r_u - > buffer_written = q_u - > buffer_size2 ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2001-02-28 05:38:09 +03:00
( * buffer_written ) = print_job_write ( Printer - > jobid , ( char * ) buffer , buffer_size ) ;
r_u - > buffer_written = q_u - > buffer_size2 ;
2000-02-07 19:17:59 +03:00
return 0x0 ;
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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-08-10 09:41:53 +04:00
int snum , errcode = ERRbadfunc ;
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " control_printer: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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 ) ) {
2000-11-07 05:54:50 +03:00
errcode = 0 ;
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 ) ) {
2000-11-07 05:54:50 +03:00
errcode = 0 ;
2000-04-16 10:20:43 +04:00
}
break ;
case PRINTER_CONTROL_PURGE :
2000-08-30 04:45:59 +04:00
if ( print_queue_purge ( & user , snum , & errcode ) ) {
2000-11-07 05:54:50 +03:00
errcode = 0 ;
2000-04-16 10:20:43 +04:00
}
break ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _spoolss_abortprinter ( pipes_struct * p , SPOOL_Q_ABORTPRINTER * q_u , SPOOL_R_ABORTPRINTER * r_u )
2000-08-30 04:45:59 +04:00
{
2001-02-28 04:24:55 +03:00
POLICY_HND * handle = & q_u - > handle ;
2000-08-30 04:45:59 +04:00
return control_printer ( handle , PRINTER_CONTROL_PURGE , p ) ;
}
2000-05-27 13:53:11 +04:00
/********************************************************************
* called by spoolss_api_setprinter
* when updating a printer description
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ;
2000-08-09 08:19:18 +04:00
uint32 result ;
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 ) ) {
2000-11-18 02:10:56 +03:00
DEBUG ( 0 , ( " update_printer_sec: Invalid handle (%s) \n " ,
2000-11-07 05:54:50 +03:00
OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
result = NT_STATUS_INVALID_HANDLE ;
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-04-28 01:49:22 +04:00
sid_to_string ( sid_str , & the_acl - > ace [ i ] . sid ) ;
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-04-28 01:49:22 +04:00
sid_to_string ( sid_str , & the_acl - > ace [ i ] . sid ) ;
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-08-27 23:46:22 +04:00
result = NT_STATUS_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-08-27 23:46:22 +04:00
result = NT_STATUS_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 */
2001-02-16 22:21:18 +03:00
slprintf ( info - > servername , sizeof ( info - > servername ) - 1 , " \\ \\ %s " , global_myname ) ;
slprintf ( info - > printername , sizeof ( info - > printername ) - 1 , " \\ \\ %s \\ %s " ,
2000-11-08 06:12:16 +03:00
global_myname , lp_servicename ( snum ) ) ;
fstrcpy ( info - > sharename , lp_servicename ( snum ) ) ;
info - > attributes = PRINTER_ATTRIBUTE_SHARED \
| PRINTER_ATTRIBUTE_LOCAL \
| PRINTER_ATTRIBUTE_RAW_ONLY \
2000-11-18 02:10:56 +03:00
| PRINTER_ATTRIBUTE_QUEUED ;
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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL add_printer_hook ( NT_PRINTER_INFO_LEVEL * printer )
{
char * cmd = lp_addprinter_cmd ( ) ;
char * * qlines ;
pstring command ;
pstring driverlocation ;
int numlines ;
int ret ;
2001-04-13 04:37:00 +04:00
int fd ;
2000-08-11 03:41:16 +04:00
/* build driver path... only 9X architecture is needed for legacy reasons */
slprintf ( driverlocation , sizeof ( driverlocation ) - 1 , " \\ \\ %s \\ print$ \\ WIN40 \\ 0 " ,
global_myname ) ;
/* change \ to \\ for the shell */
all_string_sub ( driverlocation , " \\ " , " \\ \\ " , sizeof ( pstring ) ) ;
2001-04-12 11:00:08 +04:00
2001-02-16 22:21:18 +03:00
slprintf ( command , sizeof ( command ) - 1 , " %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 ,
printer - > info_2 - > location , driverlocation ) ;
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-11-07 05:54:50 +03:00
/* Return true if two devicemodes are equal */
2000-12-18 09:02:31 +03:00
# define DEVMODE_CHECK_INT(field) \
if ( d1 - > field ! = d2 - > field ) { \
DEBUG ( 10 , ( " nt_devicemode_equal(): " # field " not equal (%d != %d) \n " , \
d1 - > field , d2 - > field ) ) ; \
return False ; \
}
2000-11-07 05:54:50 +03:00
static BOOL nt_devicemode_equal ( NT_DEVICEMODE * d1 , NT_DEVICEMODE * d2 )
{
2000-12-14 21:37:01 +03:00
if ( ! d1 & & ! d2 ) goto equal ; /* if both are NULL they are equal */
if ( ! d1 ^ ! d2 ) {
DEBUG ( 10 , ( " nt_devicemode_equal(): pointers not equal \n " ) ) ;
return False ; /* if either is exclusively NULL are not equal */
}
2000-11-18 02:10:56 +03:00
2001-02-16 22:21:18 +03:00
if ( ! strequal ( d1 - > devicename , d2 - > devicename ) ) {
DEBUG ( 10 , ( " nt_devicemode_equal(): device not equal (%s != %s) \n " , d1 - > devicename , d2 - > devicename ) ) ;
return False ;
}
if ( ! strequal ( d1 - > formname , d2 - > formname ) ) {
DEBUG ( 10 , ( " nt_devicemode_equal(): formname not equal (%s != %s) \n " , d1 - > formname , d2 - > formname ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
2000-12-18 09:02:31 +03:00
DEVMODE_CHECK_INT ( specversion ) ;
DEVMODE_CHECK_INT ( driverversion ) ;
DEVMODE_CHECK_INT ( driverextra ) ;
DEVMODE_CHECK_INT ( orientation ) ;
DEVMODE_CHECK_INT ( papersize ) ;
DEVMODE_CHECK_INT ( paperlength ) ;
DEVMODE_CHECK_INT ( paperwidth ) ;
DEVMODE_CHECK_INT ( scale ) ;
DEVMODE_CHECK_INT ( copies ) ;
DEVMODE_CHECK_INT ( defaultsource ) ;
DEVMODE_CHECK_INT ( printquality ) ;
DEVMODE_CHECK_INT ( color ) ;
DEVMODE_CHECK_INT ( duplex ) ;
DEVMODE_CHECK_INT ( yresolution ) ;
DEVMODE_CHECK_INT ( ttoption ) ;
DEVMODE_CHECK_INT ( collate ) ;
DEVMODE_CHECK_INT ( logpixels ) ;
DEVMODE_CHECK_INT ( fields ) ;
DEVMODE_CHECK_INT ( bitsperpel ) ;
DEVMODE_CHECK_INT ( pelswidth ) ;
DEVMODE_CHECK_INT ( pelsheight ) ;
DEVMODE_CHECK_INT ( displayflags ) ;
DEVMODE_CHECK_INT ( displayfrequency ) ;
DEVMODE_CHECK_INT ( icmmethod ) ;
DEVMODE_CHECK_INT ( icmintent ) ;
DEVMODE_CHECK_INT ( mediatype ) ;
DEVMODE_CHECK_INT ( dithertype ) ;
DEVMODE_CHECK_INT ( reserved1 ) ;
DEVMODE_CHECK_INT ( reserved2 ) ;
DEVMODE_CHECK_INT ( panningwidth ) ;
DEVMODE_CHECK_INT ( panningheight ) ;
2000-11-07 05:54:50 +03:00
2000-11-22 19:19:07 +03:00
/* compare the private data if it exists */
2000-12-14 21:37:01 +03:00
if ( ! d1 - > driverextra & & ! d2 - > driverextra ) goto equal ;
2000-12-18 09:02:31 +03:00
DEVMODE_CHECK_INT ( driverextra ) ;
2000-12-14 21:37:01 +03:00
if ( memcmp ( d1 - > private , d2 - > private , d1 - > driverextra ) ) {
DEBUG ( 10 , ( " nt_devicemode_equal(): private data not equal \n " ) ) ;
return False ;
}
2000-11-07 05:54:50 +03:00
2000-12-14 21:37:01 +03:00
equal :
DEBUG ( 10 , ( " nt_devicemode_equal(): devicemodes identical \n " ) ) ;
2000-11-07 05:54:50 +03:00
return True ;
}
/* Return true if two NT_PRINTER_PARAM structures are equal */
static BOOL nt_printer_param_equal ( NT_PRINTER_PARAM * p1 ,
NT_PRINTER_PARAM * p2 )
{
2000-12-14 21:37:01 +03:00
if ( ! p1 & & ! p2 ) goto equal ;
2000-11-07 05:54:50 +03:00
2000-12-14 21:37:01 +03:00
if ( ( ! p1 & & p2 ) | | ( p1 & & ! p2 ) ) {
DEBUG ( 10 , ( " nt_printer_param_equal(): pointers differ \n " ) ) ;
return False ;
}
2000-11-07 05:54:50 +03:00
/* Compare lists of printer parameters */
while ( p1 ) {
BOOL found = False ;
NT_PRINTER_PARAM * q = p1 ;
/* Find the parameter in the second structure */
while ( q ) {
2000-12-18 09:02:31 +03:00
if ( strequal ( p1 - > value , q - > value ) ) {
if ( p1 - > type ! = q - > type ) {
DEBUG ( 10 , ( " nt_printer_param_equal(): "
" types for %s differ (%d != %d) \n " ,
p1 - > value , p1 - > type ,
q - > type ) ) ;
break ;
}
if ( p1 - > data_len ! = q - > data_len ) {
DEBUG ( 10 , ( " nt_printer_param_equal(): "
" len for %s differs (%d != %d) \n " ,
p1 - > value , p1 - > data_len ,
q - > data_len ) ) ;
break ;
}
if ( memcmp ( p1 - > data , q - > data , p1 - > data_len ) = = 0 ) {
found = True ;
} else {
DEBUG ( 10 , ( " nt_printer_param_equal(): "
" data for %s differs \n " , p1 - > value ) ) ;
}
break ;
2000-11-07 05:54:50 +03:00
}
q = q - > next ;
}
if ( ! found ) {
2000-12-14 21:37:01 +03:00
DEBUG ( 10 , ( " nt_printer_param_equal(): param %s "
2000-12-18 09:02:31 +03:00
" does not exist \n " , p1 - > value ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
p1 = p1 - > next ;
}
2000-12-14 21:37:01 +03:00
equal :
DEBUG ( 10 , ( " nt_printer_param_equal(): printer params identical \n " ) ) ;
2000-11-07 05:54:50 +03:00
return True ;
}
/********************************************************************
* Called by update_printer when trying to work out whether to
* actually update printer info .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-12-18 09:02:31 +03:00
# define PI_CHECK_INT(field) \
if ( pi1 - > field ! = pi2 - > field ) { \
DEBUG ( 10 , ( " nt_printer_info_level_equal(): " # field " not equal (%d != %d) \n " , \
pi1 - > field , pi2 - > field ) ) ; \
return False ; \
}
# define PI_CHECK_STR(field) \
if ( ! strequal ( pi1 - > field , pi2 - > field ) ) { \
DEBUG ( 10 , ( " nt_printer_info_level_equal(): " # field " not equal (%s != %s) \n " , \
pi1 - > field , pi2 - > field ) ) ; \
return False ; \
}
2000-11-07 05:54:50 +03:00
static BOOL nt_printer_info_level_equal ( NT_PRINTER_INFO_LEVEL * p1 ,
NT_PRINTER_INFO_LEVEL * p2 )
{
NT_PRINTER_INFO_LEVEL_2 * pi1 , * pi2 ;
/* Trivial conditions */
if ( ( ! p1 & & ! p2 ) | | ( ! p1 - > info_2 & & ! p2 - > info_2 ) ) {
2000-12-14 21:37:01 +03:00
goto equal ;
2000-11-07 05:54:50 +03:00
}
2000-11-18 02:10:56 +03:00
if ( ( ! p1 & & p2 ) | | ( p1 & & ! p2 ) | |
2000-11-07 05:54:50 +03:00
( ! p1 - > info_2 & & p2 - > info_2 ) | |
( p1 - > info_2 & & ! p2 - > info_2 ) ) {
2000-12-14 21:37:01 +03:00
DEBUG ( 10 , ( " nt_printer_info_level_equal(): info levels "
" differ \n " ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
/* Compare two nt_printer_info_level structures. Don't compare
status or cjobs as they seem to have something to do with the
printer queue . */
pi1 = p1 - > info_2 ;
pi2 = p2 - > info_2 ;
2001-02-16 22:21:18 +03:00
/* Don't check the attributes as we stomp on the value in
check_printer_ok ( ) anyway . */
#if 0
2000-12-18 09:02:31 +03:00
PI_CHECK_INT ( attributes ) ;
2001-02-16 22:21:18 +03:00
# endif
2000-12-18 09:02:31 +03:00
PI_CHECK_INT ( priority ) ;
PI_CHECK_INT ( default_priority ) ;
PI_CHECK_INT ( starttime ) ;
PI_CHECK_INT ( untiltime ) ;
PI_CHECK_INT ( averageppm ) ;
2000-11-07 05:54:50 +03:00
2000-11-18 02:10:56 +03:00
/* Yuck - don't check the printername or servername as the
2000-11-07 05:54:50 +03:00
add_a_printer ( ) code plays games with them . You can ' t
change the printername or the sharename through this interface
in Samba . */
2000-12-18 09:02:31 +03:00
PI_CHECK_STR ( sharename ) ;
PI_CHECK_STR ( portname ) ;
PI_CHECK_STR ( drivername ) ;
PI_CHECK_STR ( comment ) ;
PI_CHECK_STR ( location ) ;
2000-11-07 05:54:50 +03:00
if ( ! nt_devicemode_equal ( pi1 - > devmode , pi2 - > devmode ) ) {
return False ;
}
2000-12-18 09:02:31 +03:00
PI_CHECK_STR ( sepfile ) ;
PI_CHECK_STR ( printprocessor ) ;
PI_CHECK_STR ( datatype ) ;
PI_CHECK_STR ( parameters ) ;
2000-11-07 05:54:50 +03:00
if ( ! nt_printer_param_equal ( pi1 - > specific , pi2 - > specific ) ) {
return False ;
}
if ( ! sec_desc_equal ( pi1 - > secdesc_buf - > sec , pi2 - > secdesc_buf - > sec ) ) {
return False ;
}
2000-12-18 09:02:31 +03:00
PI_CHECK_INT ( changeid ) ;
PI_CHECK_INT ( c_setprinter ) ;
PI_CHECK_INT ( setuptime ) ;
2000-11-07 05:54:50 +03:00
2000-12-14 21:37:01 +03:00
equal :
DEBUG ( 10 , ( " nt_printer_info_level_equal(): infos are identical \n " ) ) ;
2000-11-07 05:54:50 +03:00
return True ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* called by spoolss_api_setprinter
* when updating a printer description
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) ;
2000-08-09 08:19:18 +04:00
uint32 result ;
2000-07-10 09:08:21 +04:00
2000-02-07 19:17:59 +03:00
DEBUG ( 8 , ( " update_printer \n " ) ) ;
2001-08-27 23:46:22 +04:00
result = NT_STATUS_OK ;
2000-07-10 09:08:21 +04:00
2000-02-27 01:22:24 +03:00
if ( level ! = 2 ) {
2000-06-01 06:35:30 +04:00
DEBUG ( 0 , ( " 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-08-27 23:46:22 +04:00
result = NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
result = NT_STATUS_INVALID_HANDLE ;
2000-07-10 09:08:21 +04:00
goto done ;
}
2000-08-09 08:19:18 +04:00
2000-11-07 05:54:50 +03:00
if ( ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 ) | |
( get_a_printer ( & old_printer , 2 , lp_servicename ( snum ) ) ! = 0 ) ) {
2001-08-27 23:46:22 +04:00
result = NT_STATUS_INVALID_HANDLE ;
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 ' .
*/
2000-06-01 06:35:30 +04:00
convert_printer_info ( info , printer , level ) ;
2000-11-10 22:36:34 +03:00
2000-06-01 06:35:30 +04:00
if ( info - > info_2 - > devmode_ptr ! = 0 ) {
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
2000-02-07 19:17:59 +03:00
DEBUGADD ( 8 , ( " 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-08-10 09:41:53 +04:00
result = ERRinvalidparam ;
2000-07-22 04:48:29 +04:00
goto done ;
}
2000-11-07 05:54:50 +03:00
/* NT likes to call this function even though nothing has actually
changed . Check this so the user doesn ' t end up with an
annoying permission denied dialog box . */
if ( nt_printer_info_level_equal ( printer , old_printer ) ) {
DEBUG ( 3 , ( " printer info has not changed \n " ) ) ;
2001-08-27 23:46:22 +04:00
result = NT_STATUS_OK ;
2000-11-07 05:54:50 +03: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
if ( ! print_access_check ( NULL , snum , PRINTER_ACCESS_ADMINISTER ) ) {
DEBUG ( 3 , ( " printer property change denied by security "
" descriptor \n " ) ) ;
2001-08-27 23:46:22 +04:00
result = NT_STATUS_ACCESS_DENIED ;
2000-11-07 05:54:50 +03:00
goto done ;
}
/* Call addprinter hook */
2000-08-11 03:41:16 +04:00
if ( * lp_addprinter_cmd ( ) )
if ( ! add_printer_hook ( printer ) ) {
2001-08-27 23:46:22 +04:00
result = NT_STATUS_ACCESS_DENIED ;
2000-08-11 03:41:16 +04:00
goto done ;
}
2000-11-07 05:54:50 +03:00
/* Update printer info */
2000-06-01 06:35:30 +04:00
if ( add_a_printer ( * printer , 2 ) ! = 0 ) {
2000-02-27 01:22:24 +03:00
/* I don't really know what to return here !!! */
2001-08-27 23:46:22 +04:00
result = NT_STATUS_ACCESS_DENIED ;
2000-07-10 09:08:21 +04:00
goto done ;
2000-02-07 19:17:59 +03:00
}
2000-07-10 09:08:21 +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
2001-03-11 03:32:10 +03:00
srv_spoolss_sendnotify ( p , handle ) ;
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-08-27 23:46:22 +04:00
NTSTATUS _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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_setprinter: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
NTSTATUS _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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_fcpn: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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-08-10 09:41:53 +04:00
return ERRinvalidparam ; /* this is what a NT server
2000-08-28 08:42:31 +04:00
returns for AddJob . AddJob
must fail on non - local
printers */
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 ) ;
2001-02-16 22:21:18 +03:00
slprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , global_myname ) ;
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 ) ;
init_unistr ( & job_info - > username , queue - > user ) ;
init_unistr ( & job_info - > document , queue - > file ) ;
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 ;
job_info - > totalpages = 0 ;
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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ,
NT_PRINTER_INFO_LEVEL * ntprinter )
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 ) ;
2001-02-16 22:21:18 +03:00
slprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , global_myname ) ;
2000-02-07 19:17:59 +03:00
job_info - > jobid = queue - > job ;
2001-02-16 22:21:18 +03:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s \\ %s " , global_myname , 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 ) ;
init_unistr ( & job_info - > username , queue - > user ) ;
init_unistr ( & job_info - > document , queue - > file ) ;
init_unistr ( & job_info - > notifyname , queue - > user ) ;
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 ;
job_info - > totalpages = 0 ;
job_info - > size = queue - > size ;
make_systemtime ( & ( job_info - > submitted ) , t ) ;
job_info - > timeelapsed = 0 ;
job_info - > pagesprinted = 0 ;
2000-11-10 22:36:34 +03:00
if ( ( job_info - > devmode = construct_dev_mode ( snum ) ) = = NULL ) {
2000-04-07 02:48:53 +04:00
return False ;
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) {
safe_free ( queue ) ;
* 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
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 ) ) {
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 */
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
}
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ;
2000-02-15 21:07:45 +03:00
JOB_INFO_2 * info ;
int i ;
info = ( JOB_INFO_2 * ) malloc ( * returned * sizeof ( JOB_INFO_2 ) ) ;
2000-04-06 20:23:04 +04:00
if ( info = = NULL ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-06 20:23:04 +04:00
}
2001-01-18 01:55:02 +03:00
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 ) {
* returned = 0 ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2001-01-18 01:55:02 +03:00
}
2000-02-15 21:07:45 +03:00
for ( i = 0 ; i < * returned ; i + + )
2001-01-18 01:55:02 +03:00
fill_job_info_2 ( & ( info [ i ] ) , & queue [ i ] , i , snum , ntprinter ) ;
2000-04-06 20:23:04 +04:00
2001-01-18 01:55:02 +03:00
free_a_printer ( & ntprinter , 2 ) ;
2000-04-06 20:23:04 +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
2000-04-06 20:23:04 +04:00
if ( ! alloc_buffer_size ( buffer , * needed ) ) {
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_2 ( " " , buffer , & info [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
/* clear memory */
2001-01-18 01:55:02 +03:00
for ( i = 0 ; i < * returned ; i + + )
free_job_info_2 ( & info [ i ] ) ;
free ( info ) ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumjobs .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 firstjob = q_u->firstjob; - notused. */
/* uint32 numofjobs = q_u->numofjobs; - notused. */
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_queue_struct * queue = NULL ;
print_status_struct prt_status ;
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 " ) ) ;
ZERO_STRUCT ( prt_status ) ;
* needed = 0 ;
* returned = 0 ;
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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 ) {
safe_free ( queue ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_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 :
2000-04-06 20:23:04 +04:00
safe_free ( queue ) ;
* 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-08-27 23:46:22 +04:00
NTSTATUS _spoolss_schedulejob ( pipes_struct * p , SPOOL_Q_SCHEDULEJOB * q_u , SPOOL_R_SCHEDULEJOB * r_u )
2000-02-15 21:07:45 +03:00
{
return 0x0 ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 level = q_u->level; - notused. */
/* JOB_INFO *ctr = &q_u->ctr; - notused. */
uint32 command = q_u - > command ;
2000-07-06 10:53:47 +04:00
struct current_user user ;
2000-02-07 19:17:59 +03:00
print_status_struct prt_status ;
2001-08-10 09:41:53 +04:00
int snum , errcode = ERRbadfunc ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
memset ( & prt_status , 0 , sizeof ( prt_status ) ) ;
2000-02-07 19:17:59 +03:00
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) ) {
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2000-04-16 10:20:43 +04:00
if ( ! print_job_exists ( 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 :
2000-11-08 03:20:26 +03:00
if ( print_job_delete ( & user , jobid , & errcode ) ) {
errcode = 0 ;
2000-09-26 01:05:18 +04:00
}
2000-04-16 10:20:43 +04:00
break ;
case JOB_CONTROL_PAUSE :
2000-11-08 03:20:26 +03:00
if ( print_job_pause ( & user , jobid , & errcode ) ) {
errcode = 0 ;
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 :
2000-11-08 03:20:26 +03:00
if ( print_job_resume ( & user , jobid , & errcode ) ) {
errcode = 0 ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ;
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
2000-07-25 17:15:16 +04:00
# define MAX_VERSION 4
2000-02-07 19:17:59 +03:00
2000-07-25 17:15:16 +04:00
for ( version = 0 ; version < MAX_VERSION ; version + + ) {
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 " ) ) ;
safe_free ( driver_info_1 ) ;
2000-07-25 17:15:16 +04:00
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-08-27 23:46:22 +04:00
NTSTATUS status ;
2000-07-25 17:15:16 +04:00
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
2000-09-15 04:15:10 +04:00
if ( ( status = get_a_printer_driver ( & driver , 3 , list [ i ] , architecture , version ) ) ! = 0 ) {
safe_free ( list ) ;
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 ;
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 ) ) {
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
}
2000-03-16 19:23:38 +03: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
}
2000-02-15 21:07:45 +03:00
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumerates all printer drivers at level 2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ;
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
2000-07-25 17:15:16 +04:00
# define MAX_VERSION 4
for ( version = 0 ; version < MAX_VERSION ; version + + ) {
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 " ) ) ;
safe_free ( driver_info_2 ) ;
2000-07-25 17:15:16 +04:00
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-08-27 23:46:22 +04:00
NTSTATUS 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 ) ;
2000-09-15 04:15:10 +04:00
if ( ( status = get_a_printer_driver ( & driver , 3 , list [ i ] , architecture , version ) ) ! = 0 ) {
safe_free ( list ) ;
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 ;
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 ) ) {
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
}
2000-03-16 19:23:38 +03: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
}
2000-02-15 21:07:45 +03:00
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumerates all printer drivers at level 3.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ;
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
2000-07-25 17:15:16 +04:00
# define MAX_VERSION 4
2000-02-15 21:07:45 +03:00
2000-07-25 17:15:16 +04:00
for ( version = 0 ; version < MAX_VERSION ; version + + ) {
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 " ) ) ;
safe_free ( driver_info_3 ) ;
2000-07-25 17:15:16 +04:00
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-08-27 23:46:22 +04:00
NTSTATUS 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 ) ;
2000-09-15 04:15:10 +04:00
if ( ( status = get_a_printer_driver ( & driver , 3 , list [ i ] , architecture , version ) ) ! = 0 ) {
safe_free ( list ) ;
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 ;
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 ) ) {
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 + + )
safe_free ( driver_info_3 [ i ] . dependentfiles ) ;
safe_free ( driver_info_3 ) ;
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
}
2000-02-15 21:07:45 +03:00
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
Enumerates all printer drivers .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 05:38:09 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 *name = &q_u->name; - notused. */
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 " ) ) ;
fstrcpy ( servername , global_myname ) ;
* 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 ;
2000-07-25 17:15:16 +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-08-27 23:46:22 +04:00
NTSTATUS _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
/* POLICY_HND *handle = &q_u->handle; - notused. */
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-08-10 09:41:53 +04:00
if ( * numofforms = = 0 ) return ERRnomoreitems ;
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 ] ) ;
}
safe_free ( builtinlist ) ;
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-03-03 08:27:26 +03:00
safe_free ( list ) ;
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 ) ) {
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-03-03 08:27:26 +03:00
safe_free ( forms_1 ) ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-07 19:17:59 +03:00
default :
2001-03-03 08:27:26 +03:00
safe_free ( list ) ;
2001-04-04 03:09:04 +04:00
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-08-27 23:46:22 +04:00
NTSTATUS _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
/* POLICY_HND *handle = &q_u->handle; - notused. */
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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 ;
}
}
safe_free ( list ) ;
if ( i = = numofforms ) {
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-09-06 00:56:09 +04:00
default :
2001-03-03 08:27:26 +03: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
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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-08-27 23:46:22 +04:00
return NT_STATUS_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-03 12:50:59 +04:00
DEBUG ( 10 , ( " Returning WERR_NOMEM [%x] \n " , 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 ) ) {
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
}
safe_free ( ports ) ;
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
}
2000-02-15 21:07:45 +03:00
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
enumports level 2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 03:59:22 +04:00
2001-08-27 23:46:22 +04:00
static NTSTATUS 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-08-27 23:46:22 +04:00
return NT_STATUS_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 ) {
2001-09-03 12:50:59 +04:00
DEBUG ( 10 , ( " Returning WERR_NOMEM [%x] \n " , 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-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 ) ) {
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
}
safe_free ( ports ) ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
enumports .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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
/* UNISTR2 *name = &q_u->name; - notused. */
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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ,
2000-02-21 04:58:13 +03:00
uint32 unk0 , uint32 unk1 , uint32 unk2 , uint32 unk3 ,
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 ;
2000-02-21 04:58:13 +03:00
fstring name ;
2000-07-25 05:50:53 +04:00
int snum ;
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.*/
2000-06-01 06:35:30 +04:00
convert_printer_info ( info , printer , 2 ) ;
2000-02-07 19:17:59 +03:00
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-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-09-06 05:55:36 +04:00
}
2000-08-01 00:41:51 +04:00
slprintf ( name , sizeof ( name ) - 1 , " \\ \\ %s \\ %s " , global_myname ,
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-08-27 23:46:22 +04:00
return NT_STATUS_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-08-27 23:46:22 +04:00
return NT_STATUS_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-08-10 09:41:53 +04:00
return ERRinvalidparam ;
2000-07-25 05:50:53 +04:00
}
2001-08-10 23:38:53 +04:00
/*
* When a printer is created , the drivername bound to the printer is used
* to lookup previously saved driver initialization info , which is then
* bound to the new printer , simulating what happens in the Windows arch .
*/
set_driver_init ( printer , 2 ) ;
2000-03-13 18:53:02 +03:00
/* write the ASCII on disk */
2000-06-02 22:38:49 +04:00
if ( add_a_printer ( * printer , 2 ) ! = 0 ) {
free_a_printer ( & printer , 2 ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-06-02 22:38:49 +04:00
}
2000-03-13 18:53:02 +03:00
2001-03-11 03:32:10 +03:00
if ( ! open_printer_hnd ( p , handle , name ) ) {
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-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-02-07 19:17:59 +03:00
}
2000-06-02 22:38:49 +04:00
free_a_printer ( & printer , 2 ) ;
2000-09-26 01:05:18 +04:00
2001-03-11 03:32:10 +03:00
srv_spoolss_sendnotify ( p , handle ) ;
2000-09-26 01:05:18 +04:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_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-08-27 23:46:22 +04:00
NTSTATUS _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 ;
uint32 unk0 = q_u - > unk0 ;
uint32 unk1 = q_u - > unk1 ;
uint32 unk2 = q_u - > unk2 ;
uint32 unk3 = q_u - > unk3 ;
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 ,
2000-03-29 18:49:05 +04:00
unk0 , unk1 , unk2 , unk3 ,
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-08-27 23:46:22 +04:00
NTSTATUS _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
/* UNISTR2 *server_name = &q_u->server_name; - notused. */
uint32 level = q_u - > level ;
SPOOL_PRINTER_DRIVER_INFO_LEVEL * info = & q_u - > info ;
2001-08-27 23:46:22 +04:00
uint32 err = NT_STATUS_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 ;
2000-05-12 18:28:46 +04:00
ZERO_STRUCT ( driver ) ;
2000-09-22 01:44:15 +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-08-27 23:46:22 +04:00
if ( ( err = clean_up_driver_struct ( driver , level , & user ) ) ! = NT_STATUS_OK )
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 ) ) {
if ( err = = 0 )
2001-08-27 23:46:22 +04:00
err = NT_STATUS_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-08-27 23:46:22 +04:00
err = NT_STATUS_ACCESS_DENIED ;
2000-07-26 07:38:30 +04:00
goto done ;
}
2000-02-21 04:58:13 +03:00
2000-07-26 07:38:30 +04:00
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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ;
2000-07-25 17:15:16 +04:00
unistr2_to_ascii ( long_archi , uni_environment , sizeof ( long_archi ) - 1 ) ;
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
slprintf ( path , sizeof ( path ) - 1 , " \\ \\ %s \\ print$ \\ %s " , global_myname , short_archi ) ;
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 ) ) {
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
safe_free ( info ) ;
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-21 04:58:13 +03:00
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_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-08-27 23:46:22 +04:00
NTSTATUS _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-08-27 23:46:22 +04:00
NTSTATUS _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 ;
uint32 idx = q_u - > index ;
uint32 in_value_len = q_u - > valuesize ;
uint32 in_data_len = q_u - > datasize ;
uint32 * out_max_value_len = & r_u - > valuesize ;
uint16 * * out_value = & r_u - > value ;
uint32 * out_value_len = & r_u - > realvaluesize ;
uint32 * out_type = & r_u - > type ;
uint32 * out_max_data_len = & r_u - > datasize ;
uint8 * * data_out = & r_u - > data ;
uint32 * out_data_len = & r_u - > realdatasize ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-07 19:17:59 +03:00
fstring value ;
uint32 param_index ;
uint32 biggest_valuesize ;
uint32 biggest_datasize ;
uint32 data_len ;
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
int snum ;
2000-02-27 01:22:24 +03:00
uint8 * data = NULL ;
uint32 type ;
2000-02-07 19:17:59 +03:00
ZERO_STRUCT ( printer ) ;
2000-02-27 01:22:24 +03:00
* out_max_value_len = 0 ;
* out_value = NULL ;
* out_value_len = 0 ;
* out_type = 0 ;
* out_max_data_len = 0 ;
2000-03-10 20:12:24 +03:00
* data_out = NULL ;
2000-02-27 01:22:24 +03:00
* 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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_enumprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-25 02:01:24 +03:00
2000-06-29 04:52:40 +04:00
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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
*/
if ( ( in_value_len = = 0 ) & & ( in_data_len = = 0 ) ) {
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
2000-09-15 04:15:10 +04:00
#if 0
2000-09-08 00:56:24 +04:00
/*
* NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
* if this parameter size doesn ' t exist .
* Ok - my opinion here is that the client is not asking for the greatest
* possible size of all the parameters , but is asking specifically for the size needed
* for this specific parameter . In that case we can remove the loop below and
* simplify this lookup code considerably . JF - comments welcome . JRA .
*/
if ( ! get_specific_param_by_index ( * printer , 2 , idx , value , & data , & type , & data_len ) ) {
safe_free ( data ) ;
free_a_printer ( & printer , 2 ) ;
2001-08-10 09:41:53 +04:00
return ERRnomoreitems ;
2000-09-08 00:56:24 +04:00
}
2000-09-15 04:15:10 +04:00
# endif
2000-09-08 00:56:24 +04:00
safe_free ( data ) ;
data = NULL ;
2000-02-07 19:17:59 +03:00
param_index = 0 ;
biggest_valuesize = 0 ;
biggest_datasize = 0 ;
2000-06-01 06:35:30 +04:00
while ( get_specific_param_by_index ( * printer , 2 , param_index , value , & data , & type , & data_len ) ) {
2000-02-07 19:17:59 +03:00
if ( strlen ( value ) > biggest_valuesize ) biggest_valuesize = strlen ( value ) ;
2000-02-27 01:22:24 +03:00
if ( data_len > biggest_datasize ) biggest_datasize = data_len ;
2000-02-07 19:17:59 +03:00
2000-02-27 01:22:24 +03:00
DEBUG ( 6 , ( " current values: [%d], [%d] \n " , biggest_valuesize , biggest_datasize ) ) ;
safe_free ( data ) ;
2000-09-08 00:56:24 +04:00
data = NULL ;
2000-02-07 19:17:59 +03:00
param_index + + ;
}
2000-02-27 01:22:24 +03:00
2000-09-07 23:12:59 +04:00
/*
* I think this is correct , it doesn ' t break APW and
* allows Gerald ' s Win32 test programs to work correctly ,
* but may need altering . . . . JRA .
*/
if ( param_index = = 0 ) {
/* No parameters found. */
free_a_printer ( & printer , 2 ) ;
2001-08-10 09:41:53 +04:00
return ERRnomoreitems ;
2000-09-07 23:12:59 +04:00
}
2000-02-27 01:22:24 +03:00
/* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
* out_value_len = 2 * ( 1 + biggest_valuesize ) ;
* out_data_len = biggest_datasize ;
DEBUG ( 6 , ( " final values: [%d], [%d] \n " , * out_value_len , * out_data_len ) ) ;
2000-06-03 04:53:07 +04:00
free_a_printer ( & printer , 2 ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
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
*/
2000-03-13 14:09:20 +03:00
2000-06-01 06:35:30 +04:00
if ( ! get_specific_param_by_index ( * printer , 2 , idx , value , & data , & type , & data_len ) ) {
2000-04-07 02:48:53 +04:00
safe_free ( data ) ;
2000-06-03 04:53:07 +04:00
free_a_printer ( & printer , 2 ) ;
2001-08-10 09:41:53 +04:00
return ERRnomoreitems ;
2000-02-07 19:17:59 +03:00
}
2000-04-07 02:48:53 +04:00
2000-06-03 04:53:07 +04:00
free_a_printer ( & printer , 2 ) ;
2000-11-18 02:10:56 +03:00
/*
2000-02-27 01:22:24 +03:00
* 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
2000-06-22 05:39:17 +04:00
* out_max_value_len = ( in_value_len / sizeof ( uint16 ) ) ;
2001-02-28 03:51:02 +03:00
if ( ( * out_value = ( uint16 * ) talloc_zero ( p - > mem_ctx , in_value_len * sizeof ( uint8 ) ) ) = = NULL ) {
2000-04-07 02:48:53 +04:00
safe_free ( data ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
}
2000-07-12 18:10:40 +04:00
2001-07-04 11:15:53 +04:00
* out_value_len = rpcstr_push ( ( char * ) * out_value , value , in_value_len , 0 ) ;
2000-02-27 01:22:24 +03:00
* out_type = type ;
/* the data is counted in bytes */
* out_max_data_len = in_data_len ;
2001-02-28 03:51:02 +03:00
if ( ( * data_out = ( uint8 * ) talloc_zero ( p - > mem_ctx , in_data_len * sizeof ( uint8 ) ) ) = = NULL ) {
2000-04-07 02:48:53 +04:00
safe_free ( data ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-04-07 02:48:53 +04:00
}
2000-07-12 18:10:40 +04:00
2000-06-29 04:52:40 +04:00
memcpy ( * data_out , data , ( size_t ) data_len ) ;
2000-02-27 01:22:24 +03:00
* out_data_len = data_len ;
safe_free ( data ) ;
2000-02-07 19:17:59 +03:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _spoolss_setprinterdata ( pipes_struct * p , SPOOL_Q_SETPRINTERDATA * q_u , SPOOL_R_SETPRINTERDATA * r_u )
2000-02-07 19:17:59 +03:00
{
2001-03-01 00:19:31 +03:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * value = & q_u - > value ;
uint32 type = q_u - > type ;
/* uint32 max_len = q_u->max_len; - notused. */
uint8 * data = q_u - > data ;
uint32 real_len = q_u - > real_len ;
/* uint32 numeric_data = q_u->numeric_data; - notused. */
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-11-07 05:54:50 +03:00
NT_PRINTER_PARAM * param = NULL , old_param ;
2000-02-07 19:17:59 +03:00
int snum = 0 ;
2001-08-27 23:46:22 +04:00
NTSTATUS status = 0x0 ;
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_setprinterdata \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_setprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( status ! = 0x0 )
2001-09-03 12:50:59 +04:00
return WERR_INVALID_NAME ;
2000-02-07 19:17:59 +03:00
convert_specific_param ( & param , value , type , data , real_len ) ;
2000-11-07 05:54:50 +03:00
2001-01-30 00:34:08 +03:00
/* Check if we are making any changes or not. Return true if
2000-11-07 05:54:50 +03:00
nothing is actually changing . */
2001-01-30 00:34:08 +03:00
ZERO_STRUCT ( old_param ) ;
2000-11-07 05:54:50 +03:00
if ( get_specific_param ( * printer , 2 , param - > value , & old_param . data ,
2001-04-13 23:12:06 +04:00
& old_param . type , ( uint32 * ) & old_param . data_len ) ) {
2000-11-07 05:54:50 +03:00
if ( param - > type = = old_param . type & &
param - > data_len = = old_param . data_len & &
memcmp ( param - > data , old_param . data ,
old_param . data_len ) = = 0 ) {
DEBUG ( 3 , ( " setprinterdata hasn't changed \n " ) ) ;
2001-08-27 23:46:22 +04:00
status = NT_STATUS_OK ;
2000-11-07 05:54:50 +03:00
goto done ;
}
}
/* Access check */
if ( ! print_access_check ( NULL , snum , PRINTER_ACCESS_ADMINISTER ) ) {
DEBUG ( 3 , ( " security descriptor change denied by existing "
" security descriptor \n " ) ) ;
2001-08-27 23:46:22 +04:00
status = NT_STATUS_ACCESS_DENIED ;
2000-11-07 05:54:50 +03:00
goto done ;
}
2000-06-01 06:35:30 +04:00
unlink_specific_param_if_exist ( printer - > info_2 , param ) ;
2000-04-05 14:05:32 +04:00
2001-08-10 23:38:53 +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 ( param - > type = = 3 & & ! strcmp ( param - > value , PHANTOM_DEVMODE_KEY ) ) {
/*
* Set devmode and printer initialization info
*/
status = save_driver_init ( printer , 2 , param ) ;
}
else {
add_a_specific_param ( printer - > info_2 , & param ) ;
status = mod_a_printer ( * printer , 2 ) ;
}
2000-11-07 05:54:50 +03:00
done :
2000-06-03 04:53:07 +04:00
free_a_printer ( & printer , 2 ) ;
2000-11-17 05:22:35 +03:00
if ( param )
free_nt_printer_param ( & param ) ;
2000-11-07 05:54:50 +03:00
safe_free ( old_param . data ) ;
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
2001-08-27 23:46:22 +04:00
NTSTATUS _spoolss_deleteprinterdata ( pipes_struct * p , SPOOL_Q_DELETEPRINTERDATA * q_u , SPOOL_R_DELETEPRINTERDATA * r_u )
2000-09-09 04:19:35 +04:00
{
2001-02-28 04:24:55 +03:00
POLICY_HND * handle = & q_u - > handle ;
UNISTR2 * value = & q_u - > valuename ;
2000-09-09 04:19:35 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_PRINTER_PARAM param ;
int snum = 0 ;
2001-08-27 23:46:22 +04:00
NTSTATUS status = 0x0 ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-09-09 04:19:35 +04:00
DEBUG ( 5 , ( " spoolss_deleteprinterdata \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2000-09-09 04:19:35 +04:00
DEBUG ( 0 , ( " _spoolss_deleteprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-09-09 04:19:35 +04:00
}
2001-03-11 03:32:10 +03:00
if ( ! get_printer_snum ( p , handle , & snum ) )
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-09-09 04:19:35 +04:00
if ( ! print_access_check ( NULL , snum , PRINTER_ACCESS_ADMINISTER ) ) {
2001-01-19 19:58:23 +03:00
DEBUG ( 3 , ( " _spoolss_deleteprinterdata: printer properties "
" change denied by existing security descriptor \n " ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_ACCESS_DENIED ;
2000-09-09 04:19:35 +04:00
}
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( status ! = 0x0 )
2001-09-03 12:50:59 +04:00
return WERR_INVALID_NAME ;
2000-09-09 04:19:35 +04:00
ZERO_STRUCTP ( & param ) ;
unistr2_to_ascii ( param . value , value , sizeof ( param . value ) - 1 ) ;
if ( ! unlink_specific_param_if_exist ( printer - > info_2 , & param ) )
2001-08-10 09:41:53 +04:00
status = ERRinvalidparam ;
2000-09-09 04:19:35 +04:00
else
2000-10-27 01:43:13 +04:00
status = mod_a_printer ( * printer , 2 ) ;
2000-09-09 04:19:35 +04:00
free_a_printer ( & printer , 2 ) ;
return status ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 ;
/* uint32 level = q_u->level; - notused. */
FORM * form = & q_u - > form ;
2001-04-04 03:09:04 +04:00
nt_forms_struct tmpForm ;
2001-03-01 00:19:31 +03:00
2000-02-07 19:17:59 +03:00
int count = 0 ;
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_addform: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-07-07 03:31:46 +04:00
}
2000-02-07 19:17:59 +03:00
2001-04-04 03:09:04 +04:00
/* can't add if builtin */
if ( get_a_builtin_ntform ( & form - > name , & tmpForm ) ) {
2001-08-10 09:41:53 +04:00
return ERRinvalidparam ;
2001-04-04 03:09:04 +04:00
}
2001-03-03 08:27:26 +03:00
count = get_ntforms ( & list ) ;
if ( ! add_a_form ( & list , form , & count ) )
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-02-07 19:17:59 +03:00
write_ntforms ( & list , count ) ;
2001-03-03 08:27:26 +03:00
safe_free ( list ) ;
return 0x0 ;
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-08-27 23:46:22 +04:00
NTSTATUS _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 ;
2000-08-31 23:04:51 +04:00
int count = 0 ;
uint32 ret = 0 ;
nt_forms_struct * list = NULL ;
2001-03-11 03:32:10 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( p , handle ) ;
2000-08-31 23:04:51 +04:00
DEBUG ( 5 , ( " spoolss_deleteform \n " ) ) ;
2001-03-11 03:32:10 +03:00
if ( ! Printer ) {
2000-08-31 23:04:51 +04:00
DEBUG ( 0 , ( " _spoolss_deleteform: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-08-31 23:04:51 +04:00
}
2001-04-04 03:09:04 +04:00
/* can't delete if builtin */
if ( get_a_builtin_ntform ( form_name , & tmpForm ) ) {
2001-08-10 09:41:53 +04:00
return ERRinvalidparam ;
2001-04-04 03:09:04 +04:00
}
2001-03-03 08:27:26 +03:00
count = get_ntforms ( & list ) ;
2000-08-31 23:04:51 +04:00
if ( ! delete_a_form ( & list , form_name , & count , & ret ) )
2001-08-10 09:41:53 +04:00
return ERRinvalidparam ;
2000-08-31 23:04:51 +04:00
2001-03-03 08:27:26 +03:00
safe_free ( list ) ;
2000-08-31 23:04:51 +04:00
return ret ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 ;
/* UNISTR2 *uni_name = &q_u->name; - notused. */
/* uint32 level = q_u->level; - notused. */
FORM * form = & q_u - > form ;
2001-04-04 03:09:04 +04:00
nt_forms_struct tmpForm ;
2001-03-01 00:19:31 +03:00
2000-02-07 19:17:59 +03:00
int count = 0 ;
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 ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_setform: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2001-04-04 03:09:04 +04:00
/* can't set if builtin */
if ( get_a_builtin_ntform ( & form - > name , & tmpForm ) ) {
2001-08-10 09:41:53 +04:00
return ERRinvalidparam ;
2001-04-04 03:09:04 +04:00
}
2001-03-03 08:27:26 +03:00
count = get_ntforms ( & list ) ;
2000-02-07 19:17:59 +03:00
update_a_form ( & list , form , count ) ;
write_ntforms ( & list , count ) ;
2001-03-03 08:27:26 +03:00
safe_free ( list ) ;
2000-02-07 19:17:59 +03:00
return 0x0 ;
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
enumprintprocessors level 1.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) ;
safe_free ( info_1 ) ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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
/* UNISTR2 *name = &q_u->name; - notused. */
/* UNISTR2 *environment = &q_u->environment; - notused. */
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-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.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) ;
safe_free ( info_1 ) ;
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
}
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_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-08-27 23:46:22 +04:00
NTSTATUS _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
/* UNISTR2 *name = &q_u->name; - notused. */
/* UNISTR2 *processor = &q_u->processor; - notused. */
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-08-27 23:46:22 +04:00
static NTSTATUS 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 ) ;
safe_free ( info_1 ) ;
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-08-27 23:46:22 +04:00
return NT_STATUS_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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) ;
safe_free ( info_2 ) ;
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-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-15 21:07:45 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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
/* UNISTR2 *name = &q_u->name; - notused. */
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-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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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 ) {
safe_free ( queue ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-02-21 04:58:13 +03:00
}
for ( i = 0 ; i < count & & found = = False ; i + + ) {
if ( queue [ i ] . job = = ( int ) jobid )
found = True ;
}
if ( found = = False ) {
safe_free ( queue ) ;
2000-04-06 20:23:04 +04:00
safe_free ( info_1 ) ;
2000-02-21 04:58:13 +03:00
/* I shoud reply something else ... I can't find the good one */
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
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 ) ;
safe_free ( queue ) ;
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 ) ) {
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
safe_free ( info_1 ) ;
if ( * needed > offered )
2001-09-03 12:50:59 +04:00
return WERR_INSUFFICIENT_BUFFER ;
2000-02-21 04:58:13 +03:00
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
static NTSTATUS 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
{
int i = 0 ;
BOOL found = False ;
2000-06-16 12:18:09 +04:00
JOB_INFO_2 * info_2 ;
2001-01-18 01:55:02 +03:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
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 ) {
safe_free ( queue ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2000-02-21 04:58:13 +03:00
}
for ( i = 0 ; i < count & & found = = False ; i + + ) {
if ( queue [ i ] . job = = ( int ) jobid )
found = True ;
}
if ( found = = False ) {
safe_free ( queue ) ;
2000-04-06 20:23:04 +04:00
safe_free ( info_2 ) ;
2000-02-21 04:58:13 +03:00
/* I shoud reply something else ... I can't find the good one */
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-21 04:58:13 +03:00
}
2001-01-18 01:55:02 +03:00
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 ) {
safe_free ( queue ) ;
2001-09-03 12:50:59 +04:00
return WERR_NOMEM ;
2001-01-18 01:55:02 +03:00
}
fill_job_info_2 ( info_2 , & ( queue [ i - 1 ] ) , i , snum , ntprinter ) ;
2000-04-06 20:23:04 +04:00
2001-01-18 01:55:02 +03:00
free_a_printer ( & ntprinter , 2 ) ;
2000-04-06 20:23:04 +04:00
safe_free ( queue ) ;
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 ) ) {
safe_free ( info_2 ) ;
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_2 ( " " , buffer , info_2 , 0 ) ;
2000-02-21 04:58:13 +03:00
2000-12-15 04:47:37 +03:00
free_job_info_2 ( info_2 ) ;
2001-01-18 01:55:02 +03:00
free ( info_2 ) ;
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
else
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2000-02-21 04:58:13 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-01 00:19:31 +03:00
2001-08-27 23:46:22 +04:00
NTSTATUS _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 ;
2000-02-07 19:17:59 +03:00
int snum ;
int count ;
print_queue_struct * queue = NULL ;
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
2000-02-24 19:27:06 +03:00
memset ( & prt_status , 0 , sizeof ( prt_status ) ) ;
2000-02-07 19:17:59 +03:00
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-08-27 23:46:22 +04:00
return NT_STATUS_INVALID_HANDLE ;
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
switch ( level ) {
case 1 :
return getjob_level_1 ( queue , count , snum , jobid , buffer , offered , needed ) ;
case 2 :
2000-04-05 14:05:32 +04:00
return getjob_level_2 ( queue , count , snum , jobid , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
default :
safe_free ( queue ) ;
2001-09-03 12:50:59 +04:00
return WERR_UNKNOWN_LEVEL ;
2000-02-07 19:17:59 +03:00
}
}