mirror of
https://github.com/samba-team/samba.git
synced 2025-03-10 12:58:35 +03:00
s3-spoolss: use pidl for _spoolss_EnumPrinters.
Guenther
This commit is contained in:
parent
cdcc5a122b
commit
f6f703f16e
@ -6086,7 +6086,6 @@ void construct_info_data(struct spoolss_Notify *info_data,
|
|||||||
DEVICEMODE *construct_dev_mode(const char *servicename);
|
DEVICEMODE *construct_dev_mode(const char *servicename);
|
||||||
struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
|
struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
|
||||||
const char *servicename);
|
const char *servicename);
|
||||||
WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u);
|
|
||||||
WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
|
WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
|
||||||
WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri );
|
WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri );
|
||||||
bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
|
bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
|
||||||
|
@ -190,27 +190,7 @@ static bool api_spoolss_rfnpcnex(pipes_struct *p)
|
|||||||
|
|
||||||
static bool api_spoolss_enumprinters(pipes_struct *p)
|
static bool api_spoolss_enumprinters(pipes_struct *p)
|
||||||
{
|
{
|
||||||
SPOOL_Q_ENUMPRINTERS q_u;
|
return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERS);
|
||||||
SPOOL_R_ENUMPRINTERS r_u;
|
|
||||||
prs_struct *data = &p->in_data.data;
|
|
||||||
prs_struct *rdata = &p->out_data.rdata;
|
|
||||||
|
|
||||||
ZERO_STRUCT(q_u);
|
|
||||||
ZERO_STRUCT(r_u);
|
|
||||||
|
|
||||||
if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) {
|
|
||||||
DEBUG(0,("spoolss_io_q_enumprinters: unable to unmarshall SPOOL_Q_ENUMPRINTERS.\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_u.status = _spoolss_enumprinters( p, &q_u, &r_u);
|
|
||||||
|
|
||||||
if (!spoolss_io_r_enumprinters("", &r_u, rdata, 0)) {
|
|
||||||
DEBUG(0,("spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -4481,97 +4481,214 @@ static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* construct_printer_info1
|
||||||
|
* fill a spoolss_PrinterInfo1 struct
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
|
||||||
|
const NT_PRINTER_INFO_LEVEL *ntprinter,
|
||||||
|
uint32_t flags,
|
||||||
|
struct spoolss_PrinterInfo1 *r,
|
||||||
|
int snum)
|
||||||
|
{
|
||||||
|
char *chaine = NULL;
|
||||||
|
r->flags = flags;
|
||||||
|
|
||||||
|
if (*ntprinter->info_2->comment == '\0') {
|
||||||
|
r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
|
||||||
|
chaine = talloc_asprintf(mem_ctx,
|
||||||
|
"%s,%s,%s", ntprinter->info_2->printername,
|
||||||
|
ntprinter->info_2->drivername, lp_comment(snum));
|
||||||
|
} else {
|
||||||
|
r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
|
||||||
|
chaine = talloc_asprintf(mem_ctx,
|
||||||
|
"%s,%s,%s", ntprinter->info_2->printername,
|
||||||
|
ntprinter->info_2->drivername, ntprinter->info_2->comment);
|
||||||
|
}
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(chaine);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->comment);
|
||||||
|
|
||||||
|
r->description = talloc_strdup(mem_ctx, chaine);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->description);
|
||||||
|
r->name = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->name);
|
||||||
|
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* construct_printer_info2
|
||||||
|
* fill a spoolss_PrinterInfo2 struct
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
|
||||||
|
const NT_PRINTER_INFO_LEVEL *ntprinter,
|
||||||
|
struct spoolss_PrinterInfo2 *r,
|
||||||
|
int snum)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
print_status_struct status;
|
||||||
|
|
||||||
|
count = print_queue_length(snum, &status);
|
||||||
|
|
||||||
|
r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->servername);
|
||||||
|
r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->printername);
|
||||||
|
r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->sharename);
|
||||||
|
r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->portname);
|
||||||
|
r->drivername = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->drivername);
|
||||||
|
|
||||||
|
if (*ntprinter->info_2->comment == '\0') {
|
||||||
|
r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
|
||||||
|
} else {
|
||||||
|
r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
|
||||||
|
}
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->comment);
|
||||||
|
|
||||||
|
r->location = talloc_strdup(mem_ctx, ntprinter->info_2->location);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->location);
|
||||||
|
r->sepfile = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->sepfile);
|
||||||
|
r->printprocessor = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
|
||||||
|
r->datatype = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->datatype);
|
||||||
|
r->parameters = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(r->parameters);
|
||||||
|
|
||||||
|
r->attributes = ntprinter->info_2->attributes;
|
||||||
|
|
||||||
|
r->priority = ntprinter->info_2->priority;
|
||||||
|
r->defaultpriority = ntprinter->info_2->default_priority;
|
||||||
|
r->starttime = ntprinter->info_2->starttime;
|
||||||
|
r->untiltime = ntprinter->info_2->untiltime;
|
||||||
|
r->status = nt_printq_status(status.status);
|
||||||
|
r->cjobs = count;
|
||||||
|
r->averageppm = ntprinter->info_2->averageppm;
|
||||||
|
|
||||||
|
r->devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
|
||||||
|
if (!r->devmode) {
|
||||||
|
DEBUG(8,("Returning NULL Devicemode!\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
r->secdesc = NULL;
|
||||||
|
|
||||||
|
if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
|
||||||
|
/* don't use talloc_steal() here unless you do a deep steal of all
|
||||||
|
the SEC_DESC members */
|
||||||
|
|
||||||
|
r->secdesc = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Spoolss_enumprinters.
|
Spoolss_enumprinters.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
|
||||||
|
uint32_t flags,
|
||||||
|
union spoolss_PrinterInfo **info_p,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
int snum;
|
int snum;
|
||||||
int i;
|
int n_services = lp_numservices();
|
||||||
int n_services=lp_numservices();
|
union spoolss_PrinterInfo *info = NULL;
|
||||||
PRINTER_INFO_1 *printers=NULL;
|
|
||||||
PRINTER_INFO_1 current_prt;
|
|
||||||
WERROR result = WERR_OK;
|
WERROR result = WERR_OK;
|
||||||
|
|
||||||
DEBUG(4,("enum_all_printers_info_1\n"));
|
DEBUG(4,("enum_all_printers_info_1\n"));
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
for (snum=0; snum<n_services; snum++) {
|
for (snum=0; snum<n_services; snum++) {
|
||||||
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
|
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
|
||||||
|
|
||||||
|
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
|
||||||
|
struct spoolss_PrinterInfo1 info1;
|
||||||
|
|
||||||
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
|
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
|
||||||
|
|
||||||
if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
|
result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
|
||||||
if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
|
continue;
|
||||||
*returned=0;
|
|
||||||
return WERR_NOMEM;
|
|
||||||
}
|
|
||||||
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
|
|
||||||
|
|
||||||
memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
|
|
||||||
(*returned)++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = construct_printer_info1(info, ntprinter, flags, &info1, snum);
|
||||||
|
free_a_printer(&ntprinter,2);
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
|
||||||
|
union spoolss_PrinterInfo,
|
||||||
|
*count + 1);
|
||||||
|
if (!info) {
|
||||||
|
DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
|
||||||
|
result = WERR_NOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count));
|
||||||
|
|
||||||
|
info[*count].info1 = info1;
|
||||||
|
(*count)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the required size. */
|
out:
|
||||||
for (i=0; i<*returned; i++)
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
(*needed) += spoolss_size_printer_info_1(&printers[i]);
|
TALLOC_FREE(info);
|
||||||
|
*count = 0;
|
||||||
if (*needed > offered) {
|
return result;
|
||||||
result = WERR_INSUFFICIENT_BUFFER;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rpcbuf_alloc_size(buffer, *needed)) {
|
*info_p = info;
|
||||||
result = WERR_NOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill the buffer with the structures */
|
return WERR_OK;
|
||||||
for (i=0; i<*returned; i++)
|
|
||||||
smb_io_printer_info_1("", buffer, &printers[i], 0);
|
|
||||||
|
|
||||||
out:
|
|
||||||
/* clear memory */
|
|
||||||
|
|
||||||
SAFE_FREE(printers);
|
|
||||||
|
|
||||||
if ( !W_ERROR_IS_OK(result) )
|
|
||||||
*returned = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
enum_all_printers_info_1_local.
|
enum_all_printers_info_1_local.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
|
||||||
|
union spoolss_PrinterInfo **info,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
DEBUG(4,("enum_all_printers_info_1_local\n"));
|
DEBUG(4,("enum_all_printers_info_1_local\n"));
|
||||||
|
|
||||||
return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
|
return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
enum_all_printers_info_1_name.
|
enum_all_printers_info_1_name.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
|
||||||
|
const char *name,
|
||||||
|
union spoolss_PrinterInfo **info,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
char *s = name;
|
const char *s = name;
|
||||||
|
|
||||||
DEBUG(4,("enum_all_printers_info_1_name\n"));
|
DEBUG(4,("enum_all_printers_info_1_name\n"));
|
||||||
|
|
||||||
if ((name[0] == '\\') && (name[1] == '\\'))
|
if ((name[0] == '\\') && (name[1] == '\\')) {
|
||||||
s = name + 2;
|
s = name + 2;
|
||||||
|
|
||||||
if (is_myname_or_ipaddr(s)) {
|
|
||||||
return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!is_myname_or_ipaddr(s)) {
|
||||||
return WERR_INVALID_NAME;
|
return WERR_INVALID_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
|
#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
|
||||||
@ -4642,9 +4759,12 @@ out:
|
|||||||
enum_all_printers_info_1_network.
|
enum_all_printers_info_1_network.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
|
||||||
|
const char *name,
|
||||||
|
union spoolss_PrinterInfo **info,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
char *s = name;
|
const char *s = name;
|
||||||
|
|
||||||
DEBUG(4,("enum_all_printers_info_1_network\n"));
|
DEBUG(4,("enum_all_printers_info_1_network\n"));
|
||||||
|
|
||||||
@ -4656,13 +4776,15 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
|
|||||||
listed. Windows responds to this call with a
|
listed. Windows responds to this call with a
|
||||||
WERR_CAN_NOT_COMPLETE so we should do the same. */
|
WERR_CAN_NOT_COMPLETE so we should do the same. */
|
||||||
|
|
||||||
if (name[0] == '\\' && name[1] == '\\')
|
if (name[0] == '\\' && name[1] == '\\') {
|
||||||
s = name + 2;
|
s = name + 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_myname_or_ipaddr(s))
|
if (is_myname_or_ipaddr(s)) {
|
||||||
return WERR_CAN_NOT_COMPLETE;
|
return WERR_CAN_NOT_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
|
return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
@ -4671,92 +4793,94 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
|
|||||||
* called from api_spoolss_enumprinters (see this to understand)
|
* called from api_spoolss_enumprinters (see this to understand)
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
|
||||||
|
union spoolss_PrinterInfo **info_p,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
int snum;
|
int snum;
|
||||||
int i;
|
int n_services = lp_numservices();
|
||||||
int n_services=lp_numservices();
|
union spoolss_PrinterInfo *info = NULL;
|
||||||
PRINTER_INFO_2 *printers=NULL;
|
|
||||||
PRINTER_INFO_2 current_prt;
|
|
||||||
WERROR result = WERR_OK;
|
WERROR result = WERR_OK;
|
||||||
|
|
||||||
*returned = 0;
|
*count = 0;
|
||||||
|
|
||||||
for (snum=0; snum<n_services; snum++) {
|
for (snum=0; snum<n_services; snum++) {
|
||||||
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
|
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum)) {
|
||||||
|
|
||||||
|
struct spoolss_PrinterInfo2 info2;
|
||||||
|
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
|
||||||
|
|
||||||
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
|
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
|
||||||
|
|
||||||
if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
|
result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
|
||||||
if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
|
continue;
|
||||||
*returned = 0;
|
|
||||||
return WERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
|
|
||||||
|
|
||||||
memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
|
|
||||||
|
|
||||||
(*returned)++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = construct_printer_info2(info, ntprinter, &info2, snum);
|
||||||
|
free_a_printer(&ntprinter, 2);
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
|
||||||
|
union spoolss_PrinterInfo,
|
||||||
|
*count + 1);
|
||||||
|
if (!info) {
|
||||||
|
DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
|
||||||
|
result = WERR_NOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *count + 1));
|
||||||
|
|
||||||
|
info[*count].info2 = info2;
|
||||||
|
|
||||||
|
(*count)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the required size. */
|
out:
|
||||||
for (i=0; i<*returned; i++)
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
(*needed) += spoolss_size_printer_info_2(&printers[i]);
|
TALLOC_FREE(info);
|
||||||
|
*count = 0;
|
||||||
if (*needed > offered) {
|
return result;
|
||||||
result = WERR_INSUFFICIENT_BUFFER;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rpcbuf_alloc_size(buffer, *needed)) {
|
*info_p = info;
|
||||||
result = WERR_NOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill the buffer with the structures */
|
return WERR_OK;
|
||||||
for (i=0; i<*returned; i++)
|
|
||||||
smb_io_printer_info_2("", buffer, &(printers[i]), 0);
|
|
||||||
|
|
||||||
out:
|
|
||||||
/* clear memory */
|
|
||||||
|
|
||||||
for (i=0; i<*returned; i++)
|
|
||||||
free_devmode(printers[i].devmode);
|
|
||||||
|
|
||||||
SAFE_FREE(printers);
|
|
||||||
|
|
||||||
if ( !W_ERROR_IS_OK(result) )
|
|
||||||
*returned = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* handle enumeration of printers at level 1
|
* handle enumeration of printers at level 1
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static WERROR enumprinters_level1( uint32 flags, fstring name,
|
static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
|
||||||
RPC_BUFFER *buffer, uint32 offered,
|
uint32_t flags,
|
||||||
uint32 *needed, uint32 *returned)
|
const char *name,
|
||||||
|
union spoolss_PrinterInfo **info,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
/* Not all the flags are equals */
|
/* Not all the flags are equals */
|
||||||
|
|
||||||
if (flags & PRINTER_ENUM_LOCAL)
|
if (flags & PRINTER_ENUM_LOCAL) {
|
||||||
return enum_all_printers_info_1_local(buffer, offered, needed, returned);
|
return enum_all_printers_info_1_local(mem_ctx, info, count);
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & PRINTER_ENUM_NAME)
|
if (flags & PRINTER_ENUM_NAME) {
|
||||||
return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
|
return enum_all_printers_info_1_name(mem_ctx, name, info, count);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /* JERRY - disabled for now */
|
#if 0 /* JERRY - disabled for now */
|
||||||
if (flags & PRINTER_ENUM_REMOTE)
|
if (flags & PRINTER_ENUM_REMOTE) {
|
||||||
return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
|
return enum_all_printers_info_1_remote(mem_ctx, name, info, count);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (flags & PRINTER_ENUM_NETWORK)
|
if (flags & PRINTER_ENUM_NETWORK) {
|
||||||
return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
|
return enum_all_printers_info_1_network(mem_ctx, name, info, count);
|
||||||
|
}
|
||||||
|
|
||||||
return WERR_OK; /* NT4sp5 does that */
|
return WERR_OK; /* NT4sp5 does that */
|
||||||
}
|
}
|
||||||
@ -4765,23 +4889,27 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
|
|||||||
* handle enumeration of printers at level 2
|
* handle enumeration of printers at level 2
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static WERROR enumprinters_level2( uint32 flags, const char *servername,
|
static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
|
||||||
RPC_BUFFER *buffer, uint32 offered,
|
uint32_t flags,
|
||||||
uint32 *needed, uint32 *returned)
|
const char *servername,
|
||||||
|
union spoolss_PrinterInfo **info,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
if (flags & PRINTER_ENUM_LOCAL) {
|
if (flags & PRINTER_ENUM_LOCAL) {
|
||||||
return enum_all_printers_info_2(buffer, offered, needed, returned);
|
return enum_all_printers_info_2(mem_ctx, info, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & PRINTER_ENUM_NAME) {
|
if (flags & PRINTER_ENUM_NAME) {
|
||||||
if (is_myname_or_ipaddr(canon_servername(servername)))
|
if (!is_myname_or_ipaddr(canon_servername(servername))) {
|
||||||
return enum_all_printers_info_2(buffer, offered, needed, returned);
|
|
||||||
else
|
|
||||||
return WERR_INVALID_NAME;
|
return WERR_INVALID_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
return enum_all_printers_info_2(mem_ctx, info, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & PRINTER_ENUM_REMOTE)
|
if (flags & PRINTER_ENUM_REMOTE) {
|
||||||
return WERR_UNKNOWN_LEVEL;
|
return WERR_UNKNOWN_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
return WERR_OK;
|
return WERR_OK;
|
||||||
}
|
}
|
||||||
@ -4790,49 +4918,37 @@ static WERROR enumprinters_level2( uint32 flags, const char *servername,
|
|||||||
* handle enumeration of printers at level 5
|
* handle enumeration of printers at level 5
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static WERROR enumprinters_level5( uint32 flags, const char *servername,
|
static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
|
||||||
RPC_BUFFER *buffer, uint32 offered,
|
uint32_t flags,
|
||||||
uint32 *needed, uint32 *returned)
|
const char *servername,
|
||||||
|
union spoolss_PrinterInfo **info,
|
||||||
|
uint32_t *count)
|
||||||
{
|
{
|
||||||
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
|
/* return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/
|
||||||
return WERR_OK;
|
return WERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/****************************************************************
|
||||||
* api_spoolss_enumprinters
|
_spoolss_EnumPrinters
|
||||||
*
|
****************************************************************/
|
||||||
* called from api_spoolss_enumprinters (see this to understand)
|
|
||||||
********************************************************************/
|
|
||||||
|
|
||||||
WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
|
WERROR _spoolss_EnumPrinters(pipes_struct *p,
|
||||||
|
struct spoolss_EnumPrinters *r)
|
||||||
{
|
{
|
||||||
uint32 flags = q_u->flags;
|
const char *name;
|
||||||
UNISTR2 *servername = &q_u->servername;
|
WERROR result;
|
||||||
uint32 level = q_u->level;
|
|
||||||
RPC_BUFFER *buffer = NULL;
|
|
||||||
uint32 offered = q_u->offered;
|
|
||||||
uint32 *needed = &r_u->needed;
|
|
||||||
uint32 *returned = &r_u->returned;
|
|
||||||
|
|
||||||
fstring name;
|
|
||||||
|
|
||||||
/* that's an [in out] buffer */
|
/* that's an [in out] buffer */
|
||||||
|
|
||||||
if (!q_u->buffer && (offered!=0)) {
|
if (!r->in.buffer && (r->in.offered != 0)) {
|
||||||
return WERR_INVALID_PARAM;
|
return WERR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offered > MAX_RPC_DATA_SIZE) {
|
DEBUG(4,("_spoolss_EnumPrinters\n"));
|
||||||
return WERR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcbuf_move(q_u->buffer, &r_u->buffer);
|
*r->out.needed = 0;
|
||||||
buffer = r_u->buffer;
|
*r->out.count = 0;
|
||||||
|
*r->out.info = NULL;
|
||||||
DEBUG(4,("_spoolss_enumprinters\n"));
|
|
||||||
|
|
||||||
*needed=0;
|
|
||||||
*returned=0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Level 1:
|
* Level 1:
|
||||||
@ -4847,21 +4963,42 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
|
|||||||
* Level 5: same as Level 2
|
* Level 5: same as Level 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unistr2_to_ascii(name, servername, sizeof(name));
|
name = talloc_strdup_upper(p->mem_ctx, r->in.server);
|
||||||
strupper_m(name);
|
W_ERROR_HAVE_NO_MEMORY(name);
|
||||||
|
|
||||||
switch (level) {
|
switch (r->in.level) {
|
||||||
case 1:
|
case 1:
|
||||||
return enumprinters_level1(flags, name, buffer, offered, needed, returned);
|
result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
|
||||||
|
r->out.info, r->out.count);
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
return enumprinters_level2(flags, name, buffer, offered, needed, returned);
|
result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
|
||||||
|
r->out.info, r->out.count);
|
||||||
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
return enumprinters_level5(flags, name, buffer, offered, needed, returned);
|
result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
|
||||||
|
r->out.info, r->out.count);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
|
result = WERR_OK; /* ??? */
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return WERR_UNKNOWN_LEVEL;
|
||||||
}
|
}
|
||||||
return WERR_UNKNOWN_LEVEL;
|
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
|
||||||
|
spoolss_EnumPrinters, NULL,
|
||||||
|
*r->out.info, r->in.level,
|
||||||
|
*r->out.count);
|
||||||
|
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
|
||||||
|
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
|
||||||
|
|
||||||
|
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -10217,17 +10354,6 @@ WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
|
|||||||
return WERR_OK;
|
return WERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
_spoolss_EnumPrinters
|
|
||||||
****************************************************************/
|
|
||||||
|
|
||||||
WERROR _spoolss_EnumPrinters(pipes_struct *p,
|
|
||||||
struct spoolss_EnumPrinters *r)
|
|
||||||
{
|
|
||||||
p->rng_fault_state = true;
|
|
||||||
return WERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
_spoolss_AddPrinter
|
_spoolss_AddPrinter
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user