*
* 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
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
if (type->count2 != type->count)
DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
+ if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) {
+ return False;
+ }
+
/* parse the option type data */
for(i=0;i<type->count2;i++)
if(!prs_uint16("fields",ps,depth,&type->fields[i]))
return False;
/* reading */
- if (UNMARSHALLING(ps))
+ if (UNMARSHALLING(ps) && ctr->count)
if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
return False;
if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
return False;
- if (UNMARSHALLING(ps)) {
+ if (UNMARSHALLING(ps) && data->notify_data.data.length) {
data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
data->notify_data.data.length);
case NOTIFY_POINTER:
- if (UNMARSHALLING(ps)) {
+ if (UNMARSHALLING(ps) && data->notify_data.data.length) {
data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
data->notify_data.data.length);
/* Tallocate memory for string */
- data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
- if (!data->notify_data.data.string)
- return False;
+ if (x) {
+ data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
+ if (!data->notify_data.data.string)
+ return False;
+ } else {
+ data->notify_data.data.string = NULL;
+ }
if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
return False;
BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
{
+ uint32 offset = 0;
prs_struct *ps=&buffer->prs;
prs_debug(ps, depth, desc, "smb_io_printer_info_3");
buffer->struct_start=prs_offset(ps);
- if (!prs_uint32("flags", ps, depth, &info->flags))
- return False;
+ if (MARSHALLING(ps)) {
+ /* Ensure the SD is 8 byte aligned in the buffer. */
+ uint start = prs_offset(ps); /* Remember the start position. */
+ uint off_val = 0;
+
+ /* Write a dummy value. */
+ if (!prs_uint32("offset", ps, depth, &off_val))
+ return False;
+
+ /* 8 byte align. */
+ if (!prs_align_uint64(ps))
+ return False;
+
+ /* Remember where we must seek back to write the SD. */
+ offset = prs_offset(ps);
+
+ /* Calculate the real offset for the SD. */
+
+ off_val = offset - start;
+
+ /* Seek back to where we store the SD offset & store. */
+ prs_set_offset(ps, start);
+ if (!prs_uint32("offset", ps, depth, &off_val))
+ return False;
+
+ /* Return to after the 8 byte align. */
+ prs_set_offset(ps, offset);
+
+ } else {
+ if (!prs_uint32("offset", ps, depth, &offset))
+ return False;
+ /* Seek within the buffer. */
+ if (!prs_set_offset(ps, offset))
+ return False;
+ }
if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
return False;
return True;
}
+/*******************************************************************
+ Parse a PRINTER_INFO_6 structure.
+********************************************************************/
+
+BOOL smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
+ PRINTER_INFO_6 *info, int depth)
+{
+ prs_struct *ps=&buffer->prs;
+
+ prs_debug(ps, depth, desc, "smb_io_printer_info_6");
+ depth++;
+
+ if (!prs_uint32("status", ps, depth, &info->status))
+ return False;
+
+ return True;
+}
+
/*******************************************************************
Parse a PRINTER_INFO_7 structure.
********************************************************************/
return size;
}
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+
+uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
+{
+ return sizeof(uint32);
+}
/*******************************************************************
return the size required by a struct in the stream
uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
{
- /* The 4 is for the self relative pointer.. */
- /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
- return 4 + (uint32)sec_desc_size( info->secdesc );
+ /* The 8 is for the self relative pointer - 8 byte aligned.. */
+ return 8 + (uint32)sec_desc_size( info->secdesc );
}
/*******************************************************************
}
case 3:
{
- ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
+ /* FIXME ! Our parsing here is wrong I think,
+ * but for a level3 it makes no sense for
+ * ptr_sec_desc to be NULL. JRA. Based on
+ * a Vista sniff from Martin Zielinski <mz@seh.de>.
+ */
+ if (UNMARSHALLING(ps)) {
+ ptr_sec_desc = 1;
+ } else {
+ ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
+ }
break;
}
}
prs_debug(ps, depth, "", "sec_io_desc_buf");
if (!prs_uint32("size", ps, depth + 1, &dummy))
return False;
- if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
- False;
+ if (!prs_uint32("ptr", ps, depth + 1, &dummy))
+ return False;
}
if(!prs_uint32("command", ps, depth, &q_u->command))
buf5->buf_len = len;
if (src) {
- if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
- DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
- return False;
+ if (len) {
+ if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
+ DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
+ return False;
+ }
+ } else {
+ buf5->buffer = NULL;
}
} else {
buf5->buffer=NULL;
case REG_BINARY:
case REG_DWORD:
case REG_MULTI_SZ:
- if (q_u->max_len) {
- if (UNMARSHALLING(ps))
- q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
- if(q_u->data == NULL)
- return False;
- if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
- return False;
- }
+ if (q_u->max_len) {
+ if (UNMARSHALLING(ps))
+ q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
+ if(q_u->data == NULL)
+ return False;
+ if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
+ return False;
+ }
if(!prs_align(ps))
return False;
break;
SAFE_FREE(printer);
}
+void free_printer_info_6(PRINTER_INFO_6 *printer)
+{
+ SAFE_FREE(printer);
+}
+
void free_printer_info_7(PRINTER_INFO_7 *printer)
{
SAFE_FREE(printer);
data_offset,
current_offset;
const uint32 basic_unit = 20; /* size of static portion of enum_values */
-
+
prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
depth++;
-
+
/*
* offset data begins at 20 bytes per structure * size_of_array.
* Don't forget the uint32 at the beginning
/* first loop to write basic enum_value information */
- if (UNMARSHALLING(ps)) {
+ if (UNMARSHALLING(ps) && ctr->size_of_array) {
ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
if (!ctr->values)
return False;
}
for (i=0; i<ctr->size_of_array; i++) {
+ uint32 base_offset, return_offset;
+
+ base_offset = prs_offset(ps);
+
valuename_offset = current_offset;
if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
return False;
+ /* Read or write the value. */
+
+ return_offset = prs_offset(ps);
+
+ if (!prs_set_offset(ps, base_offset + valuename_offset)) {
+ return False;
+ }
+
+ if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
+ return False;
+
+ /* And go back. */
+ if (!prs_set_offset(ps, return_offset))
+ return False;
+
if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
return False;
if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
return False;
- current_offset = data_offset + ctr->values[i].data_len - basic_unit;
- /* account for 2 byte alignment */
- current_offset += (current_offset % 2);
- }
+ /* Read or write the data. */
- /*
- * loop #2 for writing the dynamically size objects; pay
- * attention to 2-byte alignment here....
- */
-
- for (i=0; i<ctr->size_of_array; i++) {
-
- if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
+ return_offset = prs_offset(ps);
+
+ if (!prs_set_offset(ps, base_offset + data_offset)) {
return False;
-
+ }
+
if ( ctr->values[i].data_len ) {
if ( UNMARSHALLING(ps) ) {
ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
return False;
}
-
- if ( !prs_align_uint16(ps) )
+
+ current_offset = data_offset + ctr->values[i].data_len - basic_unit;
+ /* account for 2 byte alignment */
+ current_offset += (current_offset % 2);
+
+ /* Remember how far we got. */
+ data_offset = prs_offset(ps);
+
+ /* And go back. */
+ if (!prs_set_offset(ps, return_offset))
return False;
+
}
+ /* Go to the last data offset we got to. */
+
+ if (!prs_set_offset(ps, data_offset))
+ return False;
+
+ /* And ensure we're 2 byte aligned. */
+
+ if ( !prs_align_uint16(ps) )
+ return False;
+
return True;
}