summaryrefslogtreecommitdiff
path: root/source3/printing
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2007-02-09 02:12:12 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:52 -0500
commit56b40269c8a8e9a1d2fda79ea2fa991b6575e942 (patch)
treeda722aa5edf08bb27a34f753aa81dd078a635617 /source3/printing
parent86e5659abac9938e7ac0cea989ca33e807b3e181 (diff)
downloadsamba-56b40269c8a8e9a1d2fda79ea2fa991b6575e942.tar.gz
samba-56b40269c8a8e9a1d2fda79ea2fa991b6575e942.tar.bz2
samba-56b40269c8a8e9a1d2fda79ea2fa991b6575e942.zip
r21258: Fix for connecting printers from Vista by storing
the printer GUID as a REG_SZ as Vista seems to whine about unknown REG_BINARY values. Thanks to Martin Zielinski <mz@seh.de> for his excellent analysis on this. (This used to be commit fa5490b71b5cd41b63b028aa8a316e1197263083)
Diffstat (limited to 'source3/printing')
-rw-r--r--source3/printing/nt_printing.c87
1 files changed, 78 insertions, 9 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index e415cd41b2..652726c401 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2999,11 +2999,15 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
return True;
}
+/*****************************************************************
+ ****************************************************************/
+
static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
struct GUID guid)
{
int i;
REGVAL_CTR *ctr=NULL;
+ UNISTR2 unistr_guid;
/* find the DsSpooler key */
if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
@@ -3011,8 +3015,18 @@ static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
ctr = info2->data->keys[i].values;
regval_ctr_delvalue(ctr, "objectGUID");
- regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
- (char *) &guid, sizeof(struct GUID));
+
+ /* We used to store this as a REG_BINARY but that causes
+ Vista to whine */
+
+ ZERO_STRUCT( unistr_guid );
+ init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
+ UNI_STR_TERMINATE );
+
+ regval_ctr_addvalue(ctr, "objectGUID", REG_SZ,
+ (char *)unistr_guid.buffer,
+ unistr_guid.uni_max_len*2);
+
}
static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
@@ -3269,6 +3283,7 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
REGISTRY_VALUE *guid_val;
WERROR win_rc;
int i;
+ BOOL ret = False;
win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
@@ -3282,12 +3297,36 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
return False;
}
- /* fetching printer guids really ought to be a separate function.. */
- if (guid && regval_size(guid_val) == sizeof(struct GUID))
- memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
+ /* fetching printer guids really ought to be a separate function. */
+
+ if ( guid ) {
+ fstring guid_str;
+
+ /* We used to store the guid as REG_BINARY, then swapped
+ to REG_SZ for Vista compatibility so check for both */
+
+ switch ( regval_type(guid_val) ){
+ case REG_SZ:
+ rpcstr_pull( guid_str, regval_data_p(guid_val),
+ sizeof(guid_str)-1, -1, STR_TERMINATE );
+ ret = smb_string_to_uuid( guid_str, guid );
+ break;
+ case REG_BINARY:
+ if ( regval_size(guid_val) != sizeof(struct GUID) ) {
+ ret = False;
+ break;
+ }
+ memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
+ break;
+ default:
+ DEBUG(0,("is_printer_published: GUID value stored as "
+ "invaluid type (%d)\n", regval_type(guid_val) ));
+ break;
+ }
+ }
free_a_printer(&printer, 2);
- return True;
+ return ret;
}
#else
WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
@@ -3554,13 +3593,43 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
break;
}
- /* add the new value */
+ DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
+
+ /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
+ Thanks to Martin Zielinski for the hint. */
+
+ if ( type == REG_BINARY &&
+ strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
+ strequal( valuename, "objectGUID" ) )
+ {
+ struct GUID guid;
+ UNISTR2 unistr_guid;
+
+ ZERO_STRUCT( unistr_guid );
+
+ /* convert the GUID to a UNICODE string */
+
+ memcpy( &guid, data_p, sizeof(struct GUID) );
+
+ init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
+ UNI_STR_TERMINATE );
+
+ regval_ctr_addvalue( printer_data->keys[key_index].values,
+ valuename, REG_SZ,
+ (const char *)unistr_guid.buffer,
+ unistr_guid.uni_str_len*2 );
+
+ } else {
+ /* add the value */
+
+ regval_ctr_addvalue( printer_data->keys[key_index].values,
+ valuename, type, (const char *)data_p,
+ size );
+ }
- regval_ctr_addvalue( printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
- DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
}
return len;