From 5604a78f0919f77fdf041989e3e2e0f61da80fd9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 22 Apr 2010 16:53:15 -0400 Subject: s3-spoolss: Migrated NT_DEVICEMODE to spoolss_DeviceMode. Signed-off-by: Jim McDonough --- source3/include/nt_printing.h | 49 +---- source3/include/printing.h | 2 +- source3/include/proto.h | 15 +- source3/printing/nt_printing.c | 347 +++++++++++------------------------- source3/printing/printing.c | 22 +-- source3/rpc_server/srv_spoolss_nt.c | 220 +++++------------------ 6 files changed, 168 insertions(+), 487 deletions(-) diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 0241a54b79..5a1eb00489 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -36,47 +36,6 @@ typedef struct { NT_PRINTER_KEY *keys; } NT_PRINTER_DATA; -typedef struct ntdevicemode -{ - fstring devicename; - fstring formname; - - uint16 specversion; - uint16 driverversion; - uint16 size; - uint16 driverextra; - uint16 orientation; - uint16 papersize; - uint16 paperlength; - uint16 paperwidth; - uint16 scale; - uint16 copies; - uint16 defaultsource; - uint16 printquality; - uint16 color; - uint16 duplex; - uint16 yresolution; - uint16 ttoption; - uint16 collate; - uint16 logpixels; - - uint32 fields; - uint32 bitsperpel; - uint32 pelswidth; - uint32 pelsheight; - uint32 displayflags; - uint32 displayfrequency; - uint32 icmmethod; - uint32 icmintent; - uint32 mediatype; - uint32 dithertype; - uint32 reserved1; - uint32 reserved2; - uint32 panningwidth; - uint32 panningheight; - uint8 *nt_dev_private; -} NT_DEVICEMODE; - typedef struct nt_printer_info_level_2 { uint32 attributes; @@ -94,7 +53,7 @@ typedef struct nt_printer_info_level_2 fstring drivername; char comment[1024]; fstring location; - NT_DEVICEMODE *devmode; + struct spoolss_DeviceMode *devmode; fstring sepfile; fstring printprocessor; fstring datatype; @@ -230,10 +189,10 @@ typedef struct _Printer{ fstring machine; fstring user; } client; - + /* devmode sent in the OpenPrinter() call */ - NT_DEVICEMODE *nt_devmode; - + struct spoolss_DeviceMode *devmode; + /* cache the printer info */ NT_PRINTER_INFO_LEVEL *printer_info; diff --git a/source3/include/printing.h b/source3/include/printing.h index d91917b528..ac2ee05a93 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -40,7 +40,7 @@ struct printjob { fstring jobname; /* the job name given to us by the client */ fstring user; /* the user who started the job */ fstring queuename; /* service number of printer for this job */ - NT_DEVICEMODE *nt_devmode; + struct spoolss_DeviceMode *devmode; }; /* Information for print interfaces */ diff --git a/source3/include/proto.h b/source3/include/proto.h index 16110f2cde..0904c4a0dc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4739,11 +4739,11 @@ WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx, WERROR move_driver_to_download_area(struct pipes_struct *p, struct spoolss_AddDriverInfoCtr *r, WERROR *perr); -int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen); +int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen); +int unpack_devicemode(TALLOC_CTX *mem_ctx, + const uint8 *buf, int buflen, + struct spoolss_DeviceMode **devmode); uint32 del_a_printer(const char *sharename); -NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename); -void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr); -int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen); WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, const char *devicename, struct spoolss_DeviceMode **devmode); @@ -4831,7 +4831,7 @@ bool print_notify_deregister_pid(int snum); bool print_job_exists(const char* sharename, uint32 jobid); int print_job_fd(const char* sharename, uint32 jobid); char *print_job_fname(const char* sharename, uint32 jobid); -NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid); +struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid); bool print_job_set_name(const char *sharename, uint32 jobid, const char *name); bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name); bool print_job_delete(struct auth_serversupplied_info *server_info, int snum, @@ -4843,7 +4843,7 @@ bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size); int print_queue_length(int snum, print_status_struct *pstatus); uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, - const char *jobname, NT_DEVICEMODE *nt_devmode ); + const char *jobname, struct spoolss_DeviceMode *devmode ); void print_job_endpage(int snum, uint32 jobid); bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type); int print_queue_status(int snum, @@ -5144,9 +5144,6 @@ void reset_all_printerdata(struct messaging_context *msg, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); -bool convert_devicemode(const char *printername, - const struct spoolss_DeviceMode *devmode, - NT_DEVICEMODE **pp_nt_devmode); WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, uint32_t type, uint8_t *data, int real_len); diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 9ed6461b27..c65da830fb 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2289,62 +2289,82 @@ static WERROR get_a_printer_driver_3(TALLOC_CTX *mem_ctx, /**************************************************************************** ****************************************************************************/ -int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen) +int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen) { + enum ndr_err_code ndr_err; + DATA_BLOB blob; + int len = 0; + + if (devmode) { + ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), + devmode, + (ndr_push_flags_fn_t) + ndr_push_spoolss_DeviceMode); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(10, ("pack_devicemode: " + "error encoding spoolss_DeviceMode\n")); + goto done; + } + } else { + ZERO_STRUCT(blob); + } + + len = tdb_pack(buf, buflen, "B", blob.length, blob.data); + + if (devmode) { + DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname)); + } + +done: + return len; +} + +/**************************************************************************** +****************************************************************************/ +int unpack_devicemode(TALLOC_CTX *mem_ctx, + const uint8 *buf, int buflen, + struct spoolss_DeviceMode **devmode) +{ + struct spoolss_DeviceMode *dm; + enum ndr_err_code ndr_err; + char *data = NULL; + int data_len = 0; + DATA_BLOB blob; int len = 0; - len += tdb_pack(buf+len, buflen-len, "p", nt_devmode); + *devmode = NULL; - if (!nt_devmode) + len = tdb_unpack(buf, buflen, "B", &data_len, &data); + if (!data) { return len; + } + + dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); + if (!dm) { + goto done; + } - len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp", - nt_devmode->devicename, - nt_devmode->formname, - - nt_devmode->specversion, - nt_devmode->driverversion, - nt_devmode->size, - nt_devmode->driverextra, - nt_devmode->orientation, - nt_devmode->papersize, - nt_devmode->paperlength, - nt_devmode->paperwidth, - nt_devmode->scale, - nt_devmode->copies, - nt_devmode->defaultsource, - nt_devmode->printquality, - nt_devmode->color, - nt_devmode->duplex, - nt_devmode->yresolution, - nt_devmode->ttoption, - nt_devmode->collate, - nt_devmode->logpixels, - - nt_devmode->fields, - nt_devmode->bitsperpel, - nt_devmode->pelswidth, - nt_devmode->pelsheight, - nt_devmode->displayflags, - nt_devmode->displayfrequency, - nt_devmode->icmmethod, - nt_devmode->icmintent, - nt_devmode->mediatype, - nt_devmode->dithertype, - nt_devmode->reserved1, - nt_devmode->reserved2, - nt_devmode->panningwidth, - nt_devmode->panningheight, - nt_devmode->nt_dev_private); - - if (nt_devmode->nt_dev_private) { - len += tdb_pack(buf+len, buflen-len, "B", - nt_devmode->driverextra, - nt_devmode->nt_dev_private); - } - - DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname)); + blob = data_blob_const(data, data_len); + ndr_err = ndr_pull_struct_blob(&blob, dm, dm, + (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(10, ("unpack_devicemode: " + "error parsing spoolss_DeviceMode\n")); + goto done; + } + + DEBUG(8, ("Unpacked devicemode [%s](%s)\n", + dm->devicename, dm->formname)); + if (dm->driverextra_data.data) { + DEBUG(8, ("with a private section of %d bytes\n", + dm->__driverextra_length)); + } + + *devmode = dm; + +done: + SAFE_FREE(data); return len; } @@ -2721,187 +2741,6 @@ WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, return WERR_OK; } -/**************************************************************************** - Malloc and return an NT devicemode. -****************************************************************************/ - -NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename) -{ - - char adevice[MAXDEVICENAME]; - NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE); - - if (nt_devmode == NULL) { - DEBUG(0,("construct_nt_devicemode: malloc fail.\n")); - return NULL; - } - - ZERO_STRUCTP(nt_devmode); - - slprintf(adevice, sizeof(adevice), "%s", default_devicename); - fstrcpy(nt_devmode->devicename, adevice); - - fstrcpy(nt_devmode->formname, "Letter"); - - nt_devmode->specversion = DMSPEC_NT4_AND_ABOVE; - nt_devmode->driverversion = 0x0400; - nt_devmode->size = 0x00DC; - nt_devmode->driverextra = 0x0000; - nt_devmode->fields = DEVMODE_FORMNAME | - DEVMODE_TTOPTION | - DEVMODE_PRINTQUALITY | - DEVMODE_DEFAULTSOURCE | - DEVMODE_COPIES | - DEVMODE_SCALE | - DEVMODE_PAPERSIZE | - DEVMODE_ORIENTATION; - nt_devmode->orientation = DMORIENT_PORTRAIT; - nt_devmode->papersize = DMPAPER_LETTER; - nt_devmode->paperlength = 0; - nt_devmode->paperwidth = 0; - nt_devmode->scale = 0x64; - nt_devmode->copies = 1; - nt_devmode->defaultsource = DMBIN_FORMSOURCE; - nt_devmode->printquality = DMRES_HIGH; /* 0x0258 */ - nt_devmode->color = DMRES_MONOCHROME; - nt_devmode->duplex = DMDUP_SIMPLEX; - nt_devmode->yresolution = 0; - nt_devmode->ttoption = DMTT_SUBDEV; - nt_devmode->collate = DMCOLLATE_FALSE; - nt_devmode->icmmethod = 0; - nt_devmode->icmintent = 0; - nt_devmode->mediatype = 0; - nt_devmode->dithertype = 0; - - /* non utilisés par un driver d'imprimante */ - nt_devmode->logpixels = 0; - nt_devmode->bitsperpel = 0; - nt_devmode->pelswidth = 0; - nt_devmode->pelsheight = 0; - nt_devmode->displayflags = 0; - nt_devmode->displayfrequency = 0; - nt_devmode->reserved1 = 0; - nt_devmode->reserved2 = 0; - nt_devmode->panningwidth = 0; - nt_devmode->panningheight = 0; - - nt_devmode->nt_dev_private = NULL; - return nt_devmode; -} - -/**************************************************************************** - Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE. -****************************************************************************/ - -void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr) -{ - NT_DEVICEMODE *nt_devmode = *devmode_ptr; - - if(nt_devmode == NULL) - return; - - DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n")); - - SAFE_FREE(nt_devmode->nt_dev_private); - SAFE_FREE(*devmode_ptr); -} - -/**************************************************************************** - Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2. -****************************************************************************/ - -static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr) -{ - NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr; - - if ( !info ) - return; - - free_nt_devicemode(&info->devmode); - - TALLOC_FREE( *info_ptr ); -} - - -/**************************************************************************** -****************************************************************************/ -int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen) -{ - int len = 0; - int extra_len = 0; - NT_DEVICEMODE devmode; - - ZERO_STRUCT(devmode); - - len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode); - - if (!*nt_devmode) return len; - - len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp", - devmode.devicename, - devmode.formname, - - &devmode.specversion, - &devmode.driverversion, - &devmode.size, - &devmode.driverextra, - &devmode.orientation, - &devmode.papersize, - &devmode.paperlength, - &devmode.paperwidth, - &devmode.scale, - &devmode.copies, - &devmode.defaultsource, - &devmode.printquality, - &devmode.color, - &devmode.duplex, - &devmode.yresolution, - &devmode.ttoption, - &devmode.collate, - &devmode.logpixels, - - &devmode.fields, - &devmode.bitsperpel, - &devmode.pelswidth, - &devmode.pelsheight, - &devmode.displayflags, - &devmode.displayfrequency, - &devmode.icmmethod, - &devmode.icmintent, - &devmode.mediatype, - &devmode.dithertype, - &devmode.reserved1, - &devmode.reserved2, - &devmode.panningwidth, - &devmode.panningheight, - &devmode.nt_dev_private); - - if (devmode.nt_dev_private) { - /* the len in tdb_unpack is an int value and - * devmode.driverextra is only a short - */ - len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private); - devmode.driverextra=(uint16)extra_len; - - /* check to catch an invalid TDB entry so we don't segfault */ - if (devmode.driverextra == 0) { - devmode.nt_dev_private = NULL; - } - } - - *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode)); - if (!*nt_devmode) { - SAFE_FREE(devmode.nt_dev_private); - return -1; - } - - DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname)); - if (devmode.nt_dev_private) - DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra)); - - return len; -} - /**************************************************************************** Allocate and initialize a new slot. ***************************************************************************/ @@ -4084,6 +3923,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, bool get_loc_com) { int snum = lp_servicenumber(sharename); + WERROR result; slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername); slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", @@ -4144,7 +3984,10 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, */ if (lp_default_devmode(snum)) { - if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) { + result = spoolss_create_default_devmode(info, + info->printername, + &info->devmode); + if (!W_ERROR_IS_OK(result)) { goto fail; } } else { @@ -4165,8 +4008,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, return WERR_OK; fail: - if (info->devmode) - free_nt_devicemode(&info->devmode); + TALLOC_FREE(info->devmode); return WERR_ACCESS_DENIED; } @@ -4183,8 +4025,8 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, int snum = lp_servicenumber(sharename); TDB_DATA kbuf, dbuf; fstring printername; - char adevice[MAXDEVICENAME]; char *comment = NULL; + WERROR result; kbuf = make_printer_tdbkey(talloc_tos(), sharename); @@ -4256,7 +4098,9 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, } #endif - len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len); + len += unpack_devicemode(info, dbuf.dptr+len, + dbuf.dsize-len, + &info->devmode); /* * Some client drivers freak out if there is a NULL devmode @@ -4269,18 +4113,26 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, if (lp_default_devmode(snum) && !info->devmode) { DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n", printername)); - info->devmode = construct_nt_devicemode(printername); + result = spoolss_create_default_devmode(info, printername, + &info->devmode); + if (!W_ERROR_IS_OK(result)) { + goto done; + } } - slprintf( adevice, sizeof(adevice), "%s", info->printername ); if (info->devmode) { - fstrcpy(info->devmode->devicename, adevice); + info->devmode->devicename = talloc_strdup(info->devmode, + info->printername); + if (!info->devmode->devicename) { + result = WERR_NOMEM; + goto done; + } } if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) { DEBUG(0,("unpack_values: talloc() failed!\n")); - SAFE_FREE(dbuf.dptr); - return WERR_NOMEM; + result = WERR_NOMEM; + goto done; } len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len ); @@ -4288,8 +4140,8 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, passing this as a parameter... fixme... JRA ! */ if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) { - SAFE_FREE(dbuf.dptr); - return WERR_NOMEM; + result = WERR_NOMEM; + goto done; } /* Fix for OS/2 drivers. */ @@ -4298,12 +4150,14 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, map_to_os2_driver(info->drivername); } - SAFE_FREE(dbuf.dptr); - DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n", sharename, info->printername, info->drivername)); - return WERR_OK; + result = WERR_OK; + +done: + SAFE_FREE(dbuf.dptr); + return result; } /**************************************************************************** @@ -4548,8 +4402,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level) switch (level) { case 2: - if ( printer->info_2 ) - free_nt_printer_info_level_2(&printer->info_2); + TALLOC_FREE(printer->info_2); break; default: diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1b5decc696..e0cca8854e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -307,8 +307,10 @@ int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) if ( len == -1 ) return -1; - if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) + used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode); + if (used == -1) { return -1; + } len += used; @@ -352,9 +354,7 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid) return NULL; } - if ( pjob.nt_devmode ) { - free_nt_devicemode( &pjob.nt_devmode ); - } + talloc_free(pjob.devmode); ZERO_STRUCT( pjob ); @@ -556,7 +556,7 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo pjob->user, pjob->queuename); - len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); + len += pack_devicemode(pjob->devmode, buf+len, buflen-len); if (buflen != len) { buf = (uint8 *)SMB_REALLOC(buf, len); @@ -588,7 +588,7 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) { pjob_store_notify( sharename, jobid, &old_pjob , pjob ); - free_nt_devicemode( &old_pjob.nt_devmode ); + talloc_free(old_pjob.devmode); } } else { @@ -709,7 +709,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void jobid = IVAL(key.dptr, 0); if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) return 0; - free_nt_devicemode( &pjob.nt_devmode ); + talloc_free(pjob.devmode); if (!pjob.smbjob) { @@ -1850,14 +1850,14 @@ char *print_job_fname(const char* sharename, uint32 jobid) has not been spooled. ****************************************************************************/ -NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid) +struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid) { struct printjob *pjob = print_job_find(sharename, jobid); if ( !pjob ) return NULL; - return pjob->nt_devmode; + return pjob->devmode; } /**************************************************************************** @@ -2410,7 +2410,7 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) ***************************************************************************/ uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, - const char *jobname, NT_DEVICEMODE *nt_devmode ) + const char *jobname, struct spoolss_DeviceMode *devmode ) { uint32 jobid; char *path; @@ -2485,7 +2485,7 @@ uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, pjob.size = 0; pjob.spooled = False; pjob.smbjob = True; - pjob.nt_devmode = nt_devmode; + pjob.devmode = devmode; fstrcpy(pjob.jobname, jobname); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 27f428b2c4..dffbe9ef10 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -220,7 +220,7 @@ static int printer_entry_destructor(Printer_entry *Printer) TALLOC_FREE(Printer->notify.option); Printer->notify.client_connected = false; - free_nt_devicemode( &Printer->nt_devmode ); + TALLOC_FREE(Printer->devmode); free_a_printer( &Printer->printer_info, 2 ); /* Remove from the internal list. */ @@ -1389,81 +1389,39 @@ WERROR _spoolss_OpenPrinter(pipes_struct *p, return werr; } -/******************************************************************** - ********************************************************************/ - -bool convert_devicemode(const char *printername, - const struct spoolss_DeviceMode *devmode, - NT_DEVICEMODE **pp_nt_devmode) +static WERROR copy_devicemode(TALLOC_CTX *mem_ctx, + struct spoolss_DeviceMode *orig, + struct spoolss_DeviceMode **dest) { - NT_DEVICEMODE *nt_devmode = *pp_nt_devmode; + struct spoolss_DeviceMode *dm; - /* - * Ensure nt_devmode is a valid pointer - * as we will be overwriting it. - */ - - if (nt_devmode == NULL) { - DEBUG(5, ("convert_devicemode: allocating a generic devmode\n")); - if ((nt_devmode = construct_nt_devicemode(printername)) == NULL) - return false; + dm = talloc(mem_ctx, struct spoolss_DeviceMode); + if (!dm) { + return WERR_NOMEM; } - fstrcpy(nt_devmode->devicename, devmode->devicename); - fstrcpy(nt_devmode->formname, devmode->formname); - - nt_devmode->devicename[31] = '\0'; - nt_devmode->formname[31] = '\0'; - - nt_devmode->specversion = devmode->specversion; - nt_devmode->driverversion = devmode->driverversion; - nt_devmode->size = devmode->size; - nt_devmode->fields = devmode->fields; - nt_devmode->orientation = devmode->orientation; - nt_devmode->papersize = devmode->papersize; - nt_devmode->paperlength = devmode->paperlength; - nt_devmode->paperwidth = devmode->paperwidth; - nt_devmode->scale = devmode->scale; - nt_devmode->copies = devmode->copies; - nt_devmode->defaultsource = devmode->defaultsource; - nt_devmode->printquality = devmode->printquality; - nt_devmode->color = devmode->color; - nt_devmode->duplex = devmode->duplex; - nt_devmode->yresolution = devmode->yresolution; - nt_devmode->ttoption = devmode->ttoption; - nt_devmode->collate = devmode->collate; - - nt_devmode->logpixels = devmode->logpixels; - nt_devmode->bitsperpel = devmode->bitsperpel; - nt_devmode->pelswidth = devmode->pelswidth; - nt_devmode->pelsheight = devmode->pelsheight; - nt_devmode->displayflags = devmode->displayflags; - nt_devmode->displayfrequency = devmode->displayfrequency; - nt_devmode->icmmethod = devmode->icmmethod; - nt_devmode->icmintent = devmode->icmintent; - nt_devmode->mediatype = devmode->mediatype; - nt_devmode->dithertype = devmode->dithertype; - nt_devmode->reserved1 = devmode->reserved1; - nt_devmode->reserved2 = devmode->reserved2; - nt_devmode->panningwidth = devmode->panningwidth; - nt_devmode->panningheight = devmode->panningheight; - - /* - * Only change private and driverextra if the incoming devmode - * has a new one. JRA. - */ + /* copy all values, then duplicate strings and structs */ + *dm = *orig; - if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) { - SAFE_FREE(nt_devmode->nt_dev_private); - nt_devmode->driverextra = devmode->__driverextra_length; - if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL) - return false; - memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra); + dm->devicename = talloc_strdup(dm, orig->devicename); + if (!dm->devicename) { + return WERR_NOMEM; + } + dm->formname = talloc_strdup(dm, orig->formname); + if (!dm->formname) { + return WERR_NOMEM; + } + if (orig->driverextra_data.data) { + dm->driverextra_data.data = + (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data, + orig->driverextra_data.length); + if (!dm->driverextra_data.data) { + return WERR_NOMEM; + } } - *pp_nt_devmode = nt_devmode; - - return true; + *dest = dm; + return WERR_OK; } /**************************************************************** @@ -1674,9 +1632,8 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, if ((Printer->printer_type != SPLHND_SERVER) && r->in.devmode_ctr.devmode) { - convert_devicemode(Printer->sharename, - r->in.devmode_ctr.devmode, - &Printer->nt_devmode); + copy_devicemode(NULL, r->in.devmode_ctr.devmode, + &Printer->devmode); } #if 0 /* JERRY -- I'm doubtful this is really effective */ @@ -3545,70 +3502,6 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx, return WERR_OK; } -/**************************************************************************** - Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers - should be valid upon entry -****************************************************************************/ - -static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx, - struct spoolss_DeviceMode *r, - const NT_DEVICEMODE *ntdevmode) -{ - if (!r || !ntdevmode) { - return WERR_INVALID_PARAM; - } - - r->devicename = talloc_strdup(mem_ctx, ntdevmode->devicename); - W_ERROR_HAVE_NO_MEMORY(r->devicename); - - r->specversion = ntdevmode->specversion; - r->driverversion = ntdevmode->driverversion; - r->size = ntdevmode->size; - r->__driverextra_length = ntdevmode->driverextra; - r->fields = ntdevmode->fields; - - r->orientation = ntdevmode->orientation; - r->papersize = ntdevmode->papersize; - r->paperlength = ntdevmode->paperlength; - r->paperwidth = ntdevmode->paperwidth; - r->scale = ntdevmode->scale; - r->copies = ntdevmode->copies; - r->defaultsource = ntdevmode->defaultsource; - r->printquality = ntdevmode->printquality; - r->color = ntdevmode->color; - r->duplex = ntdevmode->duplex; - r->yresolution = ntdevmode->yresolution; - r->ttoption = ntdevmode->ttoption; - r->collate = ntdevmode->collate; - - r->formname = talloc_strdup(mem_ctx, ntdevmode->formname); - W_ERROR_HAVE_NO_MEMORY(r->formname); - - r->logpixels = ntdevmode->logpixels; - r->bitsperpel = ntdevmode->bitsperpel; - r->pelswidth = ntdevmode->pelswidth; - r->pelsheight = ntdevmode->pelsheight; - r->displayflags = ntdevmode->displayflags; - r->displayfrequency = ntdevmode->displayfrequency; - r->icmmethod = ntdevmode->icmmethod; - r->icmintent = ntdevmode->icmintent; - r->mediatype = ntdevmode->mediatype; - r->dithertype = ntdevmode->dithertype; - r->reserved1 = ntdevmode->reserved1; - r->reserved2 = ntdevmode->reserved2; - r->panningwidth = ntdevmode->panningwidth; - r->panningheight = ntdevmode->panningheight; - - if (ntdevmode->nt_dev_private != NULL) { - r->driverextra_data = data_blob_talloc(mem_ctx, - ntdevmode->nt_dev_private, - ntdevmode->driverextra); - W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data); - } - - return WERR_OK; -} - /**************************************************************************** Create a spoolss_DeviceMode struct. Returns talloced memory. @@ -3617,7 +3510,6 @@ static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx, struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx, const char *servicename) { - WERROR result; NT_PRINTER_INFO_LEVEL *printer = NULL; struct spoolss_DeviceMode *devmode = NULL; @@ -3633,18 +3525,7 @@ struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx, goto done; } - devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode); - if (!devmode) { - DEBUG(2,("construct_dev_mode: talloc fail.\n")); - goto done; - } - - DEBUGADD(8,("loading DEVICEMODE\n")); - - result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode); - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(devmode); - } + devmode = talloc_steal(mem_ctx, printer->info_2->devmode); done: free_a_printer(&printer,2); @@ -5171,7 +5052,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, Printer->jobid = print_job_start(p->server_info, snum, info_1->document_name, - Printer->nt_devmode); + Printer->devmode); /* An error occured in print_job_start() so return an appropriate NT error code. */ @@ -5661,10 +5542,10 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, convert it and link it*/ DEBUGADD(8,("update_printer: Converting the devicemode struct\n")); - if (!convert_devicemode(printer->info_2->printername, devmode, - &printer->info_2->devmode)) { - result = WERR_NOMEM; - goto done; + result = copy_devicemode(printer->info_2, devmode, + &printer->info_2->devmode); + if (!W_ERROR_IS_OK(result)) { + return result; } } @@ -5860,13 +5741,12 @@ static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *hand } if (devmode) { - /* we have a valid devmode - convert it and link it*/ + /* we have a valid devmode, copy it */ - DEBUGADD(8,("update_printer: Converting the devicemode struct\n")); - if (!convert_devicemode(printer->info_2->printername, devmode, - &printer->info_2->devmode)) { - result = WERR_NOMEM; + DEBUGADD(8, ("update_printer: Copying the devicemode struct\n")); + result = copy_devicemode(printer->info_2, devmode, + &printer->info_2->devmode); + if (!W_ERROR_IS_OK(result)) { goto done; } } @@ -7265,9 +7145,10 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p, */ DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n")); - if (!convert_devicemode(printer->info_2->printername, devmode, - &printer->info_2->devmode)) { - return WERR_NOMEM; + err = copy_devicemode(printer, devmode, + &printer->info_2->devmode); + if (!W_ERROR_IS_OK(err)) { + return err; } } @@ -8460,8 +8341,6 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx, int i = 0; bool found = false; struct spoolss_DeviceMode *devmode; - NT_DEVICEMODE *nt_devmode; - WERROR result; for (i=0; i