2000-05-27 00:54:46 +04:00
# define OLD_NTDOMAIN 1
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.
*
* 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 .
*
* 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 .
*
* 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 .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
extern pstring global_myname ;
# ifndef MAX_OPEN_PRINTER_EXS
# define MAX_OPEN_PRINTER_EXS 50
# endif
# define PRINTER_HANDLE_IS_PRINTER 0
# define PRINTER_HANDLE_IS_PRINTSERVER 1
/* 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 {
ubi_dlNode Next ;
ubi_dlNode Prev ;
2000-02-24 19:27:06 +03:00
BOOL open ;
BOOL document_started ;
BOOL page_started ;
2000-04-16 10:20:43 +04:00
int jobid ; /* jobid in printing backend */
2000-02-24 19:27:06 +03:00
POLICY_HND printer_hnd ;
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 ;
fstring localmachine ;
uint32 printerlocal ;
SPOOL_NOTIFY_OPTION * option ;
} 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 ;
2000-02-25 02:01:24 +03:00
static ubi_dlList Printer_list ;
2000-03-10 20:12:24 +03:00
static ubi_dlList counter_list ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
# define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
# define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==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_PAUSED :
return PRINTER_STATUS_PAUSED ;
case LPQ_QUEUED :
case LPQ_SPOOLING :
case LPQ_PRINTING :
return 0 ;
}
return 0 ;
}
static int nt_printq_status ( int v )
{
switch ( v ) {
case LPQ_PAUSED :
return PRINTER_STATUS_ERROR ;
case LPQ_QUEUED :
case LPQ_SPOOLING :
case LPQ_PRINTING :
return 0 ;
}
return 0 ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
initialise printer handle states . . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void init_printer_hnd ( void )
{
2000-02-25 02:01:24 +03:00
ubi_dlInitList ( & Printer_list ) ;
2000-03-10 20:12:24 +03:00
ubi_dlInitList ( & counter_list ) ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
create a unique printer handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void create_printer_hnd ( POLICY_HND * hnd )
{
static uint32 prt_hnd_low = 0 ;
static uint32 prt_hnd_high = 0 ;
if ( hnd = = NULL ) return ;
/* i severely doubt that prt_hnd_high will ever be non-zero... */
prt_hnd_low + + ;
if ( prt_hnd_low = = 0 ) prt_hnd_high + + ;
SIVAL ( hnd - > data , 0 , 0x0 ) ; /* first bit must be null */
SIVAL ( hnd - > data , 4 , prt_hnd_low ) ; /* second bit is incrementing */
SIVAL ( hnd - > data , 8 , prt_hnd_high ) ; /* second bit is incrementing */
SIVAL ( hnd - > data , 12 , time ( NULL ) ) ; /* something random */
2000-05-02 06:23:41 +04:00
SIVAL ( hnd - > data , 16 , sys_getpid ( ) ) ; /* something more random */
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
find printer index by handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-25 02:01:24 +03:00
static Printer_entry * find_printer_index_by_hnd ( const POLICY_HND * hnd )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * find_printer ;
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
find_printer = ( Printer_entry * ) ubi_dlFirst ( & Printer_list ) ;
for ( ; find_printer ; find_printer = ( Printer_entry * ) ubi_dlNext ( find_printer ) ) {
2000-06-27 02:08:20 +04:00
if ( memcmp ( & ( find_printer - > printer_hnd ) , hnd , sizeof ( * hnd ) ) = = 0 ) {
2000-02-25 02:01:24 +03:00
DEBUG ( 4 , ( " Found printer handle \n " ) ) ;
2000-02-24 19:27:06 +03:00
/*dump_data(4, hnd->data, sizeof(hnd->data));*/
2000-02-25 02:01:24 +03:00
return find_printer ;
2000-02-07 19:17:59 +03:00
}
}
2000-02-25 02:01:24 +03:00
2000-02-07 19:17:59 +03:00
DEBUG ( 3 , ( " Whoops, Printer handle not found: " ) ) ;
2000-02-24 19:27:06 +03:00
/*dump_data(4, hnd->data, sizeof(hnd->data));*/
2000-02-25 02:01:24 +03:00
return NULL ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
clear an handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void clear_handle ( POLICY_HND * hnd )
{
2000-05-29 01:01:14 +04:00
ZERO_STRUCTP ( hnd ) ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
close printer index by handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL close_printer_handle ( POLICY_HND * hnd )
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( hnd ) ;
2000-02-07 19:17:59 +03:00
2000-06-27 02:08:20 +04:00
if ( ! OPEN_HANDLE ( 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 ;
}
2000-02-25 02:01:24 +03:00
Printer - > open = False ;
Printer - > notify . flags = 0 ;
Printer - > notify . options = 0 ;
Printer - > notify . localmachine [ 0 ] = ' \0 ' ;
Printer - > notify . printerlocal = 0 ;
safe_free ( Printer - > notify . option ) ;
Printer - > notify . option = NULL ;
2000-02-24 19:27:06 +03:00
2000-02-07 19:17:59 +03:00
clear_handle ( hnd ) ;
2000-02-25 02:01:24 +03:00
ubi_dlRemThis ( & Printer_list , Printer ) ;
safe_free ( Printer ) ;
2000-02-07 19:17:59 +03:00
return True ;
}
2000-05-02 19:31:55 +04:00
/****************************************************************************
delete a printer given a handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL delete_printer_handle ( POLICY_HND * hnd )
{
Printer_entry * Printer = find_printer_index_by_hnd ( hnd ) ;
2000-06-27 02:08:20 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " delete_printer_handle: Invalid handle (%s) \n " , OUR_HANDLE ( hnd ) ) ) ;
2000-05-02 19:31:55 +04:00
return False ;
}
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 ) ) ;
2000-05-02 19:31:55 +04:00
return False ;
}
2000-08-01 00:41:51 +04:00
if ( * lp_deleteprinter_cmd ( ) ) {
pid_t local_pid = sys_getpid ( ) ;
char * cmd = lp_deleteprinter_cmd ( ) ;
char * path ;
pstring tmp_file ;
pstring command ;
int ret ;
int i ;
if ( * lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) )
path = lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) ;
else
path = tmpdir ( ) ;
/* Printer->dev.handlename equals portname equals sharename */
slprintf ( command , sizeof ( command ) , " %s \" %s \" " , cmd ,
Printer - > dev . handlename ) ;
slprintf ( tmp_file , sizeof ( tmp_file ) , " %s/smbcmd.%d " , path , local_pid ) ;
unlink ( tmp_file ) ;
DEBUG ( 10 , ( " Running [%s > %s] \n " , command , tmp_file ) ) ;
ret = smbrun ( command , tmp_file , False ) ;
if ( ret ! = 0 ) {
unlink ( tmp_file ) ;
return False ;
}
DEBUGADD ( 10 , ( " returned [%d] \n " , ret ) ) ;
DEBUGADD ( 10 , ( " Unlinking output file [%s] \n " , tmp_file ) ) ;
unlink ( tmp_file ) ;
if ( ( i = lp_servicenumber ( Printer - > dev . handlename ) ) > = 0 ) {
lp_remove_service ( i ) ;
lp_killservice ( i ) ;
return True ;
} else
return False ;
}
2000-05-02 19:31:55 +04:00
return True ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
return the snum of a printer corresponding to an handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static BOOL get_printer_snum ( POLICY_HND * hnd , int * number )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( hnd ) ;
2000-02-07 19:17:59 +03:00
2000-04-16 10:20:43 +04:00
if ( ! OPEN_HANDLE ( 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-02-07 19:17:59 +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 ;
break ;
default :
return False ;
break ;
}
}
/****************************************************************************
set printer handle type .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL set_printer_hnd_accesstype ( POLICY_HND * hnd , uint32 access_required )
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( hnd ) ;
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
if ( ! OPEN_HANDLE ( 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 */
2000-07-22 04:48:29 +04:00
if ( ! strchr ( 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
return True ;
}
/* 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
return True ;
}
return False ;
}
/****************************************************************************
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
2000-07-22 04:48:29 +04:00
aprinter = strchr ( handlename + 2 , ' \\ ' ) ;
2000-02-15 21:07:45 +03:00
aprinter + + ;
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-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 ) ) ) ;
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
continue ;
2000-07-22 04:48:29 +04: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-06-01 06:35:30 +04:00
if ( strlen ( printer - > info_2 - > printername ) ! = strlen ( aprinter ) ) {
free_a_printer ( & printer , 2 ) ;
2000-02-15 21:07:45 +03:00
continue ;
}
2000-06-01 06:35:30 +04:00
if ( strncasecmp ( printer - > info_2 - > printername , aprinter , strlen ( aprinter ) ) ) {
free_a_printer ( & printer , 2 ) ;
2000-02-15 21:07:45 +03:00
continue ;
}
found = True ;
}
2000-04-11 01:47:46 +04: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
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
continue ;
2000-07-22 04:48:29 +04: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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL open_printer_hnd ( POLICY_HND * hnd , char * name )
{
Printer_entry * new_printer ;
clear_handle ( hnd ) ;
create_printer_hnd ( hnd ) ;
if ( ( new_printer = ( Printer_entry * ) malloc ( sizeof ( Printer_entry ) ) ) = = NULL )
return False ;
ZERO_STRUCTP ( new_printer ) ;
new_printer - > open = True ;
new_printer - > notify . option = NULL ;
memcpy ( & new_printer - > printer_hnd , hnd , sizeof ( * hnd ) ) ;
ubi_dlAddHead ( & Printer_list , ( ubi_dlNode * ) new_printer ) ;
if ( ! set_printer_hnd_printertype ( new_printer , name ) ) {
close_printer_handle ( hnd ) ;
return False ;
}
if ( ! set_printer_hnd_name ( new_printer , name ) ) {
close_printer_handle ( hnd ) ;
return False ;
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL handle_is_printserver ( const POLICY_HND * handle )
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-02-25 02:01:24 +03:00
if ( ! OPEN_HANDLE ( 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
/*
* save the offset and move to the end of the buffer
* prs_grow ( ) checks the extra_space against the offset
*/
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-07-18 23:25:32 +04:00
#if 0 /* JRATEST */
buffer - > string_at_end = buffer_size ;
# else
2000-02-15 21:07:45 +03:00
buffer - > string_at_end = prs_data_size ( ps ) ;
2000-07-18 23:25:32 +04:00
# endif
2000-02-15 21:07:45 +03:00
return True ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
* spoolss_open_printer
*
* called from the spoolss dispatcher
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_open_printer_ex ( const UNISTR2 * printername ,
const PRINTER_DEFAULT * printer_default ,
uint32 user_switch , SPOOL_USER_CTR user_ctr ,
POLICY_HND * handle )
{
fstring name ;
if ( printername = = NULL )
2000-03-29 16:36:44 +04:00
return ERROR_INVALID_PRINTER_NAME ;
2000-02-07 19:17:59 +03:00
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
unistr2_to_ascii ( name , printername , sizeof ( name ) - 1 ) ;
DEBUGADD ( 3 , ( " checking name: %s \n " , name ) ) ;
2000-07-22 04:48:29 +04:00
if ( ! open_printer_hnd ( handle , name ) )
2000-03-29 16:36:44 +04:00
return ERROR_INVALID_PRINTER_NAME ;
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 , " " ) ;
*/
2000-02-15 21:07:45 +03:00
if ( ! set_printer_hnd_accesstype ( handle , printer_default - > access_required ) ) {
2000-02-07 19:17:59 +03:00
close_printer_handle ( handle ) ;
2000-03-29 16:36:44 +04:00
return ERROR_ACCESS_DENIED ;
2000-02-07 19:17:59 +03:00
}
2000-02-15 21:07:45 +03:00
2000-02-07 19:17:59 +03:00
return NT_STATUS_NO_PROBLEMO ;
}
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-02-07 19:17:59 +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
{
2000-02-21 04:58:13 +03:00
switch ( level ) {
2000-02-07 19:17:59 +03:00
case 3 :
printer - > info_3 = NULL ;
2000-06-21 03:58:56 +04:00
uni_2_asc_printer_driver_3 ( uni - > info_3 , & printer - > info_3 ) ;
2000-05-12 18:28:46 +04:00
break ;
case 6 :
printer - > info_6 = NULL ;
2000-06-21 03:58:56 +04:00
uni_2_asc_printer_driver_6 ( uni - > info_6 , & printer - > info_6 ) ;
2000-02-07 19:17:59 +03:00
break ;
default :
break ;
}
return True ;
}
2000-06-01 06:35:30 +04:00
static BOOL convert_devicemode ( const DEVICEMODE * devmode , NT_DEVICEMODE * nt_devmode )
{
unistr_to_dos ( nt_devmode - > devicename , ( const char * ) devmode - > devicename . buffer , 31 ) ;
unistr_to_dos ( nt_devmode - > formname , ( const char * ) devmode - > formname . buffer , 31 ) ;
nt_devmode - > specversion = devmode - > specversion ;
nt_devmode - > driverversion = devmode - > driverversion ;
nt_devmode - > size = devmode - > size ;
nt_devmode - > driverextra = devmode - > driverextra ;
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 ;
if ( nt_devmode - > driverextra ! = 0 ) {
2000-02-07 19:17:59 +03:00
/* if we had a previous private delete it and make a new one */
2000-06-01 06:35:30 +04:00
safe_free ( nt_devmode - > private ) ;
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
}
return True ;
}
/********************************************************************
* api_spoolss_closeprinter
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_closeprinter ( POLICY_HND * handle )
{
if ( ! close_printer_handle ( handle ) )
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
return NT_STATUS_NO_PROBLEMO ;
}
2000-05-02 19:31:55 +04:00
/********************************************************************
* api_spoolss_deleteprinter
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_deleteprinter ( POLICY_HND * handle )
{
if ( ! delete_printer_handle ( handle ) )
return ERROR_INVALID_HANDLE ;
return NT_STATUS_NO_PROBLEMO ;
}
2000-02-07 19:17:59 +03:00
/********************************************************************
2000-02-15 21:07:45 +03:00
GetPrinterData on a printer server Handle .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-07 21:06:54 +03:00
static BOOL getprinterdata_printer_server ( 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 ;
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( 4 * sizeof ( uint8 ) ) ) = = NULL )
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 ;
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( 4 * sizeof ( uint8 ) ) ) = = NULL )
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 ;
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( 4 * sizeof ( uint8 ) ) ) = = NULL )
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 ;
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( 4 * sizeof ( uint8 ) ) ) = = NULL )
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 ;
}
2000-06-01 06:35:30 +04: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 ) ;
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( ( ( * needed > in_size ) ? * needed : in_size ) * sizeof ( uint8 ) ) ) = = NULL )
return False ;
2000-02-15 21:07:45 +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 ) ;
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( ( ( * needed > in_size ) ? * needed : in_size ) * sizeof ( uint8 ) ) ) = = NULL )
return False ;
2000-02-15 21:07:45 +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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static BOOL getprinterdata_printer ( POLICY_HND * handle ,
2000-02-07 19:17:59 +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 ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " getprinterdata_printer \n " ) ) ;
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
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
2000-04-07 02:48:53 +04:00
if ( ! get_printer_snum ( handle , & snum ) )
return False ;
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
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 ) {
if ( ( * data = ( uint8 * ) malloc ( in_size * sizeof ( uint8 ) ) ) = = NULL ) {
return False ;
}
2000-04-07 02:48:53 +04:00
2000-06-06 00:55:57 +04:00
memset ( * data , 0 , in_size * sizeof ( uint8 ) ) ;
/* 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_getprinterdata ( POLICY_HND * handle , UNISTR2 * valuename ,
2000-02-07 19:17:59 +03:00
uint32 in_size ,
uint32 * type ,
uint32 * out_size ,
uint8 * * data ,
uint32 * needed )
{
fstring value ;
2000-02-07 21:06:54 +03:00
BOOL found = False ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
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
2000-02-25 02:01:24 +03:00
if ( ! OPEN_HANDLE ( Printer ) ) {
2000-04-07 02:48:53 +04:00
if ( ( * data = ( uint8 * ) malloc ( 4 * sizeof ( uint8 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " _spoolss_getprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
unistr2_to_ascii ( value , valuename , sizeof ( value ) - 1 ) ;
if ( handle_is_printserver ( handle ) )
2000-02-07 21:06:54 +03:00
found = getprinterdata_printer_server ( value , type , data , needed , * out_size ) ;
2000-02-07 19:17:59 +03:00
else
2000-02-07 21:06:54 +03:00
found = getprinterdata_printer ( 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 ) {
if ( ( * data = ( uint8 * ) malloc ( * out_size * sizeof ( uint8 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
memset ( * data , ' \0 ' , * out_size * sizeof ( uint8 ) ) ;
} else {
* data = NULL ;
}
2000-02-07 19:17:59 +03:00
return ERROR_INVALID_PARAMETER ;
}
if ( * needed > * out_size )
2000-09-08 04:28:07 +04:00
return ERROR_MORE_DATA ;
2000-02-07 19:17:59 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
/********************************************************************
* _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
* called from api_spoolss_rffpcnex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_rffpcnex ( POLICY_HND * handle , uint32 flags , uint32 options ,
2000-02-24 19:27:06 +03:00
const UNISTR2 * localmachine , uint32 printerlocal ,
SPOOL_NOTIFY_OPTION * option )
2000-02-07 19:17:59 +03:00
{
/* store the notify value in the printer struct */
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_rffpcnex: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_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 ;
Printer - > notify . options = options ;
Printer - > notify . printerlocal = printerlocal ;
Printer - > notify . option = option ;
unistr2_to_ascii ( Printer - > notify . localmachine , localmachine , sizeof ( Printer - > notify . localmachine ) - 1 ) ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the servername
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
static void spoolss_notify_server_name ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer )
2000-02-07 19:17:59 +03:00
{
pstring temp_name ;
2000-05-23 00:04:50 +04:00
snprintf ( temp_name , sizeof ( temp_name ) - 1 , " \\ \\ %s " , global_myname ) ;
2000-02-07 19:17:59 +03:00
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
temp_name , sizeof ( data - > notify_data . data . string ) , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the servicename
* jfmxxxx : it ' s incorrect should be long_printername
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 06:35:30 +04:00
static void spoolss_notify_printer_name ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue ,
NT_PRINTER_INFO_LEVEL * printer )
2000-02-07 19:17:59 +03:00
{
/*
data - > notify_data . data . length = strlen ( lp_servicename ( snum ) ) ;
2000-06-22 05:39:17 +04:00
dos_PutUniCode ( data - > notify_data . data . string , lp_servicename ( snum ) , sizeof ( data - > notify_data . data . string ) , True ) ;
2000-02-07 19:17:59 +03:00
*/
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > printername , sizeof ( data - > notify_data . data . string ) , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the servicename
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_share_name ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
lp_servicename ( snum ) , sizeof ( data - > notify_data . data . string ) , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the port name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_port_name ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
/* even if it's strange, that's consistant in all the code */
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
lp_servicename ( snum ) , sizeof ( data - > notify_data . data . string ) , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_driver_name ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > drivername , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the comment
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_comment ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-07-26 14:31:05 +04:00
if ( * printer - > info_2 - > comment = = ' \0 ' )
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
2000-06-22 05:39:17 +04:00
lp_comment ( snum ) , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-07-26 14:31:05 +04:00
else
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > comment , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
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 "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_location ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > location , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
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 ! ! !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_devmode ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
}
/*******************************************************************
* 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 "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_sepfile ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > sepfile , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_print_processor ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > printprocessor , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with the print processor options
* jfm : xxxx send an empty string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_parameters ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > parameters , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_datatype ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
printer - > info_2 - > datatype , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
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 !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_security_desc ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . data . length = 0 ;
data - > notify_data . data . string [ 0 ] = 0x00 ;
}
/*******************************************************************
* fill a notify_info_data with the attributes
* jfm : xxxx a samba printer is always shared
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_attributes ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = PRINTER_ATTRIBUTE_SHARED \
2000-07-01 13:34:37 +04:00
| PRINTER_ATTRIBUTE_LOCAL \
2000-02-07 19:17:59 +03:00
| PRINTER_ATTRIBUTE_RAW_ONLY ;
}
/*******************************************************************
* fill a notify_info_data with the priority
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_priority ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > priority ;
}
/*******************************************************************
* fill a notify_info_data with the default priority
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_default_priority ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > default_priority ;
}
/*******************************************************************
* fill a notify_info_data with the start time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_start_time ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > starttime ;
}
/*******************************************************************
* fill a notify_info_data with the until time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_until_time ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = printer - > info_2 - > untiltime ;
}
/*******************************************************************
* fill a notify_info_data with the status
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_status ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
int count ;
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
count = 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_cjobs ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_average_ppm ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
/* always respond 8 pages per minutes */
/* a little hard ! */
data - > notify_data . value [ 0 ] = printer - > info_2 - > averageppm ;
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_username ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
queue - > user , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_job_status ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
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
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_job_name ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
queue - > file , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_job_status_string ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
2000-04-16 11:28:06 +04:00
char * p = " unknown " ;
switch ( queue - > status ) {
case LPQ_QUEUED :
p = " QUEUED " ;
break ;
case LPQ_PAUSED :
p = " PAUSED " ;
break ;
case LPQ_SPOOLING :
p = " SPOOLING " ;
break ;
case LPQ_PRINTING :
p = " PRINTING " ;
break ;
}
2000-06-22 05:39:17 +04:00
data - > notify_data . data . length = ( uint32 ) ( ( dos_PutUniCode ( ( char * ) data - > notify_data . data . string ,
p , sizeof ( data - > notify_data . data . string ) - 1 , True ) - sizeof ( uint16 ) ) / sizeof ( uint16 ) ) ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_job_time ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = 0x0 ;
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_job_size ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = queue - > size ;
}
/*******************************************************************
* fill a notify_info_data with
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void spoolss_notify_job_position ( int snum , SPOOL_NOTIFY_INFO_DATA * data , print_queue_struct * queue , NT_PRINTER_INFO_LEVEL * printer )
{
data - > notify_data . value [ 0 ] = queue - > job ;
}
# 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 ,
NT_PRINTER_INFO_LEVEL * printer ) ;
} ;
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 } ,
{ JOB_NOTIFY_TYPE , JOB_NOTIFY_SUBMITTED , " JOB_NOTIFY_SUBMITTED " , POINTER , NULL } ,
{ 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ;
continue ;
}
i + + ;
}
return ( 65535 ) ;
}
/*******************************************************************
return the type of notify_info_data
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ) ;
}
continue ;
}
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 ) ;
}
/*******************************************************************
*
* fill a notify_info struct with info asked
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-24 19:27:06 +03:00
static BOOL construct_notify_printer_info ( SPOOL_NOTIFY_INFO * info , int snum , SPOOL_NOTIFY_OPTION_TYPE * option_type , uint32 id )
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 ;
2000-02-24 19:27:06 +03:00
SPOOL_NOTIFY_INFO_DATA * current_data ;
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 ;
2000-02-07 19:17:59 +03:00
DEBUG ( 4 , ( " construct_notify_printer_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] on printer: [%s] \n " ,
( option_type - > type = = PRINTER_NOTIFY_TYPE ? " PRINTER_NOTIFY_TYPE " : " JOB_NOTIFY_TYPE " ) ,
option_type - > count , lp_servicename ( snum ) ) ) ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
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 ] ;
DEBUGADD ( 4 , ( " notify [%d]: type [%x], field [%x] \n " , field_num , type , field ) ) ;
if ( ! search_notify ( type , field , & j ) )
continue ;
2000-02-07 19:17:59 +03:00
2000-04-07 02:48:53 +04:00
if ( ( info - > data = Realloc ( info - > data , ( info - > count + 1 ) * sizeof ( SPOOL_NOTIFY_INFO_DATA ) ) ) = = NULL ) {
return False ;
}
2000-06-29 04:52:40 +04: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-06-01 06:35:30 +04:00
notify_info_data_table [ j ] . fn ( snum , current_data , queue , printer ) ;
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-02-24 19:27:06 +03:00
static BOOL construct_notify_jobs_info ( print_queue_struct * queue , SPOOL_NOTIFY_INFO * info , int snum , SPOOL_NOTIFY_OPTION_TYPE * option_type , uint32 id )
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 ;
2000-02-24 19:27:06 +03:00
SPOOL_NOTIFY_INFO_DATA * current_data ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
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 " ,
( option_type - > type = = PRINTER_NOTIFY_TYPE ? " PRINTER_NOTIFY_TYPE " : " JOB_NOTIFY_TYPE " ) ,
option_type - > count ) ) ;
2000-02-07 19:17:59 +03:00
2000-02-24 19:27:06 +03:00
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
return False ;
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 ;
2000-04-07 02:48:53 +04:00
if ( ( info - > data = Realloc ( info - > data , ( info - > count + 1 ) * sizeof ( SPOOL_NOTIFY_INFO_DATA ) ) ) = = NULL ) {
return False ;
}
2000-02-24 19:27:06 +03:00
current_data = & ( info - > data [ info - > count ] ) ;
construct_info_data ( current_data , type , field , id ) ;
2000-06-01 06:35:30 +04:00
notify_info_data_table [ j ] . fn ( snum , current_data , queue , printer ) ;
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
free_a_printer ( & printer , 2 ) ;
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 .
*
* 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-02-24 19:27:06 +03:00
static uint32 printserver_notify_info ( const POLICY_HND * hnd , SPOOL_NOTIFY_INFO * info )
2000-02-07 19:17:59 +03:00
{
int snum ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( 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 ) )
if ( construct_notify_printer_info ( info , snum , option_type , id ) )
id + + ;
2000-02-07 19:17:59 +03:00
}
2000-02-24 19:27:06 +03:00
/*
* Debugging information , don ' t delete .
*/
/*
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-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
*/
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/*******************************************************************
*
* fill a notify_info struct with info asked
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static uint32 printer_notify_info ( POLICY_HND * hnd , SPOOL_NOTIFY_INFO * info )
2000-02-07 19:17:59 +03:00
{
int snum ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( 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 ;
2000-02-24 19:27:06 +03:00
get_printer_snum ( 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 :
if ( construct_notify_printer_info ( info , snum , option_type , id ) )
2000-04-05 14:05:32 +04:00
id - - ;
2000-02-24 19:27:06 +03:00
break ;
case JOB_NOTIFY_TYPE :
memset ( & status , 0 , sizeof ( status ) ) ;
2000-04-16 10:20:43 +04:00
count = print_queue_status ( snum , & queue , & status ) ;
2000-02-24 19:27:06 +03:00
for ( j = 0 ; j < count ; j + + )
2000-06-29 04:52:40 +04:00
construct_notify_jobs_info ( & queue [ j ] , info , snum , option_type , queue [ j ] . job ) ;
2000-02-24 19:27:06 +03:00
safe_free ( queue ) ;
break ;
2000-02-07 19:17:59 +03:00
}
}
2000-02-24 19:27:06 +03:00
/*
* Debugging information , don ' t delete .
*/
/*
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-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 ) ) ;
}
*/
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* spoolss_rfnpcnex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_rfnpcnex ( POLICY_HND * handle , uint32 change ,
2000-02-24 19:27:06 +03:00
SPOOL_NOTIFY_OPTION * option , SPOOL_NOTIFY_INFO * info )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_rfnpcnex: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_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
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
* I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
* 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
2000-02-24 19:27:06 +03:00
/* just discard the SPOOL_NOTIFY_OPTION */
if ( option ! = NULL )
safe_free ( option - > ctr . type ) ;
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 :
return printserver_notify_info ( handle , info ) ;
2000-02-24 19:27:06 +03:00
break ;
2000-02-07 19:17:59 +03:00
case PRINTER_HANDLE_IS_PRINTER :
return printer_notify_info ( handle , info ) ;
2000-02-24 19:27:06 +03:00
break ;
2000-02-07 19:17:59 +03:00
}
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* construct_printer_info_0
* fill a printer_info_1 struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-23 18:25:36 +04:00
static BOOL construct_printer_info_0 ( PRINTER_INFO_0 * printer , int snum , fstring servername )
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-06-03 00:08:28 +04:00
time_t setup_time = time ( 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-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
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 )
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
/* the description and the name are of the form \\server\share */
2000-06-01 06:35:30 +04:00
slprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s \\ %s " , servername , 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
slprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s " , servername ) ;
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-05-27 00:54:46 +04:00
t = gmtime ( & setup_time ) ;
2000-06-01 06:35:30 +04:00
ntprinter - > info_2 - > setuptime = ( uint32 ) setup_time ; /* FIXME !! */
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 ? */
printer - > unknown16 = 0x0 ;
2000-06-01 06:35:30 +04:00
printer - > change_id = ntprinter - > info_2 - > changeid ; /* ChangeID in milliseconds*/
2000-03-10 20:12:24 +03:00
printer - > unknown18 = 0x0 ;
2000-04-16 11:28:06 +04:00
printer - > status = nt_printq_status ( status . status ) ;
2000-03-10 20:12:24 +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-03-07 21:10:20 +03:00
static BOOL construct_printer_info_1 ( fstring server , 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
2000-02-07 19:17:59 +03:00
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 )
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 ) ) ;
snprintf ( chaine , sizeof ( chaine ) - 1 , " %s%s,%s,%s " , server , ntprinter - > info_2 - > printername ,
ntprinter - > info_2 - > drivername , lp_comment ( snum ) ) ;
}
else {
init_unistr ( & printer - > comment , ntprinter - > info_2 - > comment ) ; /* saved comment. */
snprintf ( chaine , sizeof ( chaine ) - 1 , " %s%s,%s,%s " , server , ntprinter - > info_2 - > printername ,
ntprinter - > info_2 - > drivername , ntprinter - > info_2 - > comment ) ;
}
2000-03-07 21:10:20 +03:00
2000-06-01 06:35:30 +04:00
snprintf ( chaine2 , sizeof ( chaine ) - 1 , " %s%s " , server , 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
static DEVICEMODE * construct_dev_mode ( int snum , char * servername )
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 ) ;
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
goto fail ;
if ( printer - > info_2 - > devmode )
ntdevmode = dup_nt_devicemode ( printer - > info_2 - > devmode ) ;
2000-07-12 18:10:40 +04:00
#if 0 /* JFMTEST */
2000-06-01 06:35:30 +04:00
else
2000-06-27 02:08:20 +04:00
ntdevmode = construct_nt_devicemode ( printer - > info_2 - > printername ) ;
2000-07-12 18:10:40 +04:00
# endif
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
2000-07-01 13:34:37 +04:00
snprintf ( adevice , sizeof ( adevice ) , " \\ \\ %s \\ %s " , global_myname , 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
2000-06-01 06:35:30 +04:00
snprintf ( aform , sizeof ( aform ) , ntdevmode - > formname ) ;
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-02-07 19:17:59 +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-04-23 12:13:48 +04:00
static BOOL construct_printer_info_2 ( fstring servername , PRINTER_INFO_2 * printer , int snum )
2000-02-07 19:17:59 +03:00
{
pstring chaine ;
2000-03-10 20:12:24 +03:00
pstring chaine2 ;
pstring sl ;
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
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 )
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-03-10 20:12:24 +03:00
snprintf ( chaine , sizeof ( chaine ) - 1 , " %s " , servername ) ;
2000-02-07 19:17:59 +03:00
2000-03-10 20:12:24 +03:00
if ( strlen ( servername ) ! = 0 )
fstrcpy ( sl , " \\ " ) ;
else
fstrcpy ( sl , ' \0 ' ) ;
2000-06-01 06:35:30 +04:00
snprintf ( chaine2 , sizeof ( chaine ) - 1 , " %s%s%s " , servername , sl , ntprinter - > info_2 - > printername ) ;
2000-03-10 20:12:24 +03:00
init_unistr ( & printer - > servername , chaine ) ; /* servername*/
init_unistr ( & printer - > printername , chaine2 ) ; /* printername*/
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-07-12 18:10:40 +04:00
if ( ( printer - > devmode = construct_dev_mode ( snum , servername ) ) = = NULL ) {
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL construct_printer_info_3 ( fstring servername ,
2000-06-03 00:08:28 +04:00
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
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 )
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-06-01 06:35:30 +04:00
printer - > flags = 4 ; /* This is the offset to the SEC_DESC. */
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 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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL enum_all_printers_info_1 ( fstring server , 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 ( ) ;
2000-03-07 21:10:20 +03:00
PRINTER_INFO_1 * printers = NULL ;
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-03-10 20:12:24 +03:00
if ( construct_printer_info_1 ( server , flags , & current_prt , snum ) ) {
2000-04-07 02:48:53 +04:00
if ( ( printers = Realloc ( printers , ( * returned + 1 ) * sizeof ( PRINTER_INFO_1 ) ) ) = = NULL ) {
* returned = 0 ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
2000-03-07 21:10:20 +03:00
DEBUG ( 4 , ( " ReAlloced memory for [%d] PRINTER_INFO_1 \n " , * returned ) ) ;
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 + + )
2000-03-07 21:10:20 +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 ) )
return ERROR_INSUFFICIENT_BUFFER ;
/* fill the buffer with the structures */
for ( i = 0 ; i < * returned ; i + + )
2000-03-07 21:10:20 +03:00
new_smb_io_printer_info_1 ( " " , buffer , & ( printers [ i ] ) , 0 ) ;
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 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
/********************************************************************
2000-03-07 21:10:20 +03:00
enum_all_printers_info_1_local .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL enum_all_printers_info_1_local ( fstring name , 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
fstring temp ;
DEBUG ( 4 , ( " enum_all_printers_info_1_local \n " ) ) ;
2000-02-15 21:07:45 +03:00
2000-03-07 21:10:20 +03:00
fstrcpy ( temp , " \\ \\ " ) ;
fstrcat ( temp , global_myname ) ;
if ( ! strcmp ( name , temp ) ) {
fstrcat ( temp , " \\ " ) ;
2000-03-10 20:12:24 +03:00
return enum_all_printers_info_1 ( temp , PRINTER_ENUM_ICON8 , buffer , offered , needed , returned ) ;
2000-03-07 21:10:20 +03:00
}
else
2000-03-10 20:12:24 +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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL enum_all_printers_info_1_name ( fstring name , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
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-03-07 21:10:20 +03:00
if ( ! strcmp ( name , temp ) ) {
fstrcat ( temp , " \\ " ) ;
2000-03-10 20:12:24 +03:00
return enum_all_printers_info_1 ( temp , PRINTER_ENUM_ICON8 , buffer , offered , needed , returned ) ;
2000-02-07 19:17:59 +03:00
}
2000-03-07 21:10:20 +03:00
else
return ERROR_INVALID_NAME ;
}
/********************************************************************
enum_all_printers_info_1_remote .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL enum_all_printers_info_1_remote ( fstring name , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
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 )
*
* 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
2000-03-07 21:10:20 +03:00
* returned = 1 ;
snprintf ( printername , sizeof ( printername ) - 1 , " Windows NT Remote Printers!! \\ \\ %s " , global_myname ) ;
snprintf ( desc , sizeof ( desc ) - 1 , " %s " , global_myname ) ;
snprintf ( comment , sizeof ( comment ) - 1 , " Logged on Domain " ) ;
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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-15 21:07:45 +03:00
/* fill the buffer with the structures */
2000-03-07 21:10:20 +03:00
new_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 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
2000-03-07 21:10:20 +03:00
/********************************************************************
enum_all_printers_info_1_network .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL enum_all_printers_info_1_network ( fstring name , NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
fstring temp ;
DEBUG ( 4 , ( " enum_all_printers_info_1_network \n " ) ) ;
fstrcpy ( temp , " \\ \\ " ) ;
fstrcat ( temp , global_myname ) ;
fstrcat ( temp , " \\ " ) ;
2000-03-10 20:12:24 +03:00
return enum_all_printers_info_1 ( temp , 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 )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-03-10 20:12:24 +03:00
static BOOL enum_all_printers_info_2 ( fstring servername , 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 ( ) ;
2000-03-10 20:12:24 +03:00
PRINTER_INFO_2 * printers = NULL ;
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
if ( construct_printer_info_2 ( servername , & current_prt , snum ) ) {
2000-04-07 02:48:53 +04:00
if ( ( printers = Realloc ( printers , ( * returned + 1 ) * sizeof ( PRINTER_INFO_2 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
free_sec_desc ( & printers [ i ] . secdesc ) ;
2000-03-29 16:36:44 +04:00
}
safe_free ( printers ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 + + )
2000-03-10 20:12:24 +03:00
new_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 ) ;
free_sec_desc ( & printers [ i ] . secdesc ) ;
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 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
/********************************************************************
* handle enumeration of printers at level 1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 enumprinters_level1 ( uint32 flags , fstring name ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
2000-03-07 21:10:20 +03:00
/* Not all the flags are equals */
if ( flags & PRINTER_ENUM_LOCAL )
return enum_all_printers_info_1_local ( name , buffer , offered , needed , returned ) ;
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 )
return enum_all_printers_info_1_network ( name , buffer , offered , needed , returned ) ;
2000-02-15 21:07:45 +03:00
2000-03-07 21:10:20 +03:00
return NT_STATUS_NO_PROBLEMO ; /* NT4sp5 does that */
2000-02-15 21:07:45 +03:00
}
/********************************************************************
* handle enumeration of printers at level 2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 enumprinters_level2 ( uint32 flags , fstring servername ,
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-03-13 14:09:20 +03:00
if ( ! strcmp ( servername , temp ) )
2000-03-10 20:12:24 +03:00
return enum_all_printers_info_2 ( temp , buffer , offered , needed , returned ) ;
else
return enum_all_printers_info_2 ( " " , buffer , offered , needed , returned ) ;
}
if ( flags & PRINTER_ENUM_NAME ) {
2000-03-13 14:09:20 +03:00
if ( ! strcmp ( servername , temp ) )
2000-03-10 20:12:24 +03:00
return enum_all_printers_info_2 ( temp , buffer , offered , needed , returned ) ;
else
return ERROR_INVALID_NAME ;
}
if ( flags & PRINTER_ENUM_REMOTE )
return ERROR_INVALID_LEVEL ;
return NT_STATUS_NO_PROBLEMO ;
2000-02-15 21:07:45 +03:00
}
/********************************************************************
* handle enumeration of printers at level 5
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 enumprinters_level5 ( uint32 flags , fstring servername ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* api_spoolss_enumprinters
*
* called from api_spoolss_enumprinters ( see this to understand )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-15 21:07:45 +03:00
uint32 _spoolss_enumprinters ( uint32 flags , const UNISTR2 * servername , uint32 level ,
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
fstring name ;
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 ;
/*
* Level 1 :
* flags = = PRINTER_ENUM_NAME
* if name = = " " then enumerates all printers
* if name ! = " " then enumerate the printer
* flags = = PRINTER_ENUM_REMOTE
* name is NULL , enumerate printers
* Level 2 : name ! = " " enumerates printers , name can ' t be NULL
* Level 3 : doesn ' t exist
* Level 4 : does a local registry lookup
* Level 5 : same as Level 2
*/
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 ) ;
break ;
case 2 :
return enumprinters_level2 ( flags , name , buffer , offered , needed , returned ) ;
break ;
case 5 :
return enumprinters_level5 ( flags , name , buffer , offered , needed , returned ) ;
break ;
case 3 :
case 4 :
default :
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-15 21:07:45 +03:00
break ;
}
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-23 18:25:36 +04:00
static uint32 getprinter_level_0 ( fstring servername , 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
2000-03-10 20:12:24 +03:00
2000-02-21 04:58:13 +03:00
construct_printer_info_0 ( printer , snum , servername ) ;
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
new_smb_io_printer_info_0 ( " " , buffer , printer , 0 ) ;
/* clear memory */
safe_free ( printer ) ;
if ( * needed > offered ) {
return ERROR_INSUFFICIENT_BUFFER ;
2000-02-07 19:17:59 +03:00
}
2000-02-21 04:58:13 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-23 18:25:36 +04:00
static uint32 getprinter_level_1 ( fstring servername , 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
2000-03-07 21:10:20 +03:00
construct_printer_info_1 ( servername , 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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_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 */
new_smb_io_printer_info_1 ( " " , buffer , printer , 0 ) ;
/* clear memory */
safe_free ( printer ) ;
if ( * needed > offered ) {
return ERROR_INSUFFICIENT_BUFFER ;
2000-02-07 19:17:59 +03:00
}
2000-02-21 04:58:13 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
2000-02-07 19:17:59 +03:00
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-23 18:25:36 +04:00
static uint32 getprinter_level_2 ( fstring servername , int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
2000-02-21 04:58:13 +03:00
{
PRINTER_INFO_2 * printer = NULL ;
2000-03-10 20:12:24 +03:00
fstring temp ;
2000-02-21 04:58:13 +03:00
2000-04-07 02:48:53 +04:00
if ( ( printer = ( PRINTER_INFO_2 * ) malloc ( sizeof ( PRINTER_INFO_2 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
2000-03-10 20:12:24 +03:00
fstrcpy ( temp , " \\ \\ " ) ;
fstrcat ( temp , servername ) ;
construct_printer_info_2 ( temp , 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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-10 20:12:24 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2000-06-03 01:16:39 +04:00
if ( ! new_smb_io_printer_info_2 ( " " , buffer , printer , 0 ) ) {
free_printer_info_2 ( printer ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
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 ) {
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
2000-05-27 05:26:34 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 getprinter_level_3 ( fstring servername , int snum , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
PRINTER_INFO_3 * printer = NULL ;
fstring temp ;
fstrcpy ( temp , " \\ \\ " ) ;
fstrcat ( temp , servername ) ;
2000-06-03 00:08:28 +04:00
if ( ! construct_printer_info_3 ( temp , & printer , snum ) )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
2000-05-27 05:26:34 +04:00
return ERROR_INSUFFICIENT_BUFFER ;
}
/* fill the buffer with the structures */
new_smb_io_printer_info_3 ( " " , buffer , printer , 0 ) ;
/* 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 ) {
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_getprinter ( POLICY_HND * handle , uint32 level ,
NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
int snum ;
2000-04-23 18:25:36 +04:00
fstring servername ;
2000-02-21 04:58:13 +03:00
* needed = 0 ;
pstrcpy ( servername , global_myname ) ;
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-21 04:58:13 +03:00
switch ( level ) {
case 0 :
return getprinter_level_0 ( servername , snum , buffer , offered , needed ) ;
case 1 :
return getprinter_level_1 ( servername , snum , buffer , offered , needed ) ;
case 2 :
return getprinter_level_2 ( servername , snum , buffer , offered , needed ) ;
2000-05-27 05:26:34 +04:00
case 3 :
return getprinter_level_3 ( servername , snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
default :
2000-03-10 20:12:24 +03:00
return ERROR_INVALID_LEVEL ;
2000-02-21 04:58:13 +03:00
break ;
}
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 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 ) ;
2000-07-25 17:15:16 +04:00
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
return ERROR_INVALID_PRINTER_NAME ;
if ( get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ! = 0 )
return ERROR_UNKNOWN_PRINTER_DRIVER ;
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
return NT_STATUS_NO_PROBLEMO ;
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
{
pstring temp_driverpath ;
pstring temp_datafile ;
pstring temp_configfile ;
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
snprintf ( temp_driverpath , sizeof ( temp_driverpath ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > driverpath ) ;
init_unistr ( & info - > driverpath , temp_driverpath ) ;
snprintf ( temp_datafile , sizeof ( temp_datafile ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > datafile ) ;
init_unistr ( & info - > datafile , temp_datafile ) ;
2000-02-07 19:17:59 +03:00
2000-07-25 17:15:16 +04:00
snprintf ( temp_configfile , sizeof ( temp_configfile ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > configfile ) ;
init_unistr ( & info - > configfile , temp_configfile ) ;
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 uint32 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 ) ;
2000-07-25 17:15:16 +04:00
if ( ! get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 )
return ERROR_INVALID_PRINTER_NAME ;
if ( ! get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ! = 0 )
return ERROR_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
return NT_STATUS_NO_PROBLEMO ;
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 ;
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 ;
2000-07-25 17:15:16 +04:00
snprintf ( 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 ) ) ) ;
2000-04-07 02:48:53 +04:00
if ( ( * uni_array = Realloc ( * uni_array , ( j + strlen ( line ) + 2 ) * sizeof ( uint16 ) ) ) = = NULL ) {
DEBUG ( 0 , ( " init_unistr_array: Realloc error \n " ) ) ;
return ;
}
2000-06-22 05:39:17 +04:00
j + = ( dos_PutUniCode ( ( char * ) ( * uni_array + j ) , line , sizeof ( uint16 ) * strlen ( line ) , True ) / 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
{
pstring temp_driverpath ;
pstring temp_datafile ;
pstring temp_configfile ;
pstring temp_helpfile ;
2000-05-23 00:04:50 +04:00
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 ) ;
snprintf ( temp_driverpath , sizeof ( temp_driverpath ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > driverpath ) ;
2000-06-27 02:08:20 +04:00
init_unistr ( & info - > driverpath , temp_driverpath ) ;
2000-07-25 17:15:16 +04:00
snprintf ( temp_datafile , sizeof ( temp_datafile ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > datafile ) ;
2000-06-27 02:08:20 +04:00
init_unistr ( & info - > datafile , temp_datafile ) ;
2000-07-25 17:15:16 +04:00
snprintf ( temp_configfile , sizeof ( temp_configfile ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > configfile ) ;
2000-06-27 02:08:20 +04:00
init_unistr ( & info - > configfile , temp_configfile ) ;
2000-07-25 17:15:16 +04:00
snprintf ( temp_helpfile , sizeof ( temp_helpfile ) - 1 , " \\ \\ %s%s " , servername , driver . info_3 - > helpfile ) ;
2000-06-27 02:08:20 +04:00
init_unistr ( & info - > helpfile , temp_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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
2000-07-25 17:15:16 +04:00
uint32 status = 0 ;
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 ) ) ;
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %d \n " , status ) ) ;
if ( status ! = 0 )
return ERROR_INVALID_PRINTER_NAME ;
status = get_a_printer_driver ( & driver , 3 , printer - > info_2 - > drivername , architecture , version ) ;
DEBUG ( 8 , ( " construct_printer_driver_info_3: status: %d \n " , status ) ) ;
2000-07-26 02:35:57 +04:00
if ( status ! = 0 ) {
free_a_printer ( & printer , 2 ) ;
2000-07-25 17:15:16 +04:00
return ERROR_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
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03: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-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
2000-07-25 17:15:16 +04:00
uint32 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
if ( status ! = NT_STATUS_NO_PROBLEMO ) {
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
new_smb_io_printer_driver_info_1 ( " " , buffer , info , 0 ) ;
/* clear memory */
safe_free ( info ) ;
2000-03-13 14:09:20 +03:00
if ( * needed > offered )
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
2000-07-25 17:15:16 +04:00
uint32 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
if ( status ! = NT_STATUS_NO_PROBLEMO ) {
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
new_smb_io_printer_driver_info_2 ( " " , buffer , info , 0 ) ;
/* clear memory */
safe_free ( info ) ;
2000-03-13 14:09:20 +03:00
if ( * needed > offered )
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
2000-07-25 17:15:16 +04:00
uint32 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 ) ;
if ( status ! = NT_STATUS_NO_PROBLEMO ) {
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
/* fill the buffer with the structures */
2000-05-24 10:34:47 +04:00
new_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 )
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_getprinterdriver2 ( POLICY_HND * handle , const UNISTR2 * uni_arch , uint32 level ,
2000-03-13 14:09:20 +03:00
uint32 clientmajorversion , uint32 clientminorversion ,
2000-02-21 04:58:13 +03:00
NEW_BUFFER * buffer , uint32 offered ,
2000-03-13 14:09:20 +03:00
uint32 * needed , uint32 * servermajorversion , uint32 * serverminorversion )
2000-02-07 19:17:59 +03:00
{
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
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
2000-02-21 04:58:13 +03:00
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
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
break ;
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
break ;
case 3 :
2000-07-25 17:15:16 +04:00
return getprinterdriver2_level3 ( servername , architecture , clientmajorversion , snum , buffer , offered , needed ) ;
2000-02-21 04:58:13 +03:00
break ;
default :
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-21 04:58:13 +03:00
break ;
2000-02-07 19:17:59 +03:00
}
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_startpageprinter ( POLICY_HND * handle )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( OPEN_HANDLE ( Printer ) ) {
2000-02-25 02:01:24 +03:00
Printer - > page_started = True ;
2000-02-07 19:17:59 +03:00
return 0x0 ;
}
2000-02-25 02:01:24 +03:00
DEBUG ( 3 , ( " Error in startpageprinter printer handle \n " ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_endpageprinter ( POLICY_HND * handle )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_endpageprinter: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_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
2000-02-25 02:01:24 +03:00
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_startdocprinter ( POLICY_HND * handle , uint32 level ,
2000-07-06 10:53:47 +04:00
pipes_struct * p , DOC_INFO * docinfo ,
uint32 * 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 ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-07-06 10:53:47 +04:00
struct current_user user ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_startdocprinter: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2000-07-06 10:53:47 +04:00
if ( p - > ntlmssp_auth_validated ) {
memcpy ( & user , & p - > pipe_user , sizeof ( user ) ) ;
} else {
extern struct current_user current_user ;
memcpy ( & user , & current_user , sizeof ( user ) ) ;
}
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 ;
2000-03-07 12:06:03 +03:00
return ERROR_INVALID_DATATYPE ;
2000-02-07 19:17:59 +03:00
}
}
/* get the share number of the printer */
2000-08-24 03:05:49 +04:00
if ( ! get_printer_snum ( handle , & snum ) ) {
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
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
return 0x0 ;
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_enddocprinter ( POLICY_HND * handle )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_enddocprinter: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2000-02-25 02:01:24 +03:00
Printer - > document_started = False ;
2000-04-16 10:20:43 +04:00
print_job_end ( Printer - > jobid ) ;
/* error codes unhandled so far ... */
2000-02-07 19:17:59 +03:00
return 0x0 ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_writeprinter ( POLICY_HND * handle ,
2000-02-07 19:17:59 +03:00
uint32 buffer_size ,
2000-07-22 04:48:29 +04:00
uint8 * buffer ,
2000-02-07 19:17:59 +03:00
uint32 * buffer_written )
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_writeprinter: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2000-07-10 10:41:04 +04:00
( * buffer_written ) = print_job_write ( Printer - > jobid , ( char * ) buffer ,
buffer_size ) ;
2000-02-07 19:17:59 +03:00
return 0x0 ;
}
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static uint32 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 ;
2000-02-07 19:17:59 +03:00
int snum ;
2000-08-30 04:45:59 +04:00
int errcode = 0 ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-07-06 10:53:47 +04:00
if ( p - > ntlmssp_auth_validated ) {
memcpy ( & user , & p - > pipe_user , sizeof ( user ) ) ;
} else {
extern struct current_user current_user ;
memcpy ( & user , & current_user , sizeof ( user ) ) ;
}
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " control_printer: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-07-07 03:31:46 +04:00
}
2000-02-07 19:17:59 +03:00
2000-02-27 01:22:24 +03:00
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_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-04-16 10:20:43 +04:00
return 0 ;
}
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-04-16 10:20:43 +04:00
return 0 ;
}
break ;
case PRINTER_CONTROL_PURGE :
2000-08-30 04:45:59 +04:00
if ( print_queue_purge ( & user , snum , & errcode ) ) {
2000-04-16 10:20:43 +04:00
return 0 ;
}
break ;
2000-02-07 19:17:59 +03:00
}
2000-08-30 04:45:59 +04:00
if ( errcode )
return ( uint32 ) errcode ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_FUNCTION ;
2000-02-07 19:17:59 +03:00
}
2000-08-30 04:45:59 +04:00
/********************************************************************
* api_spoolss_abortprinter
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_abortprinter ( POLICY_HND * handle , pipes_struct * p )
{
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
static uint32 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-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
2000-05-27 13:53:11 +04:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-08-09 08:19:18 +04:00
if ( ! OPEN_HANDLE ( Printer ) | | ! get_printer_snum ( handle , & snum ) ) {
2000-07-07 03:31:46 +04:00
DEBUG ( 0 , ( " update_printer_sec: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-05-27 13:53:11 +04:00
return ERROR_INVALID_HANDLE ;
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-07-10 09:08:21 +04:00
if ( p - > ntlmssp_auth_validated ) {
memcpy ( & user , & p - > pipe_user , sizeof ( user ) ) ;
} else {
extern struct current_user current_user ;
memcpy ( & user , & current_user , sizeof ( user ) ) ;
}
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
information . */
2000-09-01 22:49:26 +04:00
if ( ! print_access_check ( & user , snum , PRINTER_ACCESS_ADMINISTER ) ) {
2000-08-09 11:34:35 +04:00
result = ERROR_ACCESS_DENIED ;
2000-07-17 09:38:26 +04:00
goto done ;
2000-07-17 06:38:43 +04:00
}
2000-07-22 04:48:29 +04:00
result = nt_printing_setsec ( Printer - > dev . handlename , secdesc_ctr ) ;
2000-07-17 09:38:26 +04:00
done :
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL check_printer_ok ( NT_PRINTER_INFO_LEVEL_2 * info , int snum )
{
/*
* Ensure that this printer is shared under the correct name
* as this is what Samba insists upon .
*/
2000-07-25 05:50:53 +04:00
if ( ! ( info - > attributes & PRINTER_ATTRIBUTE_SHARED ) ) {
DEBUG ( 10 , ( " check_printer_ok: SHARED check failed (%x). \n " , ( unsigned int ) info - > attributes ) ) ;
2000-07-22 04:48:29 +04:00
return False ;
2000-07-25 05:50:53 +04:00
}
2000-07-22 04:48:29 +04:00
2000-07-25 05:50:53 +04:00
if ( ! ( info - > attributes & PRINTER_ATTRIBUTE_RAW_ONLY ) ) {
/* NT forgets to set the raw attribute but sends the correct type. */
if ( strequal ( info - > datatype , " RAW " ) )
info - > attributes | = PRINTER_ATTRIBUTE_RAW_ONLY ;
else {
DEBUG ( 10 , ( " check_printer_ok: RAW check failed (%x). \n " , ( unsigned int ) info - > attributes ) ) ;
return False ;
}
}
2000-07-22 04:48:29 +04:00
2000-07-25 05:50:53 +04:00
if ( ! strequal ( info - > sharename , lp_servicename ( snum ) ) ) {
DEBUG ( 10 , ( " check_printer_ok: NAME check failed (%s) (%s). \n " , info - > sharename , lp_servicename ( snum ) ) ) ;
2000-07-22 04:48:29 +04:00
return False ;
2000-07-25 05:50:53 +04: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 )
{
pid_t local_pid = sys_getpid ( ) ;
char * cmd = lp_addprinter_cmd ( ) ;
char * path ;
char * * qlines ;
pstring tmp_file ;
pstring command ;
pstring driverlocation ;
int numlines ;
int ret ;
if ( * lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) )
path = lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) ;
else
path = tmpdir ( ) ;
/* 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 ) ) ;
slprintf ( tmp_file , sizeof ( tmp_file ) , " %s/smbcmd.%d " , path , local_pid ) ;
slprintf ( command , sizeof ( command ) , " %s \" %s \" \" %s \" \" %s \" \" %s \" \" %s \" \" %s \" " ,
cmd , printer - > info_2 - > printername , printer - > info_2 - > sharename ,
printer - > info_2 - > portname , printer - > info_2 - > drivername ,
printer - > info_2 - > location , driverlocation ) ;
unlink ( tmp_file ) ;
DEBUG ( 10 , ( " Running [%s > %s] \n " , command , tmp_file ) ) ;
ret = smbrun ( command , tmp_file , False ) ;
DEBUGADD ( 10 , ( " returned [%d] \n " , ret ) ) ;
if ( ret ! = 0 ) {
unlink ( tmp_file ) ;
return False ;
}
numlines = 0 ;
qlines = file_lines_load ( tmp_file , & numlines ) ;
DEBUGADD ( 10 , ( " Lines returned = [%d] \n " , numlines ) ) ;
DEBUGADD ( 10 , ( " Unlinking port file [%s] \n " , tmp_file ) ) ;
unlink ( tmp_file ) ;
if ( numlines ) {
// Set the portname to what the script says the portname should be
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
// Send SIGHUP to process group... is there a better way?
kill ( 0 , SIGHUP ) ;
add_all_printers ( ) ;
}
file_lines_free ( qlines ) ;
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
2000-07-22 04:48:29 +04:00
static uint32 update_printer ( 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-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( 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 " ) ) ;
2000-07-10 09:08:21 +04:00
result = NT_STATUS_NO_PROBLEMO ;
/* Check calling user has permission to update printer description */
2000-07-12 18:10:40 +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 " ) ) ;
2000-07-10 09:08:21 +04:00
result = ERROR_INVALID_LEVEL ;
goto done ;
2000-02-07 19:17:59 +03:00
}
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
2000-07-10 09:08:21 +04:00
result = ERROR_INVALID_HANDLE ;
goto done ;
2000-07-07 03:31:46 +04:00
}
2000-02-25 02:01:24 +03:00
2000-07-10 09:08:21 +04:00
if ( ! get_printer_snum ( handle , & snum ) ) {
result = ERROR_INVALID_HANDLE ;
goto done ;
}
2000-08-09 08:19:18 +04:00
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
DEBUG ( 3 , ( " printer property change denied by security "
" descriptor \n " ) ) ;
2000-08-09 11:34:35 +04:00
result = ERROR_ACCESS_DENIED ;
2000-08-09 08:19:18 +04:00
goto done ;
}
2000-02-25 02:01:24 +03:00
2000-07-10 09:08:21 +04:00
if ( get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ! = 0 ) {
result = ERROR_INVALID_HANDLE ;
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-02-07 19:17:59 +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
/*
* Ensure printer - > info_2 - > devmode is a valid pointer
* as we will be overwriting it in convert_devicemode ( ) .
*/
2000-02-07 19:17:59 +03:00
2000-06-27 02:08:20 +04:00
if ( printer - > info_2 - > devmode = = NULL )
printer - > info_2 - > devmode = construct_nt_devicemode ( printer - > info_2 - > printername ) ;
2000-02-07 19:17:59 +03:00
DEBUGADD ( 8 , ( " Converting the devicemode struct \n " ) ) ;
2000-06-27 02:08:20 +04:00
convert_devicemode ( devmode , printer - > info_2 - > devmode ) ;
2000-06-01 06:35:30 +04:00
} else {
if ( printer - > info_2 - > devmode ! = NULL )
free_nt_devicemode ( & printer - > info_2 - > devmode ) ;
printer - > info_2 - > devmode = NULL ;
2000-02-07 19:17:59 +03:00
}
2000-07-22 04:48:29 +04:00
/*
* Do sanity check on the requested changes for Samba .
*/
if ( ! check_printer_ok ( printer - > info_2 , snum ) ) {
2000-08-01 00:41:51 +04:00
result = ERROR_INVALID_PARAMETER ;
2000-07-22 04:48:29 +04:00
goto done ;
}
2000-08-11 03:41:16 +04:00
if ( * lp_addprinter_cmd ( ) )
if ( ! add_printer_hook ( printer ) ) {
result = ERROR_ACCESS_DENIED ;
goto done ;
}
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 !!! */
2000-07-10 09:08:21 +04:00
result = ERROR_ACCESS_DENIED ;
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-07-10 09:08:21 +04:00
return result ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_setprinter ( POLICY_HND * handle , uint32 level ,
2000-02-27 01:22:24 +03:00
const SPOOL_PRINTER_INFO_LEVEL * info ,
2000-06-01 06:35:30 +04:00
DEVMODE_CTR devmode_ctr ,
SEC_DESC_BUF * secdesc_ctr ,
2000-07-06 10:53:47 +04:00
uint32 command , pipes_struct * p )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_setprinter: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_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
break ;
case 2 :
2000-02-27 01:22:24 +03:00
return update_printer ( handle , level , info , devmode_ctr . devmode ) ;
2000-02-25 02:01:24 +03:00
break ;
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-05-27 13:53:11 +04:00
break ;
2000-03-13 22:34:04 +03:00
default :
return ERROR_INVALID_LEVEL ;
break ;
2000-02-07 19:17:59 +03:00
}
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_fcpn ( POLICY_HND * handle )
2000-02-07 19:17:59 +03:00
{
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-24 19:27:06 +03:00
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_fcpn: Invalid handle (%s) \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-07-07 03:31:46 +04:00
}
2000-02-24 19:27:06 +03: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 )
safe_free ( Printer - > notify . option - > ctr . type ) ;
2000-06-06 00:55:57 +04:00
safe_free ( Printer - > notify . option ) ;
2000-02-25 02:01:24 +03:00
Printer - > notify . option = NULL ;
2000-02-24 19:27:06 +03:00
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_addjob ( POLICY_HND * handle , uint32 level ,
2000-08-28 08:42:31 +04:00
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed )
{
* needed = 0 ;
return ERROR_INVALID_PARAMETER ; /* this is what a NT server
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 ;
time_t unixdate = time ( NULL ) ;
t = gmtime ( & unixdate ) ;
snprintf ( temp_name , sizeof ( temp_name ) , " \\ \\ %s " , global_myname ) ;
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 ,
int position , int snum )
{
pstring temp_name ;
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * ntprinter = NULL ;
2000-02-07 19:17:59 +03:00
pstring chaine ;
struct tm * t ;
time_t unixdate = time ( NULL ) ;
if ( get_a_printer ( & ntprinter , 2 , lp_servicename ( snum ) ) ! = 0 )
2000-04-06 20:23:04 +04:00
return False ;
2000-02-07 19:17:59 +03:00
t = gmtime ( & unixdate ) ;
snprintf ( temp_name , sizeof ( temp_name ) , " \\ \\ %s " , global_myname ) ;
job_info - > jobid = queue - > job ;
2000-06-01 06:35:30 +04:00
snprintf ( chaine , sizeof ( chaine ) - 1 , " \\ \\ %s \\ %s " , global_myname , ntprinter - > info_2 - > printername ) ;
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 , " " ) ;
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-06-01 06:35:30 +04:00
if ( ( job_info - > devmode = construct_dev_mode ( snum , global_myname ) ) = = NULL ) {
free_a_printer ( & ntprinter , 2 ) ;
2000-04-07 02:48:53 +04:00
return False ;
}
2000-06-01 06:35:30 +04:00
free_a_printer ( & ntprinter , 2 ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-15 21:07:45 +03:00
static uint32 enumjobs_level1 ( print_queue_struct * queue , int snum ,
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
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 ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 + + )
2000-07-18 23:25:32 +04:00
new_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 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-15 21:07:45 +03:00
static uint32 enumjobs_level2 ( print_queue_struct * queue , int snum ,
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
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 ) {
safe_free ( queue ) ;
* returned = 0 ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
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_2 ( & ( 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_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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 + + )
2000-07-18 23:25:32 +04:00
new_smb_io_job_info_2 ( " " , buffer , & info [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
/* clear memory */
safe_free ( info ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
Enumjobs .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_enumjobs ( POLICY_HND * handle , uint32 firstjob , uint32 numofjobs , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
int snum ;
print_queue_struct * queue = NULL ;
print_status_struct prt_status ;
DEBUG ( 4 , ( " _spoolss_enumjobs \n " ) ) ;
ZERO_STRUCT ( prt_status ) ;
* needed = 0 ;
* returned = 0 ;
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_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 ) ) ;
switch ( level ) {
case 1 :
return enumjobs_level1 ( queue , snum , buffer , offered , needed , returned ) ;
break ;
case 2 :
return enumjobs_level2 ( queue , snum , buffer , offered , needed , returned ) ;
break ;
default :
2000-04-06 20:23:04 +04:00
safe_free ( queue ) ;
* returned = 0 ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-15 21:07:45 +03:00
break ;
}
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_schedulejob ( POLICY_HND * handle , uint32 jobid )
2000-02-15 21:07:45 +03:00
{
return 0x0 ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_setjob ( POLICY_HND * handle ,
2000-02-15 21:07:45 +03:00
uint32 jobid ,
2000-02-07 19:17:59 +03:00
uint32 level ,
2000-07-06 10:53:47 +04:00
pipes_struct * p ,
2000-02-07 19:17:59 +03:00
JOB_INFO * ctr ,
uint32 command )
{
2000-07-06 10:53:47 +04:00
struct current_user user ;
2000-02-07 19:17:59 +03:00
int snum ;
print_status_struct prt_status ;
2000-02-24 19:27:06 +03:00
memset ( & prt_status , 0 , sizeof ( prt_status ) ) ;
2000-02-07 19:17:59 +03:00
2000-04-05 14:05:32 +04:00
if ( ! get_printer_snum ( handle , & snum ) ) {
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
2000-04-16 10:20:43 +04:00
if ( ! print_job_exists ( jobid ) ) {
return ERROR_INVALID_PRINTER_NAME ;
2000-02-07 19:17:59 +03:00
}
2000-07-06 10:53:47 +04:00
if ( p - > ntlmssp_auth_validated ) {
memcpy ( & user , & p - > pipe_user , sizeof ( user ) ) ;
} else {
extern struct current_user current_user ;
memcpy ( & user , & current_user , sizeof ( user ) ) ;
}
2000-04-16 10:20:43 +04:00
switch ( command ) {
case JOB_CONTROL_CANCEL :
case JOB_CONTROL_DELETE :
2000-07-06 10:53:47 +04:00
if ( print_job_delete ( & user , jobid ) ) return 0x0 ;
2000-04-16 10:20:43 +04:00
break ;
case JOB_CONTROL_PAUSE :
2000-07-06 10:53:47 +04:00
if ( print_job_pause ( & user , jobid ) ) return 0x0 ;
2000-04-16 10:20:43 +04:00
break ;
case JOB_CONTROL_RESUME :
2000-07-06 10:53:47 +04:00
if ( print_job_resume ( & user , jobid ) ) return 0x0 ;
2000-04-16 10:20:43 +04:00
break ;
default :
return ERROR_INVALID_LEVEL ;
2000-02-07 19:17:59 +03:00
}
2000-04-16 10:20:43 +04:00
return ERROR_INVALID_HANDLE ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
DRIVER_INFO_1 * 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
if ( ndrivers ! = 0 ) {
if ( ( driver_info_1 = ( DRIVER_INFO_1 * ) Realloc ( driver_info_1 , ( * returned + ndrivers ) * sizeof ( DRIVER_INFO_1 ) ) ) = = NULL ) {
safe_free ( list ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
}
for ( i = 0 ; i < ndrivers ; i + + ) {
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
get_a_printer_driver ( & driver , 3 , list [ i ] , architecture , version ) ;
fill_printer_driver_info_1 ( & ( driver_info_1 [ * returned + i ] ) , driver , servername , architecture ) ;
}
* 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 ) ) ;
* needed + = spoolss_size_printer_driver_info_1 ( & ( driver_info_1 [ i ] ) ) ;
}
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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2000-02-07 19:17:59 +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 ) ) ;
2000-02-15 21:07:45 +03:00
new_smb_io_printer_driver_info_1 ( " " , buffer , & ( driver_info_1 [ i ] ) , 0 ) ;
}
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 ;
2000-02-15 21:07:45 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2000-02-15 21:07:45 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
Enumerates all printer drivers at level 2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
2000-02-15 21:07:45 +03:00
DRIVER_INFO_2 * 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
if ( ndrivers ! = 0 ) {
if ( ( driver_info_2 = ( DRIVER_INFO_2 * ) Realloc ( driver_info_2 , ( * returned + ndrivers ) * sizeof ( DRIVER_INFO_2 ) ) ) = = NULL ) {
safe_free ( list ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
2000-05-29 03:00:23 +04:00
}
2000-07-25 17:15:16 +04:00
for ( i = 0 ; i < ndrivers ; i + + ) {
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
get_a_printer_driver ( & driver , 3 , list [ i ] , architecture , version ) ;
fill_printer_driver_info_2 ( & ( driver_info_2 [ * returned + i ] ) , driver , servername ) ;
}
* 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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 ) ) ;
2000-02-15 21:07:45 +03:00
new_smb_io_printer_driver_info_2 ( " " , buffer , & ( driver_info_2 [ i ] ) , 0 ) ;
}
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 ;
2000-02-15 21:07:45 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-16 19:23:38 +03:00
}
2000-02-15 21:07:45 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
Enumerates all printer drivers at level 3.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
static uint32 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 ;
DRIVER_INFO_3 * 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 )
return ERROR_NOT_ENOUGH_MEMORY ;
if ( ndrivers ! = 0 ) {
if ( ( driver_info_3 = ( DRIVER_INFO_3 * ) Realloc ( driver_info_3 , ( * returned + ndrivers ) * sizeof ( DRIVER_INFO_3 ) ) ) = = NULL ) {
safe_free ( list ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
}
for ( i = 0 ; i < ndrivers ; i + + ) {
DEBUGADD ( 5 , ( " \t driver: [%s] \n " , list [ i ] ) ) ;
ZERO_STRUCT ( driver ) ;
get_a_printer_driver ( & driver , 3 , list [ i ] , architecture , version ) ;
fill_printer_driver_info_3 ( & ( driver_info_3 [ * returned + i ] ) , driver , servername ) ;
}
* 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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 ) ) ;
2000-06-30 05:07:26 +04:00
new_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 ;
2000-02-15 21:07:45 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-29 16:36:44 +04:00
}
2000-02-15 21:07:45 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
Enumerates all printer drivers .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_enumprinterdrivers ( UNISTR2 * name , UNISTR2 * environment , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
2000-05-27 07:12:06 +04:00
fstring * list = NULL ;
2000-02-15 21:07:45 +03:00
fstring servername ;
fstring architecture ;
DEBUG ( 4 , ( " _spoolss_enumprinterdrivers \n " ) ) ;
fstrcpy ( servername , global_myname ) ;
* needed = 0 ;
* returned = 0 ;
unistr2_to_ascii ( architecture , environment , sizeof ( architecture ) - 1 ) ;
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
break ;
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
break ;
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
break ;
default :
2000-07-12 18:10:40 +04:00
* returned = 0 ;
2000-07-25 17:15:16 +04:00
safe_free ( list ) ;
2000-03-29 16:36:44 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-15 21:07:45 +03:00
break ;
}
2000-02-07 19:17:59 +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 ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _new_spoolss_enumforms ( POLICY_HND * handle , uint32 level ,
2000-02-07 19:17:59 +03:00
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * numofforms )
{
nt_forms_struct * list = NULL ;
FORM_1 * forms_1 ;
int buffer_size = 0 ;
int i ;
DEBUG ( 4 , ( " _new_spoolss_enumforms \n " ) ) ;
DEBUGADD ( 5 , ( " Offered buffer size [%d] \n " , offered ) ) ;
DEBUGADD ( 5 , ( " Info level [%d] \n " , level ) ) ;
* numofforms = get_ntforms ( & list ) ;
DEBUGADD ( 5 , ( " Number of forms [%d] \n " , * numofforms ) ) ;
2000-05-29 05:09:14 +04:00
if ( * numofforms = = 0 ) return ERROR_NO_MORE_ITEMS ;
2000-02-07 19:17:59 +03:00
switch ( level ) {
case 1 :
2000-05-29 05:09:14 +04:00
if ( ( forms_1 = ( FORM_1 * ) malloc ( * numofforms * sizeof ( FORM_1 ) ) ) = = NULL ) {
2000-04-07 02:48:53 +04:00
* numofforms = 0 ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
2000-02-07 19:17:59 +03:00
/* construct the list of form structures */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * numofforms ; i + + ) {
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " Filling form number [%d] \n " , i ) ) ;
2000-09-06 00:56:09 +04:00
fill_form_1 ( & forms_1 [ i ] , & list [ i ] ) ;
2000-02-07 19:17:59 +03:00
}
2000-03-29 16:36:44 +04:00
safe_free ( list ) ;
2000-02-07 19:17:59 +03:00
/* check the required size. */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; 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 ;
2000-03-13 14:09:20 +03:00
if ( ! alloc_buffer_size ( buffer , buffer_size ) ) {
2000-03-29 16:36:44 +04:00
safe_free ( forms_1 ) ;
2000-02-07 19:17:59 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-07 19:17:59 +03:00
/* fill the buffer with the form structures */
2000-03-29 16:36:44 +04:00
for ( i = 0 ; i < * numofforms ; i + + ) {
2000-02-07 19:17:59 +03:00
DEBUGADD ( 6 , ( " adding form [%d] to buffer \n " , i ) ) ;
2000-07-07 03:31:46 +04:00
new_smb_io_form_1 ( " " , buffer , & forms_1 [ i ] , 0 ) ;
2000-02-07 19:17:59 +03:00
}
2000-03-29 16:36:44 +04:00
safe_free ( forms_1 ) ;
2000-02-07 19:17:59 +03:00
2000-03-29 16:36:44 +04:00
if ( * needed > offered ) {
* numofforms = 0 ;
2000-02-07 19:17:59 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-29 16:36:44 +04:00
}
2000-02-07 19:17:59 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
default :
safe_free ( list ) ;
2000-03-13 14:09:20 +03:00
return ERROR_INVALID_LEVEL ;
2000-02-07 19:17:59 +03:00
}
}
2000-09-06 00:56:09 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_getform ( POLICY_HND * handle , uint32 level , UNISTR2 * uni_formname , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
nt_forms_struct * list = NULL ;
FORM_1 form_1 ;
fstring form_name ;
int buffer_size = 0 ;
int numofforms , i ;
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 ) ) ;
numofforms = get_ntforms ( & list ) ;
DEBUGADD ( 5 , ( " Number of forms [%d] \n " , numofforms ) ) ;
if ( numofforms = = 0 )
return ERROR_NO_MORE_ITEMS ;
switch ( level ) {
case 1 :
/* Check if the requested name is in the list of form structures */
for ( i = 0 ; i < numofforms ; i + + ) {
DEBUG ( 4 , ( " _spoolss_getform: checking form %s (want %s) \n " , list [ i ] . name , form_name ) ) ;
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 ) ;
/* check the required size. */
* needed = spoolss_size_form_1 ( & form_1 ) ;
if ( ! alloc_buffer_size ( buffer , buffer_size ) ) {
return ERROR_INSUFFICIENT_BUFFER ;
}
if ( * needed > offered ) {
return ERROR_INSUFFICIENT_BUFFER ;
}
/* fill the buffer with the form structures */
DEBUGADD ( 6 , ( " adding form %s [%d] to buffer \n " , form_name , i ) ) ;
new_smb_io_form_1 ( " " , buffer , & form_1 , 0 ) ;
return NT_STATUS_NO_PROBLEMO ;
default :
safe_free ( list ) ;
return ERROR_INVALID_LEVEL ;
}
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-15 21:07:45 +03:00
static uint32 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 ( ) ) {
pid_t local_pid = sys_getpid ( ) ;
char * cmd = lp_enumports_cmd ( ) ;
char * path ;
char * * qlines ;
pstring tmp_file ;
pstring command ;
int numlines ;
int ret ;
if ( * lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) )
path = lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) ;
else
path = tmpdir ( ) ;
slprintf ( tmp_file , sizeof ( tmp_file ) , " %s/smbcmd.%d " , path , local_pid ) ;
slprintf ( command , sizeof ( command ) , " %s \" %d \" " , cmd , 1 ) ;
unlink ( tmp_file ) ;
DEBUG ( 10 , ( " Running [%s > %s] \n " , command , tmp_file ) ) ;
ret = smbrun ( command , tmp_file , False ) ;
DEBUG ( 10 , ( " Returned [%d] \n " , ret ) ) ;
if ( ret ! = 0 ) {
unlink ( tmp_file ) ;
// Is this the best error to return here?
return ERROR_ACCESS_DENIED ;
}
2000-02-07 19:17:59 +03:00
2000-08-01 00:41:51 +04:00
numlines = 0 ;
qlines = file_lines_load ( tmp_file , & numlines ) ;
DEBUGADD ( 10 , ( " Lines returned = [%d] \n " , numlines ) ) ;
DEBUGADD ( 10 , ( " Unlinking port file [%s] \n " , tmp_file ) ) ;
unlink ( tmp_file ) ;
if ( numlines ) {
if ( ( ports = ( PORT_INFO_1 * ) malloc ( numlines * sizeof ( PORT_INFO_1 ) ) ) = = NULL ) {
DEBUG ( 10 , ( " Returning ERROR_NOT_ENOUGH_MEMORY [%x] \n " , ERROR_NOT_ENOUGH_MEMORY ) ) ;
file_lines_free ( qlines ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
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 )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 ) ) ;
2000-06-23 03:59:22 +04:00
new_smb_io_port_1 ( " " , buffer , & ports [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
}
safe_free ( ports ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
2000-02-07 19:17:59 +03:00
}
2000-02-15 21:07:45 +03:00
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
enumports level 2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 03:59:22 +04:00
2000-02-15 21:07:45 +03:00
static uint32 enumports_level_2 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
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 ( ) ) {
pid_t local_pid = sys_getpid ( ) ;
char * cmd = lp_enumports_cmd ( ) ;
char * path ;
char * * qlines ;
pstring tmp_file ;
pstring command ;
int numlines ;
int ret ;
if ( * lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) )
path = lp_pathname ( lp_servicenumber ( PRINTERS_NAME ) ) ;
else
path = tmpdir ( ) ;
slprintf ( tmp_file , sizeof ( tmp_file ) , " %s/smbcmd.%d " , path , local_pid ) ;
slprintf ( command , sizeof ( command ) , " %s \" %d \" " , cmd , 2 ) ;
unlink ( tmp_file ) ;
DEBUG ( 10 , ( " Running [%s > %s] \n " , command , tmp_file ) ) ;
ret = smbrun ( command , tmp_file , False ) ;
DEBUGADD ( 10 , ( " returned [%d] \n " , ret ) ) ;
if ( ret ! = 0 ) {
unlink ( tmp_file ) ;
// Is this the best error to return here?
return ERROR_ACCESS_DENIED ;
}
2000-02-15 21:07:45 +03:00
2000-08-01 00:41:51 +04:00
numlines = 0 ;
qlines = file_lines_load ( tmp_file , & numlines ) ;
DEBUGADD ( 10 , ( " Lines returned = [%d] \n " , numlines ) ) ;
DEBUGADD ( 10 , ( " Unlinking port file [%s] \n " , tmp_file ) ) ;
unlink ( tmp_file ) ;
if ( numlines ) {
if ( ( ports = ( PORT_INFO_2 * ) malloc ( numlines * sizeof ( PORT_INFO_2 ) ) ) = = NULL ) {
DEBUG ( 10 , ( " Returning ERROR_NOT_ENOUGH_MEMORY [%x] \n " , ERROR_NOT_ENOUGH_MEMORY ) ) ;
file_lines_free ( qlines ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
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 )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
2000-02-15 21:07:45 +03:00
return ERROR_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 ) ) ;
2000-06-23 03:59:22 +04:00
new_smb_io_port_2 ( " " , buffer , & ports [ i ] , 0 ) ;
2000-02-15 21:07:45 +03:00
}
safe_free ( ports ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
enumports .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_enumports ( UNISTR2 * name , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
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 ) ;
break ;
case 2 :
return enumports_level_2 ( buffer , offered , needed , returned ) ;
break ;
default :
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-15 21:07:45 +03:00
break ;
}
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-03-29 18:49:05 +04:00
static uint32 spoolss_addprinterex_level_2 ( 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 " ) ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
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 ) ;
2000-08-01 00:41:51 +04:00
return ERROR_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 ) ;
return ERROR_ACCESS_DENIED ;
}
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 ) ;
return ERROR_ACCESS_DENIED ;
}
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 ) ;
2000-08-01 00:41:51 +04:00
return ERROR_INVALID_PARAMETER ;
2000-07-25 05:50:53 +04:00
}
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 ) ;
2000-03-13 18:53:02 +03:00
return ERROR_ACCESS_DENIED ;
2000-06-02 22:38:49 +04:00
}
2000-03-13 18:53:02 +03:00
2000-07-22 04:48:29 +04:00
if ( ! open_printer_hnd ( 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 ) ;
2000-03-13 18:53:02 +03:00
return ERROR_ACCESS_DENIED ;
2000-02-07 19:17:59 +03:00
}
2000-06-02 22:38:49 +04:00
free_a_printer ( & printer , 2 ) ;
2000-02-21 04:58:13 +03:00
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
2000-03-29 18:49:05 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_addprinterex ( const UNISTR2 * uni_srv_name , uint32 level ,
const SPOOL_PRINTER_INFO_LEVEL * info ,
uint32 unk0 , uint32 unk1 , uint32 unk2 , uint32 unk3 ,
uint32 user_switch , const SPOOL_USER_CTR * user ,
POLICY_HND * handle )
{
switch ( level ) {
case 1 :
/* we don't handle yet */
/* but I know what to do ... */
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-03-29 18:49:05 +04:00
break ;
case 2 :
return spoolss_addprinterex_level_2 ( uni_srv_name , info ,
unk0 , unk1 , unk2 , unk3 ,
user_switch , user , handle ) ;
break ;
default :
return ERROR_INVALID_LEVEL ;
break ;
}
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-25 17:15:16 +04:00
uint32 _spoolss_addprinterdriver ( pipes_struct * p , const UNISTR2 * server_name ,
uint32 level , const SPOOL_PRINTER_DRIVER_INFO_LEVEL * info )
2000-02-07 19:17:59 +03:00
{
2000-06-04 04:26:08 +04:00
uint32 err = NT_STATUS_NO_PROBLEMO ;
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-02-21 04:58:13 +03:00
2000-07-25 17:15:16 +04:00
if ( p - > ntlmssp_auth_validated ) {
memcpy ( & user , & p - > pipe_user , sizeof ( user ) ) ;
} else {
extern struct current_user current_user ;
memcpy ( & user , & current_user , sizeof ( user ) ) ;
}
2000-02-07 19:17:59 +03:00
convert_printer_driver_info ( info , & driver , level ) ;
2000-02-21 04:58:13 +03:00
2000-07-25 17:15:16 +04:00
DEBUG ( 5 , ( " Cleaning driver's information \n " ) ) ;
clean_up_driver_struct ( driver , level ) ;
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 )
err = ERROR_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 ) {
err = ERROR_ACCESS_DENIED ;
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
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 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 )
return ERROR_INVALID_ENVIRONMENT ;
2000-04-07 02:48:53 +04:00
if ( ( info = ( DRIVER_DIRECTORY_1 * ) malloc ( sizeof ( DRIVER_DIRECTORY_1 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-03-13 14:09:20 +03:00
}
2000-02-21 04:58:13 +03:00
new_smb_io_driverdir_1 ( " " , buffer , info , 0 ) ;
safe_free ( info ) ;
if ( * needed > offered )
return ERROR_INSUFFICIENT_BUFFER ;
else
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
2000-02-21 04:58:13 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_getprinterdriverdirectory ( UNISTR2 * name , UNISTR2 * uni_environment , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed )
{
DEBUG ( 4 , ( " _spoolss_getprinterdriverdirectory \n " ) ) ;
* needed = 0 ;
switch ( level ) {
case 1 :
return getprinterdriverdir_level_1 ( name , uni_environment , buffer , offered , needed ) ;
break ;
default :
2000-03-13 14:09:20 +03:00
return ERROR_INVALID_LEVEL ;
2000-02-21 04:58:13 +03:00
break ;
}
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_enumprinterdata ( POLICY_HND * handle , uint32 idx ,
2000-02-27 01:22:24 +03:00
uint32 in_value_len , uint32 in_data_len ,
uint32 * out_max_value_len , uint16 * * out_value , uint32 * out_value_len ,
uint32 * out_type ,
2000-03-10 20:12:24 +03:00
uint32 * out_max_data_len , uint8 * * data_out , uint32 * out_data_len )
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
fstring value ;
uint32 param_index ;
uint32 biggest_valuesize ;
uint32 biggest_datasize ;
uint32 data_len ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( 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 " ) ) ;
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_enumprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_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
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_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 )
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +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
/*
* 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 ) ;
return ERROR_NO_MORE_ITEMS ;
}
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 ) ;
return ERROR_NO_MORE_ITEMS ;
}
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 ) ;
2000-02-27 01:22:24 +03:00
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +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 ) ;
2000-03-07 12:06:03 +03:00
return ERROR_NO_MORE_ITEMS ;
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-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-06-22 05:39:17 +04:00
* out_max_value_len = ( in_value_len / sizeof ( uint16 ) ) ;
2000-04-07 02:48:53 +04:00
if ( ( * out_value = ( uint16 * ) malloc ( in_value_len * sizeof ( uint8 ) ) ) = = NULL ) {
safe_free ( data ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
2000-07-12 18:10:40 +04:00
ZERO_STRUCTP ( * out_value ) ;
2000-06-22 05:39:17 +04:00
* out_value_len = ( uint32 ) dos_PutUniCode ( ( char * ) * out_value , value , in_value_len , True ) ;
2000-02-27 01:22:24 +03:00
* out_type = type ;
/* the data is counted in bytes */
* out_max_data_len = in_data_len ;
2000-04-07 02:48:53 +04:00
if ( ( * data_out = ( uint8 * ) malloc ( in_data_len * sizeof ( uint8 ) ) ) = = NULL ) {
safe_free ( data ) ;
return ERROR_NOT_ENOUGH_MEMORY ;
}
2000-07-12 18:10:40 +04:00
ZERO_STRUCTP ( * data_out ) ;
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
2000-02-27 01:22:24 +03:00
return NT_STATUS_NO_PROBLEMO ;
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_setprinterdata ( POLICY_HND * handle ,
2000-02-07 19:17:59 +03:00
const UNISTR2 * value ,
uint32 type ,
uint32 max_len ,
const uint8 * data ,
uint32 real_len ,
uint32 numeric_data )
{
2000-06-01 06:35:30 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2000-08-09 08:19:18 +04:00
NT_PRINTER_PARAM * param = NULL ;
2000-02-07 19:17:59 +03:00
int snum = 0 ;
uint32 status = 0x0 ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_setprinterdata \n " ) ) ;
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_setprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_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
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
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
DEBUG ( 3 , ( " security descriptor change denied by existing "
" security descriptor \n " ) ) ;
2000-08-09 11:34:35 +04:00
return ERROR_ACCESS_DENIED ;
2000-08-09 08:19:18 +04:00
}
2000-02-07 19:17:59 +03:00
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( status ! = 0x0 )
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_NAME ;
2000-02-07 19:17:59 +03:00
convert_specific_param ( & param , value , type , data , real_len ) ;
2000-06-01 06:35:30 +04:00
unlink_specific_param_if_exist ( printer - > info_2 , param ) ;
2000-02-07 19:17:59 +03:00
2000-06-01 06:35:30 +04:00
if ( ! add_a_specific_param ( printer - > info_2 , param ) )
2000-04-05 14:05:32 +04:00
status = ERROR_INVALID_PARAMETER ;
2000-02-07 19:17:59 +03:00
else
2000-06-01 06:35:30 +04:00
status = add_a_printer ( * printer , 2 ) ;
2000-04-05 14:05:32 +04:00
2000-06-03 04:53:07 +04:00
free_a_printer ( & printer , 2 ) ;
2000-02-07 19:17:59 +03:00
return status ;
}
2000-09-09 04:19:35 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_deleteprinterdata ( POLICY_HND * handle , const UNISTR2 * value )
{
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_PRINTER_PARAM param ;
int snum = 0 ;
uint32 status = 0x0 ;
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
DEBUG ( 5 , ( " spoolss_deleteprinterdata \n " ) ) ;
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_deleteprinterdata: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
return ERROR_INVALID_HANDLE ;
}
if ( ! get_printer_snum ( handle , & snum ) )
return ERROR_INVALID_HANDLE ;
if ( ! print_access_check ( NULL , snum , PRINTER_ACCESS_ADMINISTER ) ) {
DEBUG ( 3 , ( " _spoolss_deleteprinterdata: security descriptor change denied by existing "
" security descriptor \n " ) ) ;
return ERROR_ACCESS_DENIED ;
}
status = get_a_printer ( & printer , 2 , lp_servicename ( snum ) ) ;
if ( status ! = 0x0 )
return ERROR_INVALID_NAME ;
ZERO_STRUCTP ( & param ) ;
unistr2_to_ascii ( param . value , value , sizeof ( param . value ) - 1 ) ;
if ( ! unlink_specific_param_if_exist ( printer - > info_2 , & param ) )
status = ERROR_INVALID_PARAMETER ;
else
status = add_a_printer ( * printer , 2 ) ;
free_a_printer ( & printer , 2 ) ;
return status ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_addform ( POLICY_HND * handle ,
2000-02-07 19:17:59 +03:00
uint32 level ,
const FORM * form )
{
int count = 0 ;
nt_forms_struct * list = NULL ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_addform \n " ) ) ;
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_addform: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-07-07 03:31:46 +04:00
}
2000-02-07 19:17:59 +03:00
count = get_ntforms ( & list ) ;
2000-04-07 02:48:53 +04:00
if ( ! add_a_form ( & list , form , & count ) )
return ERROR_NOT_ENOUGH_MEMORY ;
2000-02-07 19:17:59 +03:00
write_ntforms ( & list , count ) ;
safe_free ( list ) ;
return 0x0 ;
}
2000-08-31 23:04:51 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_deleteform ( POLICY_HND * handle , UNISTR2 * form_name )
{
int count = 0 ;
uint32 ret = 0 ;
nt_forms_struct * list = NULL ;
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
DEBUG ( 5 , ( " spoolss_deleteform \n " ) ) ;
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_deleteform: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
return ERROR_INVALID_HANDLE ;
}
count = get_ntforms ( & list ) ;
if ( ! delete_a_form ( & list , form_name , & count , & ret ) )
return ERROR_INVALID_PARAMETER ;
safe_free ( list ) ;
return ret ;
}
2000-02-07 19:17:59 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 04:48:29 +04:00
uint32 _spoolss_setform ( POLICY_HND * handle ,
2000-02-07 19:17:59 +03:00
const UNISTR2 * uni_name ,
uint32 level ,
const FORM * form )
{
int count = 0 ;
nt_forms_struct * list = NULL ;
2000-02-25 02:01:24 +03:00
Printer_entry * Printer = find_printer_index_by_hnd ( handle ) ;
2000-02-07 19:17:59 +03:00
DEBUG ( 5 , ( " spoolss_setform \n " ) ) ;
2000-07-07 03:31:46 +04:00
if ( ! OPEN_HANDLE ( Printer ) ) {
DEBUG ( 0 , ( " _spoolss_setform: Invalid handle (%s). \n " , OUR_HANDLE ( handle ) ) ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_HANDLE ;
2000-02-07 19:17:59 +03:00
}
count = get_ntforms ( & list ) ;
update_a_form ( & list , form , count ) ;
write_ntforms ( & list , count ) ;
safe_free ( list ) ;
return 0x0 ;
}
/****************************************************************************
2000-02-15 21:07:45 +03:00
enumprintprocessors level 1.
2000-02-07 19:17:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-15 21:07:45 +03:00
static uint32 enumprintprocessors_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
PRINTPROCESSOR_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_1 = ( PRINTPROCESSOR_1 * ) malloc ( sizeof ( PRINTPROCESSOR_1 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) )
return ERROR_INSUFFICIENT_BUFFER ;
smb_io_printprocessor_info_1 ( " " , buffer , info_1 , 0 ) ;
safe_free ( info_1 ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_enumprintprocessors ( UNISTR2 * name , UNISTR2 * environment , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
DEBUG ( 5 , ( " spoolss_enumprintprocessors \n " ) ) ;
/*
* 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 ) ;
break ;
default :
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-15 21:07:45 +03:00
break ;
2000-02-07 19:17:59 +03:00
}
2000-02-27 02:01:02 +03:00
}
/****************************************************************************
enumprintprocdatatypes level 1.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 enumprintprocdatatypes_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
PRINTPROCDATATYPE_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_1 = ( PRINTPROCDATATYPE_1 * ) malloc ( sizeof ( PRINTPROCDATATYPE_1 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) )
return ERROR_INSUFFICIENT_BUFFER ;
smb_io_printprocdatatype_info_1 ( " " , buffer , info_1 , 0 ) ;
safe_free ( info_1 ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
2000-02-07 19:17:59 +03:00
2000-02-27 02:01:02 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_enumprintprocdatatypes ( UNISTR2 * name , UNISTR2 * processor , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
{
DEBUG ( 5 , ( " _spoolss_enumprintprocdatatypes \n " ) ) ;
* returned = 0 ;
* needed = 0 ;
switch ( level ) {
case 1 :
return enumprintprocdatatypes_level_1 ( buffer , offered , needed , returned ) ;
break ;
default :
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-27 02:01:02 +03:00
break ;
}
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.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 enumprintmonitors_level_1 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
PRINTMONITOR_1 * info_1 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_1 = ( PRINTMONITOR_1 * ) malloc ( sizeof ( PRINTMONITOR_1 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) )
return ERROR_INSUFFICIENT_BUFFER ;
smb_io_printmonitor_info_1 ( " " , buffer , info_1 , 0 ) ;
safe_free ( info_1 ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-15 21:07:45 +03:00
static uint32 enumprintmonitors_level_2 ( NEW_BUFFER * buffer , uint32 offered , uint32 * needed , uint32 * returned )
{
PRINTMONITOR_2 * info_2 = NULL ;
2000-04-07 02:48:53 +04:00
if ( ( info_2 = ( PRINTMONITOR_2 * ) malloc ( sizeof ( PRINTMONITOR_2 ) ) ) = = NULL )
return ERROR_NOT_ENOUGH_MEMORY ;
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 ) )
return ERROR_INSUFFICIENT_BUFFER ;
smb_io_printmonitor_info_2 ( " " , buffer , info_2 , 0 ) ;
safe_free ( info_2 ) ;
if ( * needed > offered ) {
* returned = 0 ;
return ERROR_INSUFFICIENT_BUFFER ;
}
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_enumprintmonitors ( UNISTR2 * name , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed , uint32 * returned )
2000-02-07 19:17:59 +03:00
{
DEBUG ( 5 , ( " spoolss_enumprintmonitors \n " ) ) ;
/*
* 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 ) ;
break ;
case 2 :
return enumprintmonitors_level_2 ( buffer , offered , needed , returned ) ;
break ;
default :
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-15 21:07:45 +03:00
break ;
}
2000-02-07 19:17:59 +03:00
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-21 04:58:13 +03:00
static uint32 getjob_level_1 ( print_queue_struct * queue , int count , int snum , uint32 jobid , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
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 ) ;
2000-04-05 14:05:32 +04:00
return ERROR_NOT_ENOUGH_MEMORY ;
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 */
return NT_STATUS_NO_PROBLEMO ;
}
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-04-06 20:23:04 +04:00
}
2000-02-21 04:58:13 +03:00
new_smb_io_job_info_1 ( " " , buffer , info_1 , 0 ) ;
safe_free ( info_1 ) ;
if ( * needed > offered )
return ERROR_INSUFFICIENT_BUFFER ;
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 getjob_level_2 ( print_queue_struct * queue , int count , int snum , uint32 jobid , NEW_BUFFER * buffer , uint32 offered , uint32 * needed )
{
int i = 0 ;
BOOL found = False ;
2000-06-16 12:18:09 +04:00
JOB_INFO_2 * info_2 ;
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 ) ;
2000-04-05 14:05:32 +04:00
return ERROR_NOT_ENOUGH_MEMORY ;
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 */
return NT_STATUS_NO_PROBLEMO ;
}
2000-04-06 20:23:04 +04:00
fill_job_info_2 ( info_2 , & ( queue [ i - 1 ] ) , i , snum ) ;
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 ) ;
2000-02-21 04:58:13 +03:00
return ERROR_INSUFFICIENT_BUFFER ;
2000-04-06 20:23:04 +04:00
}
2000-02-21 04:58:13 +03:00
new_smb_io_job_info_2 ( " " , buffer , info_2 , 0 ) ;
2000-06-16 12:18:09 +04:00
free_dev_mode ( info_2 - > devmode ) ;
2000-02-21 04:58:13 +03:00
safe_free ( info_2 ) ;
if ( * needed > offered )
return ERROR_INSUFFICIENT_BUFFER ;
else
return NT_STATUS_NO_PROBLEMO ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _spoolss_getjob ( POLICY_HND * handle , uint32 jobid , uint32 level ,
NEW_BUFFER * buffer , uint32 offered ,
uint32 * needed )
2000-02-07 19:17:59 +03:00
{
int snum ;
int count ;
print_queue_struct * queue = NULL ;
print_status_struct prt_status ;
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 ;
2000-02-07 19:17:59 +03:00
if ( ! get_printer_snum ( handle , & snum ) )
2000-04-05 14:05:32 +04:00
return ERROR_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 ) ;
break ;
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
break ;
default :
safe_free ( queue ) ;
2000-04-05 14:05:32 +04:00
return ERROR_INVALID_LEVEL ;
2000-02-21 04:58:13 +03:00
break ;
2000-02-07 19:17:59 +03:00
}
}
2000-05-27 00:54:46 +04:00
# undef OLD_NTDOMAIN