summaryrefslogtreecommitdiff
path: root/source3/printing
diff options
context:
space:
mode:
Diffstat (limited to 'source3/printing')
-rw-r--r--source3/printing/nt_printing.c347
-rw-r--r--source3/printing/printing.c22
2 files changed, 111 insertions, 258 deletions
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;
}
@@ -2722,187 +2742,6 @@ WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
}
/****************************************************************************
- 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);