rpc_parse/parse_spoolss.c

説明を見る。
00001 /* 
00002  *  Unix SMB/CIFS implementation.
00003  *  RPC Pipe client / server routines
00004  *  Copyright (C) Andrew Tridgell              1992-2000,
00005  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
00006  *  Copyright (C) Jean Fran巽ois Micouleau      1998-2000,
00007  *  Copyright (C) Gerald Carter                2000-2002,
00008  *  Copyright (C) Tim Potter                   2001-2002.
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *  
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *  
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023  */
00024 
00025 #include "includes.h"
00026 
00027 #undef DBGC_CLASS
00028 #define DBGC_CLASS DBGC_RPC_PARSE
00029 
00030 
00031 /*******************************************************************
00032 This should be moved in a more generic lib.
00033 ********************************************************************/  
00034 
00035 BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
00036 {
00037         if(!prs_uint16("year", ps, depth, &systime->year))
00038                 return False;
00039         if(!prs_uint16("month", ps, depth, &systime->month))
00040                 return False;
00041         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
00042                 return False;
00043         if(!prs_uint16("day", ps, depth, &systime->day))
00044                 return False;
00045         if(!prs_uint16("hour", ps, depth, &systime->hour))
00046                 return False;
00047         if(!prs_uint16("minute", ps, depth, &systime->minute))
00048                 return False;
00049         if(!prs_uint16("second", ps, depth, &systime->second))
00050                 return False;
00051         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
00052                 return False;
00053 
00054         return True;
00055 }
00056 
00057 /*******************************************************************
00058 ********************************************************************/  
00059 
00060 BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
00061 {
00062         systime->year=unixtime->tm_year+1900;
00063         systime->month=unixtime->tm_mon+1;
00064         systime->dayofweek=unixtime->tm_wday;
00065         systime->day=unixtime->tm_mday;
00066         systime->hour=unixtime->tm_hour;
00067         systime->minute=unixtime->tm_min;
00068         systime->second=unixtime->tm_sec;
00069         systime->milliseconds=0;
00070 
00071         return True;
00072 }
00073 
00074 /*******************************************************************
00075 reads or writes an DOC_INFO structure.
00076 ********************************************************************/  
00077 
00078 static BOOL smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
00079 {
00080         if (info_1 == NULL) return False;
00081 
00082         prs_debug(ps, depth, desc, "smb_io_doc_info_1");
00083         depth++;
00084  
00085         if(!prs_align(ps))
00086                 return False;
00087         
00088         if(!prs_uint32("p_docname",    ps, depth, &info_1->p_docname))
00089                 return False;
00090         if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
00091                 return False;
00092         if(!prs_uint32("p_datatype",   ps, depth, &info_1->p_datatype))
00093                 return False;
00094 
00095         if(!smb_io_unistr2("", &info_1->docname,    info_1->p_docname,    ps, depth))
00096                 return False;
00097         if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
00098                 return False;
00099         if(!smb_io_unistr2("", &info_1->datatype,   info_1->p_datatype,   ps, depth))
00100                 return False;
00101 
00102         return True;
00103 }
00104 
00105 /*******************************************************************
00106 reads or writes an DOC_INFO structure.
00107 ********************************************************************/  
00108 
00109 static BOOL smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
00110 {
00111         uint32 useless_ptr=0;
00112         
00113         if (info == NULL) return False;
00114 
00115         prs_debug(ps, depth, desc, "smb_io_doc_info");
00116         depth++;
00117  
00118         if(!prs_align(ps))
00119                 return False;
00120         
00121         if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
00122                 return False;
00123         
00124         if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
00125                 return False;
00126 
00127         switch (info->switch_value)
00128         {
00129                 case 1: 
00130                         if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
00131                                 return False;
00132                         break;
00133                 case 2:
00134                         /*
00135                           this is just a placeholder
00136                           
00137                           MSDN July 1998 says doc_info_2 is only on
00138                           Windows 95, and as Win95 doesn't do RPC to print
00139                           this case is nearly impossible
00140                           
00141                           Maybe one day with Windows for dishwasher 2037 ...
00142                           
00143                         */
00144                         /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
00145                         break;
00146                 default:
00147                         DEBUG(0,("Something is obviously wrong somewhere !\n"));
00148                         break;
00149         }
00150 
00151         return True;
00152 }
00153 
00154 /*******************************************************************
00155 reads or writes an DOC_INFO_CONTAINER structure.
00156 ********************************************************************/  
00157 
00158 static BOOL smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
00159 {
00160         if (cont == NULL) return False;
00161 
00162         prs_debug(ps, depth, desc, "smb_io_doc_info_container");
00163         depth++;
00164  
00165         if(!prs_align(ps))
00166                 return False;
00167         
00168         if(!prs_uint32("level", ps, depth, &cont->level))
00169                 return False;
00170         
00171         if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
00172                 return False;
00173 
00174         return True;
00175 }
00176 
00177 /*******************************************************************
00178 reads or writes an NOTIFY OPTION TYPE structure.
00179 ********************************************************************/  
00180 
00181 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
00182    structure.  The _TYPE structure is really the deferred referrants (i.e
00183    the notify fields array) of the _TYPE structure. -tpot */
00184 
00185 static BOOL smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
00186 {
00187         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
00188         depth++;
00189  
00190         if (!prs_align(ps))
00191                 return False;
00192 
00193         if(!prs_uint16("type", ps, depth, &type->type))
00194                 return False;
00195         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
00196                 return False;
00197         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
00198                 return False;
00199         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
00200                 return False;
00201         if(!prs_uint32("count", ps, depth, &type->count))
00202                 return False;
00203         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
00204                 return False;
00205 
00206         return True;
00207 }
00208 
00209 /*******************************************************************
00210 reads or writes an NOTIFY OPTION TYPE DATA.
00211 ********************************************************************/  
00212 
00213 static BOOL smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
00214 {
00215         int i;
00216 
00217         prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
00218         depth++;
00219  
00220         /* if there are no fields just return */
00221         if (type->fields_ptr==0)
00222                 return True;
00223 
00224         if(!prs_align(ps))
00225                 return False;
00226 
00227         if(!prs_uint32("count2", ps, depth, &type->count2))
00228                 return False;
00229         
00230         if (type->count2 != type->count)
00231                 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
00232 
00233         if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) {
00234                 return False;
00235         }
00236 
00237         /* parse the option type data */
00238         for(i=0;i<type->count2;i++)
00239                 if(!prs_uint16("fields",ps,depth,&type->fields[i]))
00240                         return False;
00241         return True;
00242 }
00243 
00244 /*******************************************************************
00245 reads or writes an NOTIFY OPTION structure.
00246 ********************************************************************/  
00247 
00248 static BOOL smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
00249 {               
00250         int i;
00251         
00252         prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
00253         depth++;
00254  
00255         if(!prs_uint32("count", ps, depth, &ctr->count))
00256                 return False;
00257 
00258         /* reading */
00259         if (UNMARSHALLING(ps) && ctr->count)
00260                 if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
00261                         return False;
00262                 
00263         /* the option type struct */
00264         for(i=0;i<ctr->count;i++)
00265                 if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
00266                         return False;
00267 
00268         /* the type associated with the option type struct */
00269         for(i=0;i<ctr->count;i++)
00270                 if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
00271                         return False;
00272         
00273         return True;
00274 }
00275 
00276 /*******************************************************************
00277 reads or writes an NOTIFY OPTION structure.
00278 ********************************************************************/  
00279 
00280 static BOOL smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
00281 {
00282         prs_debug(ps, depth, desc, "smb_io_notify_option");
00283         depth++;
00284         
00285         if(!prs_uint32("version", ps, depth, &option->version))
00286                 return False;
00287         if(!prs_uint32("flags", ps, depth, &option->flags))
00288                 return False;
00289         if(!prs_uint32("count", ps, depth, &option->count))
00290                 return False;
00291         if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
00292                 return False;
00293         
00294         /* marshalling or unmarshalling, that would work */     
00295         if (option->option_type_ptr!=0) {
00296                 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
00297                         return False;
00298         }
00299         else {
00300                 option->ctr.type=NULL;
00301                 option->ctr.count=0;
00302         }
00303         
00304         return True;
00305 }
00306 
00307 /*******************************************************************
00308 reads or writes an NOTIFY INFO DATA structure.
00309 ********************************************************************/  
00310 
00311 static BOOL smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
00312 {
00313         uint32 useless_ptr=0x0FF0ADDE;
00314 
00315         prs_debug(ps, depth, desc, "smb_io_notify_info_data");
00316         depth++;
00317 
00318         if(!prs_align(ps))
00319                 return False;
00320         if(!prs_uint16("type",           ps, depth, &data->type))
00321                 return False;
00322         if(!prs_uint16("field",          ps, depth, &data->field))
00323                 return False;
00324 
00325         if(!prs_uint32("how many words", ps, depth, &data->size))
00326                 return False;
00327         if(!prs_uint32("id",             ps, depth, &data->id))
00328                 return False;
00329         if(!prs_uint32("how many words", ps, depth, &data->size))
00330                 return False;
00331 
00332         switch (data->enc_type) {
00333 
00334                 /* One and two value data has two uint32 values */
00335 
00336         case NOTIFY_ONE_VALUE:
00337         case NOTIFY_TWO_VALUE:
00338 
00339                 if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
00340                         return False;
00341                 if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
00342                         return False;
00343                 break;
00344 
00345                 /* Pointers and strings have a string length and a
00346                    pointer.  For a string the length is expressed as
00347                    the number of uint16 characters plus a trailing
00348                    \0\0. */
00349 
00350         case NOTIFY_POINTER:
00351 
00352                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
00353                         return False;
00354                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
00355                         return False;
00356 
00357                 break;
00358 
00359         case NOTIFY_STRING:
00360 
00361                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
00362                         return False;
00363 
00364                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
00365                         return False;
00366 
00367                 break;
00368 
00369         case NOTIFY_SECDESC:
00370                 if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
00371                         return False;
00372                 if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
00373                         return False;
00374                 
00375                 break;
00376 
00377         default:
00378                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
00379                           data->enc_type));
00380                 break;
00381         }
00382 
00383         return True;
00384 }
00385 
00386 /*******************************************************************
00387 reads or writes an NOTIFY INFO DATA structure.
00388 ********************************************************************/  
00389 
00390 BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
00391                                      prs_struct *ps, int depth)
00392 {
00393         prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
00394         depth++;
00395         
00396         if(!prs_align(ps))
00397                 return False;
00398 
00399         switch(data->enc_type) {
00400 
00401                 /* No data for values */
00402 
00403         case NOTIFY_ONE_VALUE:
00404         case NOTIFY_TWO_VALUE:
00405 
00406                 break;
00407 
00408                 /* Strings start with a length in uint16s */
00409 
00410         case NOTIFY_STRING:
00411 
00412                 if (MARSHALLING(ps))
00413                         data->notify_data.data.length /= 2;
00414 
00415                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
00416                         return False;
00417 
00418                 if (UNMARSHALLING(ps) && data->notify_data.data.length) {
00419                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
00420                                                                 data->notify_data.data.length);
00421 
00422                         if (!data->notify_data.data.string) 
00423                                 return False;
00424                 }
00425 
00426                 if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
00427                                    data->notify_data.data.length))
00428                         return False;
00429 
00430                 if (MARSHALLING(ps))
00431                         data->notify_data.data.length *= 2;
00432 
00433                 break;
00434 
00435         case NOTIFY_POINTER:
00436 
00437                 if (UNMARSHALLING(ps) && data->notify_data.data.length) {
00438                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
00439                                                                 data->notify_data.data.length);
00440 
00441                         if (!data->notify_data.data.string) 
00442                                 return False;
00443                 }
00444 
00445                 if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
00446                         return False;
00447 
00448                 break;
00449 
00450         case NOTIFY_SECDESC:    
00451                 if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
00452                         return False;
00453                 if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
00454                         return False;
00455                 break;
00456 
00457         default:
00458                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
00459                           data->enc_type));
00460                 break;
00461         }
00462 
00463 #if 0
00464         if (isvalue==False) {
00465 
00466                 /* length of string in unicode include \0 */
00467                 x=data->notify_data.data.length+1;
00468 
00469                 if (data->field != 16)
00470                 if(!prs_uint32("string length", ps, depth, &x ))
00471                         return False;
00472 
00473                 if (MARSHALLING(ps)) {
00474                         /* These are already in little endian format. Don't byte swap. */
00475                         if (x == 1) {
00476 
00477                                 /* No memory allocated for this string
00478                                    therefore following the data.string
00479                                    pointer is a bad idea.  Use a pointer to
00480                                    the uint32 length union member to
00481                                    provide a source for a unicode NULL */
00482 
00483                                 if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) 
00484                                         return False;
00485                         } else {
00486 
00487                                 if (data->field == 16)
00488                                         x /= 2;
00489 
00490                                 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
00491                                         return False;
00492                         }
00493                 } else {
00494 
00495                         /* Tallocate memory for string */
00496 
00497                         if (x) {
00498                                 data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
00499                                 if (!data->notify_data.data.string) 
00500                                         return False;
00501                         } else {
00502                                 data->notify_data.data.string = NULL;
00503                         }
00504 
00505                         if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
00506                                 return False;
00507                 }
00508         }
00509 
00510 #endif
00511 
00512 #if 0   /* JERRY */
00513         /* Win2k does not seem to put this parse align here */
00514         if(!prs_align(ps))
00515                 return False;
00516 #endif
00517 
00518         return True;
00519 }
00520 
00521 /*******************************************************************
00522 reads or writes an NOTIFY INFO structure.
00523 ********************************************************************/  
00524 
00525 static BOOL smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
00526 {
00527         int i;
00528 
00529         prs_debug(ps, depth, desc, "smb_io_notify_info");
00530         depth++;
00531  
00532         if(!prs_align(ps))
00533                 return False;
00534 
00535         if(!prs_uint32("count", ps, depth, &info->count))
00536                 return False;
00537         if(!prs_uint32("version", ps, depth, &info->version))
00538                 return False;
00539         if(!prs_uint32("flags", ps, depth, &info->flags))
00540                 return False;
00541         if(!prs_uint32("count", ps, depth, &info->count))
00542                 return False;
00543 
00544         for (i=0;i<info->count;i++) {
00545                 if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
00546                         return False;
00547         }
00548 
00549         /* now do the strings at the end of the stream */       
00550         for (i=0;i<info->count;i++) {
00551                 if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
00552                         return False;
00553         }
00554 
00555         return True;
00556 }
00557 
00558 /*******************************************************************
00559 ********************************************************************/  
00560 
00561 BOOL spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
00562 {
00563         prs_debug(ps, depth, desc, "");
00564         depth++;
00565 
00566         if (!prs_align(ps))
00567                 return False;
00568 
00569         if (!prs_uint32("size", ps, depth, &q_u->size))
00570                 return False;
00571 
00572         if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
00573                 return False;
00574         if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
00575                 return False;
00576 
00577         if (!prs_uint32("build", ps, depth, &q_u->build))
00578                 return False;
00579         if (!prs_uint32("major", ps, depth, &q_u->major))
00580                 return False;
00581         if (!prs_uint32("minor", ps, depth, &q_u->minor))
00582                 return False;
00583         if (!prs_uint32("processor", ps, depth, &q_u->processor))
00584                 return False;
00585 
00586         if (!prs_io_unistr2("", ps, depth, q_u->client_name))
00587                 return False;
00588         if (!prs_align(ps))
00589                 return False;
00590 
00591         if (!prs_io_unistr2("", ps, depth, q_u->user_name))
00592                 return False;
00593 
00594         return True;
00595 }
00596 
00597 /*******************************************************************
00598 ********************************************************************/  
00599 
00600 static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
00601 {
00602         if (q_u==NULL)
00603                 return False;
00604 
00605         prs_debug(ps, depth, desc, "spool_io_user_level");
00606         depth++;
00607 
00608         if (!prs_align(ps))
00609                 return False;
00610 
00611         if (!prs_uint32("level", ps, depth, &q_u->level))
00612                 return False;
00613         
00614         switch ( q_u->level ) 
00615         {       
00616                 case 1:
00617                         if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, 
00618                                 sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
00619                         {
00620                                 return False;
00621                         }
00622                         break;
00623                 default:
00624                         return False;   
00625         }       
00626 
00627         return True;
00628 }
00629 
00630 /*******************************************************************
00631  * read or write a DEVICEMODE struct.
00632  * on reading allocate memory for the private member
00633  ********************************************************************/
00634 
00635 #define DM_NUM_OPTIONAL_FIELDS          8
00636 
00637 BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
00638 {
00639         int available_space;            /* size of the device mode left to parse */
00640                                         /* only important on unmarshalling       */
00641         int i = 0;
00642         uint16 *unistr_buffer;
00643         int j;
00644                                         
00645         struct optional_fields {
00646                 fstring         name;
00647                 uint32*         field;
00648         } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
00649                 { "icmmethod",          NULL },
00650                 { "icmintent",          NULL },
00651                 { "mediatype",          NULL },
00652                 { "dithertype",         NULL },
00653                 { "reserved1",          NULL },
00654                 { "reserved2",          NULL },
00655                 { "panningwidth",       NULL },
00656                 { "panningheight",      NULL }
00657         };
00658 
00659         /* assign at run time to keep non-gcc compilers happy */
00660 
00661         opt_fields[0].field = &devmode->icmmethod;
00662         opt_fields[1].field = &devmode->icmintent;
00663         opt_fields[2].field = &devmode->mediatype;
00664         opt_fields[3].field = &devmode->dithertype;
00665         opt_fields[4].field = &devmode->reserved1;
00666         opt_fields[5].field = &devmode->reserved2;
00667         opt_fields[6].field = &devmode->panningwidth;
00668         opt_fields[7].field = &devmode->panningheight;
00669                 
00670         
00671         prs_debug(ps, depth, desc, "spoolss_io_devmode");
00672         depth++;
00673 
00674         if (UNMARSHALLING(ps)) {
00675                 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
00676                 if (devmode->devicename.buffer == NULL)
00677                         return False;
00678                 unistr_buffer = devmode->devicename.buffer;
00679         }
00680         else {
00681                 /* devicename is a static sized string but the buffer we set is not */
00682                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
00683                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
00684                 for ( j=0; devmode->devicename.buffer[j]; j++ )
00685                         unistr_buffer[j] = devmode->devicename.buffer[j];
00686         }
00687                 
00688         if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
00689                 return False;
00690         
00691         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
00692                 return False;
00693                 
00694         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
00695                 return False;
00696         if (!prs_uint16("size",             ps, depth, &devmode->size))
00697                 return False;
00698         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
00699                 return False;
00700         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
00701                 return False;
00702         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
00703                 return False;
00704         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
00705                 return False;
00706         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
00707                 return False;
00708         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
00709                 return False;
00710         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
00711                 return False;
00712         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
00713                 return False;
00714         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
00715                 return False;
00716         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
00717                 return False;
00718         if (!prs_uint16("color",            ps, depth, &devmode->color))
00719                 return False;
00720         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
00721                 return False;
00722         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
00723                 return False;
00724         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
00725                 return False;
00726         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
00727                 return False;
00728 
00729         if (UNMARSHALLING(ps)) {
00730                 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
00731                 if (devmode->formname.buffer == NULL)
00732                         return False;
00733                 unistr_buffer = devmode->formname.buffer;
00734         }
00735         else {
00736                 /* devicename is a static sized string but the buffer we set is not */
00737                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
00738                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
00739                 for ( j=0; devmode->formname.buffer[j]; j++ )
00740                         unistr_buffer[j] = devmode->formname.buffer[j];
00741         }
00742         
00743         if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
00744                 return False;
00745         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
00746                 return False;
00747         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
00748                 return False;
00749         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
00750                 return False;
00751         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
00752                 return False;
00753         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
00754                 return False;
00755         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
00756                 return False;
00757         /* 
00758          * every device mode I've ever seen on the wire at least has up 
00759          * to the displayfrequency field.   --jerry (05-09-2002)
00760          */
00761          
00762         /* add uint32's + uint16's + two UNICODE strings */
00763          
00764         available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
00765         
00766         /* Sanity check - we only have uint32's left tp parse */
00767         
00768         if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
00769                 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
00770                         available_space, devmode->size));
00771                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
00772                 return False;
00773         }
00774 
00775         /* 
00776          * Conditional parsing.  Assume that the DeviceMode has been 
00777          * zero'd by the caller. 
00778          */
00779         
00780         while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
00781         {
00782                 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
00783                 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
00784                         return False;
00785                 available_space -= sizeof(uint32);
00786                 i++;
00787         }        
00788         
00789         /* Sanity Check - we should no available space at this point unless 
00790            MS changes the device mode structure */
00791                 
00792         if (available_space) {
00793                 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
00794                 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
00795                         available_space, devmode->size));
00796                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
00797                 return False;
00798         }
00799 
00800 
00801         if (devmode->driverextra!=0) {
00802                 if (UNMARSHALLING(ps)) {
00803                         devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
00804                         if(devmode->dev_private == NULL)
00805                                 return False;
00806                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
00807                 }
00808                         
00809                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
00810                 if (!prs_uint8s(False, "dev_private",  ps, depth,
00811                                 devmode->dev_private, devmode->driverextra))
00812                         return False;
00813         }
00814 
00815         return True;
00816 }
00817 
00818 /*******************************************************************
00819  Read or write a DEVICEMODE container
00820 ********************************************************************/  
00821 
00822 static BOOL spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
00823 {
00824         if (dm_c==NULL)
00825                 return False;
00826 
00827         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
00828         depth++;
00829 
00830         if(!prs_align(ps))
00831                 return False;
00832         
00833         if (!prs_uint32("size", ps, depth, &dm_c->size))
00834                 return False;
00835 
00836         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
00837                 return False;
00838 
00839         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
00840                 if (UNMARSHALLING(ps))
00841                         /* if while reading there is no DEVMODE ... */
00842                         dm_c->devmode=NULL;
00843                 return True;
00844         }
00845         
00846         /* so we have a DEVICEMODE to follow */         
00847         if (UNMARSHALLING(ps)) {
00848                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
00849                 dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
00850                 if(dm_c->devmode == NULL)
00851                         return False;
00852         }
00853         
00854         /* this is bad code, shouldn't be there */
00855         if (!prs_uint32("size", ps, depth, &dm_c->size))
00856                 return False;
00857                 
00858         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
00859                 return False;
00860 
00861         return True;
00862 }
00863 
00864 /*******************************************************************
00865 ********************************************************************/  
00866 
00867 static BOOL spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
00868 {
00869         if (pd==NULL)
00870                 return False;
00871 
00872         prs_debug(ps, depth, desc, "spoolss_io_printer_default");
00873         depth++;
00874 
00875         if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
00876                 return False;
00877 
00878         if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
00879                 return False;
00880         
00881         if (!prs_align(ps))
00882                 return False;
00883 
00884         if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
00885                 return False;
00886 
00887         if (!prs_align(ps))
00888                 return False;
00889 
00890         if (!prs_uint32("access_required", ps, depth, &pd->access_required))
00891                 return False;
00892 
00893         return True;
00894 }
00895 
00896 /*******************************************************************
00897  * init a structure.
00898  ********************************************************************/
00899 
00900 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
00901                 const fstring printername, 
00902                 const fstring datatype, 
00903                 uint32 access_required,
00904                 const fstring clientname,
00905                 const fstring user_name)
00906 {
00907         DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
00908 
00909         q_u->printername = TALLOC_P( get_talloc_ctx(), UNISTR2 );
00910         if (!q_u->printername) {
00911                 return False;
00912         }
00913         init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
00914 
00915         q_u->printer_default.datatype_ptr = 0;
00916 
00917         q_u->printer_default.devmode_cont.size=0;
00918         q_u->printer_default.devmode_cont.devmode_ptr=0;
00919         q_u->printer_default.devmode_cont.devmode=NULL;
00920         q_u->printer_default.access_required=access_required;
00921 
00922         q_u->user_switch = 1;
00923         
00924         q_u->user_ctr.level                 = 1;
00925         q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
00926         if (!q_u->user_ctr.user.user1) {
00927                 return False;
00928         }
00929         q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
00930         q_u->user_ctr.user.user1->build     = 1381;
00931         q_u->user_ctr.user.user1->major     = 2;
00932         q_u->user_ctr.user.user1->minor     = 0;
00933         q_u->user_ctr.user.user1->processor = 0;
00934 
00935         q_u->user_ctr.user.user1->client_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
00936         if (!q_u->user_ctr.user.user1->client_name) {
00937                 return False;
00938         }
00939         q_u->user_ctr.user.user1->user_name   = TALLOC_P( get_talloc_ctx(), UNISTR2 );
00940         if (!q_u->user_ctr.user.user1->user_name) {
00941                 return False;
00942         }
00943 
00944         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
00945         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
00946         
00947         return True;
00948 }
00949 
00950 /*******************************************************************
00951  * init a structure.
00952  ********************************************************************/
00953 
00954 BOOL make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
00955         const char *srv_name, const char* clientname, const char* user_name,
00956         uint32 level, PRINTER_INFO_CTR *ctr)
00957 {
00958         DEBUG(5,("make_spoolss_q_addprinterex\n"));
00959         
00960         if (!ctr || !ctr->printers_2) 
00961                 return False;
00962 
00963         ZERO_STRUCTP(q_u);
00964 
00965         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
00966         if (!q_u->server_name) {
00967                 return False;
00968         }
00969         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
00970 
00971         q_u->level = level;
00972         
00973         q_u->info.level = level;
00974         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
00975         switch (level) {
00976                 case 2:
00977                         /* init q_u->info.info2 from *info */
00978                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
00979                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
00980                                 return False;
00981                         }
00982                         break;
00983                 default :
00984                         break;
00985         }
00986 
00987         q_u->user_switch=1;
00988 
00989         q_u->user_ctr.level                 = 1;
00990         q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
00991         if (!q_u->user_ctr.user.user1) {
00992                 return False;
00993         }
00994         q_u->user_ctr.user.user1->build     = 1381;
00995         q_u->user_ctr.user.user1->major     = 2; 
00996         q_u->user_ctr.user.user1->minor     = 0;
00997         q_u->user_ctr.user.user1->processor = 0;
00998 
00999         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
01000         if (!q_u->user_ctr.user.user1->client_name) {
01001                 return False;
01002         }
01003         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
01004         if (!q_u->user_ctr.user.user1->user_name) {
01005                 return False;
01006         }
01007         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
01008         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
01009 
01010         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
01011                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
01012         
01013         return True;
01014 }
01015         
01016 /*******************************************************************
01017 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
01018 *******************************************************************/
01019 
01020 BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
01021                                 PRINTER_INFO_2 *info)
01022 {
01023 
01024         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
01025 
01026         /* allocate the necessary memory */
01027         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
01028                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
01029                 return False;
01030         }
01031         
01032         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
01033         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
01034         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
01035         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
01036         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
01037         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
01038         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
01039         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
01040         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
01041         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
01042         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
01043         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
01044         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
01045         inf->attributes         = info->attributes;
01046         inf->priority           = info->priority;
01047         inf->default_priority   = info->defaultpriority;
01048         inf->starttime          = info->starttime;
01049         inf->untiltime          = info->untiltime;
01050         inf->cjobs              = info->cjobs;
01051         inf->averageppm = info->averageppm;
01052         init_unistr2_from_unistr(&inf->servername,      &info->servername);
01053         init_unistr2_from_unistr(&inf->printername,     &info->printername);
01054         init_unistr2_from_unistr(&inf->sharename,       &info->sharename);
01055         init_unistr2_from_unistr(&inf->portname,        &info->portname);
01056         init_unistr2_from_unistr(&inf->drivername,      &info->drivername);
01057         init_unistr2_from_unistr(&inf->comment,         &info->comment);
01058         init_unistr2_from_unistr(&inf->location,        &info->location);
01059         init_unistr2_from_unistr(&inf->sepfile,         &info->sepfile);
01060         init_unistr2_from_unistr(&inf->printprocessor,  &info->printprocessor);
01061         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
01062         init_unistr2_from_unistr(&inf->parameters,      &info->parameters);
01063         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
01064 
01065         *spool_info2 = inf;
01066 
01067         return True;
01068 }
01069 
01070 /*******************************************************************
01071 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
01072 *******************************************************************/
01073 
01074 BOOL make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
01075                                 PRINTER_INFO_3 *info)
01076 {
01077 
01078         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
01079 
01080         /* allocate the necessary memory */
01081         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
01082                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
01083                 return False;
01084         }
01085         
01086         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
01087 
01088         *spool_info3 = inf;
01089 
01090         return True;
01091 }
01092 
01093 /*******************************************************************
01094 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
01095 *******************************************************************/
01096 
01097 BOOL make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
01098                                 PRINTER_INFO_7 *info)
01099 {
01100 
01101         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
01102 
01103         /* allocate the necessary memory */
01104         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
01105                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
01106                 return False;
01107         }
01108 
01109         inf->guid_ptr           = (info->guid.buffer!=NULL)?1:0;
01110         inf->action             = info->action;
01111         init_unistr2_from_unistr(&inf->guid,            &info->guid);
01112 
01113         *spool_info7 = inf;
01114 
01115         return True;
01116 }
01117 
01118 
01119 /*******************************************************************
01120  * read a structure.
01121  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
01122  ********************************************************************/
01123 
01124 BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
01125 {
01126         if (q_u == NULL)
01127                 return False;
01128 
01129         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
01130         depth++;
01131 
01132         if (!prs_align(ps))
01133                 return False;
01134 
01135         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
01136                 return False;
01137         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
01138                 return False;
01139         
01140         if (!prs_align(ps))
01141                 return False;
01142 
01143         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
01144                 return False;
01145                 
01146         return True;
01147 }
01148 
01149 /*******************************************************************
01150  * write a structure.
01151  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
01152  * called from spoolss_open_printer_ex (cli_spoolss.c)
01153  ********************************************************************/
01154 
01155 BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
01156 {
01157         if (r_u == NULL) return False;
01158 
01159         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
01160         depth++;
01161         
01162         if (!prs_align(ps))
01163                 return False;
01164 
01165         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
01166                 return False;   
01167 
01168         if (!prs_werror("status code", ps, depth, &(r_u->status)))
01169                 return False;
01170                 
01171         return True;
01172 }
01173 
01174 
01175 /*******************************************************************
01176  * read a structure.
01177  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
01178  ********************************************************************/
01179 
01180 BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
01181 {
01182         if (q_u == NULL)
01183                 return False;
01184 
01185         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
01186         depth++;
01187 
01188         if (!prs_align(ps))
01189                 return False;
01190 
01191         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
01192                 return False;
01193         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
01194                 return False;
01195         
01196         if (!prs_align(ps))
01197                 return False;
01198 
01199         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
01200                 return False;
01201 
01202         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
01203                 return False;   
01204         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
01205                 return False;
01206         
01207         return True;
01208 }
01209 
01210 /*******************************************************************
01211  * write a structure.
01212  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
01213  * called from spoolss_open_printer_ex (cli_spoolss.c)
01214  ********************************************************************/
01215 
01216 BOOL spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
01217 {
01218         if (r_u == NULL) return False;
01219 
01220         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
01221         depth++;
01222         
01223         if (!prs_align(ps))
01224                 return False;
01225 
01226         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
01227                 return False;
01228 
01229         if (!prs_werror("status code", ps, depth, &(r_u->status)))
01230                 return False;
01231 
01232         return True;
01233 }
01234 
01235 /*******************************************************************
01236  * init a structure.
01237  ********************************************************************/
01238 BOOL make_spoolss_q_deleteprinterdriverex( TALLOC_CTX *mem_ctx,
01239                                            SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, 
01240                                            const char *server,
01241                                            const char* arch, 
01242                                            const char* driver,
01243                                            int version)
01244 {
01245         DEBUG(5,("make_spoolss_q_deleteprinterdriverex\n"));
01246  
01247         q_u->server_ptr = (server!=NULL)?1:0;
01248         q_u->delete_flags = DPD_DELETE_UNUSED_FILES;
01249  
01250         /* these must be NULL terminated or else NT4 will
01251            complain about invalid parameters --jerry */
01252         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
01253         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
01254         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
01255 
01256         if (version >= 0) { 
01257                 q_u->delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
01258                 q_u->version = version;
01259         }
01260 
01261         return True;
01262 }
01263 
01264 
01265 /*******************************************************************
01266  * init a structure.
01267  ********************************************************************/
01268 BOOL make_spoolss_q_deleteprinterdriver(
01269         TALLOC_CTX *mem_ctx,
01270         SPOOL_Q_DELETEPRINTERDRIVER *q_u, 
01271         const char *server,
01272         const char* arch, 
01273         const char* driver 
01274 )
01275 {
01276         DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
01277         
01278         q_u->server_ptr = (server!=NULL)?1:0;
01279 
01280         /* these must be NULL terminated or else NT4 will
01281            complain about invalid parameters --jerry */
01282         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
01283         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
01284         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
01285         
01286         return True;
01287 }
01288 
01289 /*******************************************************************
01290  * make a structure.
01291  ********************************************************************/
01292 
01293 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
01294                                    const POLICY_HND *handle,
01295                                    const char *valuename, uint32 size)
01296 {
01297         if (q_u == NULL) return False;
01298 
01299         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
01300 
01301         q_u->handle = *handle;
01302         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
01303         q_u->size = size;
01304 
01305         return True;
01306 }
01307 
01308 /*******************************************************************
01309  * make a structure.
01310  ********************************************************************/
01311 
01312 BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
01313                                      const POLICY_HND *handle,
01314                                      const char *keyname, 
01315                                      const char *valuename, uint32 size)
01316 {
01317         if (q_u == NULL) return False;
01318 
01319         DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
01320 
01321         q_u->handle = *handle;
01322         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
01323         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
01324         q_u->size = size;
01325 
01326         return True;
01327 }
01328 
01329 /*******************************************************************
01330  * read a structure.
01331  * called from spoolss_q_getprinterdata (srv_spoolss.c)
01332  ********************************************************************/
01333 
01334 BOOL spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
01335 {
01336         if (q_u == NULL)
01337                 return False;
01338 
01339         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
01340         depth++;
01341 
01342         if (!prs_align(ps))
01343                 return False;
01344         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01345                 return False;
01346         if (!prs_align(ps))
01347                 return False;
01348         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
01349                 return False;
01350         if (!prs_align(ps))
01351                 return False;
01352         if (!prs_uint32("size", ps, depth, &q_u->size))
01353                 return False;
01354 
01355         return True;
01356 }
01357 
01358 /*******************************************************************
01359  * read a structure.
01360  * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
01361  ********************************************************************/
01362 
01363 BOOL spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
01364 {
01365         if (q_u == NULL)
01366                 return False;
01367 
01368         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
01369         depth++;
01370 
01371         if (!prs_align(ps))
01372                 return False;
01373         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01374                 return False;
01375         if (!prs_align(ps))
01376                 return False;
01377         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
01378                 return False;
01379 
01380         return True;
01381 }
01382 
01383 /*******************************************************************
01384  * write a structure.
01385  * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
01386  ********************************************************************/
01387 
01388 BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
01389 {
01390         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
01391         depth++;
01392         if(!prs_werror("status", ps, depth, &r_u->status))
01393                 return False;
01394 
01395         return True;
01396 }
01397 
01398 /*******************************************************************
01399  * read a structure.
01400  * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
01401  ********************************************************************/
01402 
01403 BOOL spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
01404 {
01405         if (q_u == NULL)
01406                 return False;
01407 
01408         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
01409         depth++;
01410 
01411         if (!prs_align(ps))
01412                 return False;
01413         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
01414                 return False;
01415         
01416         if (!smb_io_unistr2("keyname  ", &q_u->keyname, True, ps, depth))
01417                 return False;
01418         if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
01419                 return False;
01420 
01421         return True;
01422 }
01423 
01424 /*******************************************************************
01425  * write a structure.
01426  * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
01427  ********************************************************************/
01428 
01429 BOOL spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
01430 {
01431         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
01432         depth++;
01433         
01434         if(!prs_werror("status", ps, depth, &r_u->status))
01435                 return False;
01436 
01437         return True;
01438 }
01439 
01440 /*******************************************************************
01441  * write a structure.
01442  * called from spoolss_r_getprinterdata (srv_spoolss.c)
01443  ********************************************************************/
01444 
01445 BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
01446 {
01447         if (r_u == NULL)
01448                 return False;
01449 
01450         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
01451         depth++;
01452 
01453         if (!prs_align(ps))
01454                 return False;
01455         if (!prs_uint32("type", ps, depth, &r_u->type))
01456                 return False;
01457         if (!prs_uint32("size", ps, depth, &r_u->size))
01458                 return False;
01459         
01460         if (UNMARSHALLING(ps) && r_u->size) {
01461                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
01462                 if(!r_u->data)
01463                         return False;
01464         }
01465 
01466         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
01467                 return False;
01468                 
01469         if (!prs_align(ps))
01470                 return False;
01471         
01472         if (!prs_uint32("needed", ps, depth, &r_u->needed))
01473                 return False;
01474         if (!prs_werror("status", ps, depth, &r_u->status))
01475                 return False;
01476                 
01477         return True;
01478 }
01479 
01480 /*******************************************************************
01481  * make a structure.
01482  ********************************************************************/
01483 
01484 BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
01485 {
01486         if (q_u == NULL) return False;
01487 
01488         DEBUG(5,("make_spoolss_q_closeprinter\n"));
01489 
01490         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
01491 
01492         return True;
01493 }
01494 
01495 /*******************************************************************
01496  * read a structure.
01497  * called from static spoolss_q_abortprinter (srv_spoolss.c)
01498  * called from spoolss_abortprinter (cli_spoolss.c)
01499  ********************************************************************/
01500 
01501 BOOL spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
01502 {
01503         if (q_u == NULL) return False;
01504 
01505         prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
01506         depth++;
01507 
01508         if (!prs_align(ps))
01509                 return False;
01510 
01511         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01512                 return False;
01513 
01514         return True;
01515 }
01516 
01517 /*******************************************************************
01518  * write a structure.
01519  * called from spoolss_r_abortprinter (srv_spoolss.c)
01520  ********************************************************************/
01521 
01522 BOOL spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
01523 {
01524         prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
01525         depth++;
01526         if(!prs_werror("status", ps, depth, &r_u->status))
01527                 return False;
01528 
01529         return True;
01530 }
01531 
01532 /*******************************************************************
01533  * read a structure.
01534  * called from static spoolss_q_deleteprinter (srv_spoolss.c)
01535  * called from spoolss_deleteprinter (cli_spoolss.c)
01536  ********************************************************************/
01537 
01538 BOOL spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
01539 {
01540         if (q_u == NULL) return False;
01541 
01542         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
01543         depth++;
01544 
01545         if (!prs_align(ps))
01546                 return False;
01547 
01548         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01549                 return False;
01550 
01551         return True;
01552 }
01553 
01554 /*******************************************************************
01555  * write a structure.
01556  * called from static spoolss_r_deleteprinter (srv_spoolss.c)
01557  * called from spoolss_deleteprinter (cli_spoolss.c)
01558  ********************************************************************/
01559 
01560 BOOL spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
01561 {
01562         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
01563         depth++;
01564         
01565         if (!prs_align(ps))
01566                 return False;
01567 
01568         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
01569                 return False;
01570         if (!prs_werror("status", ps, depth, &r_u->status))
01571                 return False;
01572         
01573         return True;
01574 }
01575 
01576 
01577 /*******************************************************************
01578  * read a structure.
01579  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
01580  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
01581  ********************************************************************/
01582 
01583 BOOL spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
01584 {
01585         if (q_u == NULL) return False;
01586 
01587         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
01588         depth++;
01589 
01590         if (!prs_align(ps))
01591                 return False;
01592 
01593         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
01594                 return False;           
01595         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
01596                 return False;
01597         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
01598                 return False;
01599         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
01600                 return False;
01601 
01602 
01603         return True;
01604 }
01605 
01606 
01607 /*******************************************************************
01608  * write a structure.
01609  ********************************************************************/
01610 BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
01611 {
01612         if (r_u == NULL) return False;
01613 
01614         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
01615         depth++;
01616 
01617         if (!prs_align(ps))
01618                 return False;
01619 
01620         if (!prs_werror("status", ps, depth, &r_u->status))
01621                 return False;
01622 
01623         return True;
01624 }
01625 
01626 
01627 /*******************************************************************
01628  * read a structure.
01629  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
01630  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
01631  ********************************************************************/
01632 
01633 BOOL spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
01634 {
01635         if (q_u == NULL) return False;
01636 
01637         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
01638         depth++;
01639 
01640         if (!prs_align(ps))
01641                 return False;
01642 
01643         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
01644                 return False;           
01645         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
01646                 return False;
01647         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
01648                 return False;
01649         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
01650                 return False;
01651 
01652         if (!prs_align(ps))
01653                 return False;
01654 
01655         if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
01656                 return False;           
01657         if(!prs_uint32("version      ", ps, depth, &q_u->version))
01658                 return False;           
01659 
01660 
01661         return True;
01662 }
01663 
01664 
01665 /*******************************************************************
01666  * write a structure.
01667  ********************************************************************/
01668 BOOL spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
01669 {
01670         if (r_u == NULL) return False;
01671 
01672         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
01673         depth++;
01674 
01675         if (!prs_align(ps))
01676                 return False;
01677 
01678         if (!prs_werror("status", ps, depth, &r_u->status))
01679                 return False;
01680 
01681         return True;
01682 }
01683 
01684 
01685 
01686 /*******************************************************************
01687  * read a structure.
01688  * called from static spoolss_q_closeprinter (srv_spoolss.c)
01689  * called from spoolss_closeprinter (cli_spoolss.c)
01690  ********************************************************************/
01691 
01692 BOOL spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
01693 {
01694         if (q_u == NULL) return False;
01695 
01696         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
01697         depth++;
01698 
01699         if (!prs_align(ps))
01700                 return False;
01701 
01702         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01703                 return False;
01704 
01705         return True;
01706 }
01707 
01708 /*******************************************************************
01709  * write a structure.
01710  * called from static spoolss_r_closeprinter (srv_spoolss.c)
01711  * called from spoolss_closeprinter (cli_spoolss.c)
01712  ********************************************************************/
01713 
01714 BOOL spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
01715 {
01716         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
01717         depth++;
01718         
01719         if (!prs_align(ps))
01720                 return False;
01721 
01722         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
01723                 return False;
01724         if (!prs_werror("status", ps, depth, &r_u->status))
01725                 return False;
01726         
01727         return True;
01728 }
01729 
01730 /*******************************************************************
01731  * read a structure.
01732  * called from spoolss_q_startdocprinter (srv_spoolss.c)
01733  ********************************************************************/
01734 
01735 BOOL spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
01736 {
01737         if (q_u == NULL) return False;
01738 
01739         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
01740         depth++;
01741 
01742         if(!prs_align(ps))
01743                 return False;
01744 
01745         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01746                 return False;
01747         
01748         if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
01749                 return False;
01750 
01751         return True;
01752 }
01753 
01754 /*******************************************************************
01755  * write a structure.
01756  * called from spoolss_r_startdocprinter (srv_spoolss.c)
01757  ********************************************************************/
01758 
01759 BOOL spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
01760 {
01761         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
01762         depth++;
01763         if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
01764                 return False;
01765         if(!prs_werror("status", ps, depth, &r_u->status))
01766                 return False;
01767 
01768         return True;
01769 }
01770 
01771 /*******************************************************************
01772  * read a structure.
01773  * called from spoolss_q_enddocprinter (srv_spoolss.c)
01774  ********************************************************************/
01775 
01776 BOOL spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
01777 {
01778         if (q_u == NULL) return False;
01779 
01780         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
01781         depth++;
01782 
01783         if(!prs_align(ps))
01784                 return False;
01785 
01786         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01787                 return False;
01788 
01789         return True;
01790 }
01791 
01792 /*******************************************************************
01793  * write a structure.
01794  * called from spoolss_r_enddocprinter (srv_spoolss.c)
01795  ********************************************************************/
01796 
01797 BOOL spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
01798 {
01799         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
01800         depth++;
01801         if(!prs_werror("status", ps, depth, &r_u->status))
01802                 return False;
01803 
01804         return True;
01805 }
01806 
01807 /*******************************************************************
01808  * read a structure.
01809  * called from spoolss_q_startpageprinter (srv_spoolss.c)
01810  ********************************************************************/
01811 
01812 BOOL spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
01813 {
01814         if (q_u == NULL) return False;
01815 
01816         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
01817         depth++;
01818 
01819         if(!prs_align(ps))
01820                 return False;
01821 
01822         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01823                 return False;
01824 
01825         return True;
01826 }
01827 
01828 /*******************************************************************
01829  * write a structure.
01830  * called from spoolss_r_startpageprinter (srv_spoolss.c)
01831  ********************************************************************/
01832 
01833 BOOL spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
01834 {
01835         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
01836         depth++;
01837         if(!prs_werror("status", ps, depth, &r_u->status))
01838                 return False;
01839 
01840         return True;
01841 }
01842 
01843 /*******************************************************************
01844  * read a structure.
01845  * called from spoolss_q_endpageprinter (srv_spoolss.c)
01846  ********************************************************************/
01847 
01848 BOOL spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
01849 {
01850         if (q_u == NULL) return False;
01851 
01852         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
01853         depth++;
01854 
01855         if(!prs_align(ps))
01856                 return False;
01857 
01858         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01859                 return False;
01860 
01861         return True;
01862 }
01863 
01864 /*******************************************************************
01865  * write a structure.
01866  * called from spoolss_r_endpageprinter (srv_spoolss.c)
01867  ********************************************************************/
01868 
01869 BOOL spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
01870 {
01871         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
01872         depth++;
01873         if(!prs_werror("status", ps, depth, &r_u->status))
01874                 return False;
01875 
01876         return True;
01877 }
01878 
01879 /*******************************************************************
01880  * read a structure.
01881  * called from spoolss_q_writeprinter (srv_spoolss.c)
01882  ********************************************************************/
01883 
01884 BOOL spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
01885 {
01886         if (q_u == NULL) return False;
01887 
01888         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
01889         depth++;
01890 
01891         if(!prs_align(ps))
01892                 return False;
01893 
01894         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
01895                 return False;
01896         if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
01897                 return False;
01898         
01899         if (q_u->buffer_size!=0)
01900         {
01901                 if (UNMARSHALLING(ps))
01902                         q_u->buffer=PRS_ALLOC_MEM(ps, uint8, q_u->buffer_size);
01903                 if(q_u->buffer == NULL)
01904                         return False;   
01905                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
01906                         return False;
01907         }
01908         if(!prs_align(ps))
01909                 return False;
01910         if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
01911                 return False;
01912 
01913         return True;
01914 }
01915 
01916 /*******************************************************************
01917  * write a structure.
01918  * called from spoolss_r_writeprinter (srv_spoolss.c)
01919  ********************************************************************/
01920 
01921 BOOL spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
01922 {
01923         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
01924         depth++;
01925         if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
01926                 return False;
01927         if(!prs_werror("status", ps, depth, &r_u->status))
01928                 return False;
01929 
01930         return True;
01931 }
01932 
01933 /*******************************************************************
01934  * read a structure.
01935  * called from spoolss_q_rffpcnex (srv_spoolss.c)
01936  ********************************************************************/
01937 
01938 BOOL spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
01939 {
01940         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
01941         depth++;
01942 
01943         if(!prs_align(ps))
01944                 return False;
01945 
01946         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
01947                 return False;
01948         if(!prs_uint32("flags", ps, depth, &q_u->flags))
01949                 return False;
01950         if(!prs_uint32("options", ps, depth, &q_u->options))
01951                 return False;
01952         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
01953                 return False;
01954         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
01955                 return False;
01956 
01957         if(!prs_align(ps))
01958                 return False;
01959                 
01960         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
01961                 return False;
01962 
01963         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
01964                 return False;
01965         
01966         if (q_u->option_ptr!=0) {
01967         
01968                 if (UNMARSHALLING(ps))
01969                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
01970                                 return False;
01971         
01972                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
01973                         return False;
01974         }
01975         
01976         return True;
01977 }
01978 
01979 /*******************************************************************
01980  * write a structure.
01981  * called from spoolss_r_rffpcnex (srv_spoolss.c)
01982  ********************************************************************/
01983 
01984 BOOL spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
01985 {
01986         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
01987         depth++;
01988 
01989         if(!prs_werror("status", ps, depth, &r_u->status))
01990                 return False;
01991 
01992         return True;
01993 }
01994 
01995 /*******************************************************************
01996  * read a structure.
01997  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
01998  ********************************************************************/
01999 
02000 BOOL spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
02001 {
02002         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
02003         depth++;
02004 
02005         if(!prs_align(ps))
02006                 return False;
02007 
02008         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
02009                 return False;
02010 
02011         if(!prs_uint32("change", ps, depth, &q_u->change))
02012                 return False;
02013         
02014         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
02015                 return False;
02016         
02017         if (q_u->option_ptr!=0) {
02018         
02019                 if (UNMARSHALLING(ps))
02020                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
02021                                 return False;
02022         
02023                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
02024                         return False;
02025         }
02026 
02027         return True;
02028 }
02029 
02030 /*******************************************************************
02031  * write a structure.
02032  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
02033  ********************************************************************/
02034 
02035 BOOL spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
02036 {
02037         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
02038         depth++;
02039 
02040         if(!prs_align(ps))
02041                 return False;
02042                 
02043         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
02044                 return False;
02045 
02046         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
02047                 return False;
02048         
02049         if(!prs_align(ps))
02050                 return False;
02051         if(!prs_werror("status", ps, depth, &r_u->status))
02052                 return False;
02053 
02054         return True;
02055 }
02056 
02057 /*******************************************************************
02058  * return the length of a uint16 (obvious, but the code is clean)
02059  ********************************************************************/
02060 
02061 static uint32 size_of_uint16(uint16 *value)
02062 {
02063         return (sizeof(*value));
02064 }
02065 
02066 /*******************************************************************
02067  * return the length of a uint32 (obvious, but the code is clean)
02068  ********************************************************************/
02069 
02070 static uint32 size_of_uint32(uint32 *value)
02071 {
02072         return (sizeof(*value));
02073 }
02074 
02075 /*******************************************************************
02076  * return the length of a NTTIME (obvious, but the code is clean)
02077  ********************************************************************/
02078 
02079 static uint32 size_of_nttime(NTTIME *value)
02080 {
02081         return (sizeof(*value));
02082 }
02083 
02084 /*******************************************************************
02085  * return the length of a uint32 (obvious, but the code is clean)
02086  ********************************************************************/
02087 
02088 static uint32 size_of_device_mode(DEVICEMODE *devmode)
02089 {
02090         if (devmode==NULL)
02091                 return (4);
02092         else 
02093                 return (4+devmode->size+devmode->driverextra);
02094 }
02095 
02096 /*******************************************************************
02097  * return the length of a uint32 (obvious, but the code is clean)
02098  ********************************************************************/
02099 
02100 static uint32 size_of_systemtime(SYSTEMTIME *systime)
02101 {
02102         if (systime==NULL)
02103                 return (4);
02104         else 
02105                 return (sizeof(SYSTEMTIME) +4);
02106 }
02107 
02108 /*******************************************************************
02109  Parse a DEVMODE structure and its relative pointer.
02110 ********************************************************************/
02111 
02112 static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
02113 {
02114         prs_struct *ps=&buffer->prs;
02115 
02116         prs_debug(ps, depth, desc, "smb_io_reldevmode");
02117         depth++;
02118 
02119         if (MARSHALLING(ps)) {
02120                 uint32 struct_offset = prs_offset(ps);
02121                 uint32 relative_offset;
02122                 
02123                 if (*devmode == NULL) {
02124                         relative_offset=0;
02125                         if (!prs_uint32("offset", ps, depth, &relative_offset))
02126                                 return False;
02127                         DEBUG(8, ("boing, the devmode was NULL\n"));
02128                         
02129                         return True;
02130                 }
02131                 
02132                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
02133 
02134                 /* mz:  we have to align the device mode for VISTA */
02135                 if (buffer->string_at_end % 4) {
02136                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
02137                 }
02138 
02139                 if(!prs_set_offset(ps, buffer->string_at_end))
02140                         return False;
02141                 
02142                 /* write the DEVMODE */
02143                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
02144                         return False;
02145 
02146                 if(!prs_set_offset(ps, struct_offset))
02147                         return False;
02148                 
02149                 relative_offset=buffer->string_at_end - buffer->struct_start;
02150                 /* write its offset */
02151                 if (!prs_uint32("offset", ps, depth, &relative_offset))
02152                         return False;
02153         }
02154         else {
02155                 uint32 old_offset;
02156                 
02157                 /* read the offset */
02158                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
02159                         return False;
02160                 if (buffer->string_at_end == 0) {
02161                         *devmode = NULL;
02162                         return True;
02163                 }
02164 
02165                 old_offset = prs_offset(ps);
02166                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
02167                         return False;
02168 
02169                 /* read the string */
02170                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
02171                         return False;
02172                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
02173                         return False;
02174 
02175                 if(!prs_set_offset(ps, old_offset))
02176                         return False;
02177         }
02178         return True;
02179 }
02180 
02181 /*******************************************************************
02182  Parse a PRINTER_INFO_0 structure.
02183 ********************************************************************/  
02184 
02185 BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
02186 {
02187         prs_struct *ps=&buffer->prs;
02188 
02189         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
02190         depth++;        
02191         
02192         buffer->struct_start=prs_offset(ps);
02193 
02194         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
02195                 return False;
02196         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
02197                 return False;
02198         
02199         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
02200                 return False;
02201         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
02202                 return False;
02203         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
02204                 return False;
02205 
02206         if(!prs_uint16("year", ps, depth, &info->year))
02207                 return False;
02208         if(!prs_uint16("month", ps, depth, &info->month))
02209                 return False;
02210         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
02211                 return False;
02212         if(!prs_uint16("day", ps, depth, &info->day))
02213                 return False;
02214         if(!prs_uint16("hour", ps, depth, &info->hour))
02215                 return False;
02216         if(!prs_uint16("minute", ps, depth, &info->minute))
02217                 return False;
02218         if(!prs_uint16("second", ps, depth, &info->second))
02219                 return False;
02220         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
02221                 return False;
02222 
02223         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
02224                 return False;
02225         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
02226                 return False;
02227 
02228         if(!prs_uint16("major_version", ps, depth, &info->major_version))
02229                 return False;
02230         if(!prs_uint16("build_version", ps, depth, &info->build_version))
02231                 return False;
02232         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
02233                 return False;
02234         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
02235                 return False;
02236         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
02237                 return False;
02238         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
02239                 return False;
02240         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
02241                 return False;
02242         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
02243                 return False;
02244         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
02245                 return False;
02246         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
02247                 return False;
02248         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
02249                 return False;
02250         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
02251                 return False;
02252         if(!prs_uint32("change_id", ps, depth, &info->change_id))
02253                 return False;
02254         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
02255                 return False;
02256         if(!prs_uint32("status"   , ps, depth, &info->status))
02257                 return False;
02258         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
02259                 return False;
02260         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
02261                 return False;
02262         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
02263                 return False;
02264         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
02265                 return False;
02266         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
02267                 return False;
02268         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
02269                 return False;
02270         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
02271                 return False;
02272         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
02273                 return False;
02274         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
02275                 return False;
02276         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
02277                 return False;
02278 
02279         return True;
02280 }
02281 
02282 /*******************************************************************
02283  Parse a PRINTER_INFO_1 structure.
02284 ********************************************************************/  
02285 
02286 BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
02287 {
02288         prs_struct *ps=&buffer->prs;
02289 
02290         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
02291         depth++;        
02292         
02293         buffer->struct_start=prs_offset(ps);
02294 
02295         if (!prs_uint32("flags", ps, depth, &info->flags))
02296                 return False;
02297         if (!smb_io_relstr("description", buffer, depth, &info->description))
02298                 return False;
02299         if (!smb_io_relstr("name", buffer, depth, &info->name))
02300                 return False;
02301         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
02302                 return False;   
02303 
02304         return True;
02305 }
02306 
02307 /*******************************************************************
02308  Parse a PRINTER_INFO_2 structure.
02309 ********************************************************************/  
02310 
02311 BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
02312 {
02313         prs_struct *ps=&buffer->prs;
02314         uint32 dm_offset, sd_offset, current_offset;
02315         uint32 dummy_value = 0, has_secdesc = 0;
02316 
02317         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
02318         depth++;        
02319         
02320         buffer->struct_start=prs_offset(ps);
02321         
02322         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
02323                 return False;
02324         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
02325                 return False;
02326         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
02327                 return False;
02328         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
02329                 return False;
02330         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
02331                 return False;
02332         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
02333                 return False;
02334         if (!smb_io_relstr("location", buffer, depth, &info->location))
02335                 return False;
02336 
02337         /* save current offset and wind forwared by a uint32 */
02338         dm_offset = prs_offset(ps);
02339         if (!prs_uint32("devmode", ps, depth, &dummy_value))
02340                 return False;
02341         
02342         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
02343                 return False;
02344         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
02345                 return False;
02346         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
02347                 return False;
02348         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
02349                 return False;
02350 
02351         /* save current offset for the sec_desc */
02352         sd_offset = prs_offset(ps);
02353         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
02354                 return False;
02355 
02356         
02357         /* save current location so we can pick back up here */
02358         current_offset = prs_offset(ps);
02359         
02360         /* parse the devmode */
02361         if (!prs_set_offset(ps, dm_offset))
02362                 return False;
02363         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
02364                 return False;
02365         
02366         /* parse the sec_desc */
02367         if (info->secdesc) {
02368                 if (!prs_set_offset(ps, sd_offset))
02369                         return False;
02370                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
02371                         return False;
02372         }
02373 
02374         /* pick up where we left off */
02375         if (!prs_set_offset(ps, current_offset))
02376                 return False;
02377 
02378         if (!prs_uint32("attributes", ps, depth, &info->attributes))
02379                 return False;
02380         if (!prs_uint32("priority", ps, depth, &info->priority))
02381                 return False;
02382         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
02383                 return False;
02384         if (!prs_uint32("starttime", ps, depth, &info->starttime))
02385                 return False;
02386         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
02387                 return False;
02388         if (!prs_uint32("status", ps, depth, &info->status))
02389                 return False;
02390         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
02391                 return False;
02392         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
02393                 return False;
02394 
02395         return True;
02396 }
02397 
02398 /*******************************************************************
02399  Parse a PRINTER_INFO_3 structure.
02400 ********************************************************************/  
02401 
02402 BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
02403 {
02404         uint32 offset = 0;
02405         prs_struct *ps=&buffer->prs;
02406 
02407         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
02408         depth++;        
02409         
02410         buffer->struct_start=prs_offset(ps);
02411         
02412         if (MARSHALLING(ps)) {
02413                 /* Ensure the SD is 8 byte aligned in the buffer. */
02414                 uint start = prs_offset(ps); /* Remember the start position. */
02415                 uint off_val = 0;
02416 
02417                 /* Write a dummy value. */
02418                 if (!prs_uint32("offset", ps, depth, &off_val))
02419                         return False;
02420 
02421                 /* 8 byte align. */
02422                 if (!prs_align_uint64(ps))
02423                         return False;
02424 
02425                 /* Remember where we must seek back to write the SD. */
02426                 offset = prs_offset(ps);
02427 
02428                 /* Calculate the real offset for the SD. */
02429 
02430                 off_val = offset - start;
02431 
02432                 /* Seek back to where we store the SD offset & store. */
02433                 prs_set_offset(ps, start);
02434                 if (!prs_uint32("offset", ps, depth, &off_val))
02435                         return False;
02436 
02437                 /* Return to after the 8 byte align. */
02438                 prs_set_offset(ps, offset);
02439 
02440         } else {
02441                 if (!prs_uint32("offset", ps, depth, &offset))
02442                         return False;
02443                 /* Seek within the buffer. */
02444                 if (!prs_set_offset(ps, offset))
02445                         return False;
02446         }
02447         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
02448                 return False;
02449 
02450         return True;
02451 }
02452 
02453 /*******************************************************************
02454  Parse a PRINTER_INFO_4 structure.
02455 ********************************************************************/  
02456 
02457 BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
02458 {
02459         prs_struct *ps=&buffer->prs;
02460 
02461         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
02462         depth++;        
02463         
02464         buffer->struct_start=prs_offset(ps);
02465         
02466         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
02467                 return False;
02468         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
02469                 return False;
02470         if (!prs_uint32("attributes", ps, depth, &info->attributes))
02471                 return False;
02472         return True;
02473 }
02474 
02475 /*******************************************************************
02476  Parse a PRINTER_INFO_5 structure.
02477 ********************************************************************/  
02478 
02479 BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
02480 {
02481         prs_struct *ps=&buffer->prs;
02482 
02483         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
02484         depth++;        
02485         
02486         buffer->struct_start=prs_offset(ps);
02487         
02488         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
02489                 return False;
02490         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
02491                 return False;
02492         if (!prs_uint32("attributes", ps, depth, &info->attributes))
02493                 return False;
02494         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
02495                 return False;
02496         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
02497                 return False;
02498         return True;
02499 }
02500 
02501 /*******************************************************************
02502  Parse a PRINTER_INFO_6 structure.
02503 ********************************************************************/  
02504 
02505 BOOL smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
02506                            PRINTER_INFO_6 *info, int depth)
02507 {
02508         prs_struct *ps=&buffer->prs;
02509 
02510         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
02511         depth++;        
02512         
02513         if (!prs_uint32("status", ps, depth, &info->status))
02514                 return False;
02515 
02516         return True;
02517 }
02518 
02519 /*******************************************************************
02520  Parse a PRINTER_INFO_7 structure.
02521 ********************************************************************/  
02522 
02523 BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
02524 {
02525         prs_struct *ps=&buffer->prs;
02526 
02527         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
02528         depth++;        
02529         
02530         buffer->struct_start=prs_offset(ps);
02531         
02532         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
02533                 return False;
02534         if (!prs_uint32("action", ps, depth, &info->action))
02535                 return False;
02536         return True;
02537 }
02538 
02539 /*******************************************************************
02540  Parse a PORT_INFO_1 structure.
02541 ********************************************************************/  
02542 
02543 BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
02544 {
02545         prs_struct *ps=&buffer->prs;
02546 
02547         prs_debug(ps, depth, desc, "smb_io_port_info_1");
02548         depth++;        
02549         
02550         buffer->struct_start=prs_offset(ps);
02551         
02552         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
02553                 return False;
02554 
02555         return True;
02556 }
02557 
02558 /*******************************************************************
02559  Parse a PORT_INFO_2 structure.
02560 ********************************************************************/  
02561 
02562 BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
02563 {
02564         prs_struct *ps=&buffer->prs;
02565 
02566         prs_debug(ps, depth, desc, "smb_io_port_info_2");
02567         depth++;        
02568         
02569         buffer->struct_start=prs_offset(ps);
02570         
02571         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
02572                 return False;
02573         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
02574                 return False;
02575         if (!smb_io_relstr("description", buffer, depth, &info->description))
02576                 return False;
02577         if (!prs_uint32("port_type", ps, depth, &info->port_type))
02578                 return False;
02579         if (!prs_uint32("reserved", ps, depth, &info->reserved))
02580                 return False;
02581 
02582         return True;
02583 }
02584 
02585 /*******************************************************************
02586  Parse a DRIVER_INFO_1 structure.
02587 ********************************************************************/
02588 
02589 BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
02590 {
02591         prs_struct *ps=&buffer->prs;
02592 
02593         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
02594         depth++;        
02595         
02596         buffer->struct_start=prs_offset(ps);
02597 
02598         if (!smb_io_relstr("name", buffer, depth, &info->name))
02599                 return False;
02600 
02601         return True;
02602 }
02603 
02604 /*******************************************************************
02605  Parse a DRIVER_INFO_2 structure.
02606 ********************************************************************/
02607 
02608 BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
02609 {
02610         prs_struct *ps=&buffer->prs;
02611 
02612         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
02613         depth++;        
02614         
02615         buffer->struct_start=prs_offset(ps);
02616 
02617         if (!prs_uint32("version", ps, depth, &info->version))
02618                 return False;
02619         if (!smb_io_relstr("name", buffer, depth, &info->name))
02620                 return False;
02621         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
02622                 return False;
02623         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
02624                 return False;
02625         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
02626                 return False;
02627         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
02628                 return False;
02629 
02630         return True;
02631 }
02632 
02633 /*******************************************************************
02634  Parse a DRIVER_INFO_3 structure.
02635 ********************************************************************/
02636 
02637 BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
02638 {
02639         prs_struct *ps=&buffer->prs;
02640 
02641         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
02642         depth++;        
02643         
02644         buffer->struct_start=prs_offset(ps);
02645 
02646         if (!prs_uint32("version", ps, depth, &info->version))
02647                 return False;
02648         if (!smb_io_relstr("name", buffer, depth, &info->name))
02649                 return False;
02650         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
02651                 return False;
02652         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
02653                 return False;
02654         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
02655                 return False;
02656         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
02657                 return False;
02658         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
02659                 return False;
02660 
02661         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
02662                 return False;
02663 
02664         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
02665                 return False;
02666         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
02667                 return False;
02668 
02669         return True;
02670 }
02671 
02672 /*******************************************************************
02673  Parse a DRIVER_INFO_6 structure.
02674 ********************************************************************/
02675 
02676 BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
02677 {
02678         prs_struct *ps=&buffer->prs;
02679 
02680         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
02681         depth++;        
02682         
02683         buffer->struct_start=prs_offset(ps);
02684 
02685         if (!prs_uint32("version", ps, depth, &info->version))
02686                 return False;
02687         if (!smb_io_relstr("name", buffer, depth, &info->name))
02688                 return False;
02689         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
02690                 return False;
02691         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
02692                 return False;
02693         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
02694                 return False;
02695         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
02696                 return False;
02697         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
02698                 return False;
02699 
02700         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
02701                 return False;
02702 
02703         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
02704                 return False;
02705         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
02706                 return False;
02707 
02708         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
02709                 return False;
02710 
02711         if (!prs_uint64("date", ps, depth, &info->driver_date))
02712                 return False;
02713 
02714         if (!prs_uint32("padding", ps, depth, &info->padding))
02715                 return False;
02716 
02717         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
02718                 return False;
02719 
02720         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
02721                 return False;
02722 
02723         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
02724                 return False;
02725         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
02726                 return False;
02727         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
02728                 return False;
02729         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
02730                 return False;
02731         
02732         return True;
02733 }
02734 
02735 /*******************************************************************
02736  Parse a JOB_INFO_1 structure.
02737 ********************************************************************/  
02738 
02739 BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
02740 {
02741         prs_struct *ps=&buffer->prs;
02742 
02743         prs_debug(ps, depth, desc, "smb_io_job_info_1");
02744         depth++;        
02745         
02746         buffer->struct_start=prs_offset(ps);
02747 
02748         if (!prs_uint32("jobid", ps, depth, &info->jobid))
02749                 return False;
02750         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
02751                 return False;
02752         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
02753                 return False;
02754         if (!smb_io_relstr("username", buffer, depth, &info->username))
02755                 return False;
02756         if (!smb_io_relstr("document", buffer, depth, &info->document))
02757                 return False;
02758         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
02759                 return False;
02760         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
02761                 return False;
02762         if (!prs_uint32("status", ps, depth, &info->status))
02763                 return False;
02764         if (!prs_uint32("priority", ps, depth, &info->priority))
02765                 return False;
02766         if (!prs_uint32("position", ps, depth, &info->position))
02767                 return False;
02768         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
02769                 return False;
02770         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
02771                 return False;
02772         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
02773                 return False;
02774 
02775         return True;
02776 }
02777 
02778 /*******************************************************************
02779  Parse a JOB_INFO_2 structure.
02780 ********************************************************************/  
02781 
02782 BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
02783 {       
02784         uint32 pipo=0;
02785         prs_struct *ps=&buffer->prs;
02786         
02787         prs_debug(ps, depth, desc, "smb_io_job_info_2");
02788         depth++;        
02789 
02790         buffer->struct_start=prs_offset(ps);
02791         
02792         if (!prs_uint32("jobid",ps, depth, &info->jobid))
02793                 return False;
02794         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
02795                 return False;
02796         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
02797                 return False;
02798         if (!smb_io_relstr("username", buffer, depth, &info->username))
02799                 return False;
02800         if (!smb_io_relstr("document", buffer, depth, &info->document))
02801                 return False;
02802         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
02803                 return False;
02804         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
02805                 return False;
02806 
02807         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
02808                 return False;
02809         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
02810                 return False;
02811         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
02812                 return False;
02813         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
02814                 return False;
02815         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
02816                 return False;
02817 
02818 /*      SEC_DESC sec_desc;*/
02819         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
02820                 return False;
02821 
02822         if (!prs_uint32("status",ps, depth, &info->status))
02823                 return False;
02824         if (!prs_uint32("priority",ps, depth, &info->priority))
02825                 return False;
02826         if (!prs_uint32("position",ps, depth, &info->position)) 
02827                 return False;
02828         if (!prs_uint32("starttime",ps, depth, &info->starttime))
02829                 return False;
02830         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
02831                 return False;
02832         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
02833                 return False;
02834         if (!prs_uint32("size",ps, depth, &info->size))
02835                 return False;
02836         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
02837                 return False;
02838         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
02839                 return False;
02840         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
02841                 return False;
02842 
02843         return True;
02844 }
02845 
02846 /*******************************************************************
02847 ********************************************************************/  
02848 
02849 BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
02850 {
02851         prs_struct *ps=&buffer->prs;
02852         
02853         prs_debug(ps, depth, desc, "smb_io_form_1");
02854         depth++;
02855                 
02856         buffer->struct_start=prs_offset(ps);
02857         
02858         if (!prs_uint32("flag", ps, depth, &info->flag))
02859                 return False;
02860                 
02861         if (!smb_io_relstr("name", buffer, depth, &info->name))
02862                 return False;
02863 
02864         if (!prs_uint32("width", ps, depth, &info->width))
02865                 return False;
02866         if (!prs_uint32("length", ps, depth, &info->length))
02867                 return False;
02868         if (!prs_uint32("left", ps, depth, &info->left))
02869                 return False;
02870         if (!prs_uint32("top", ps, depth, &info->top))
02871                 return False;
02872         if (!prs_uint32("right", ps, depth, &info->right))
02873                 return False;
02874         if (!prs_uint32("bottom", ps, depth, &info->bottom))
02875                 return False;
02876 
02877         return True;
02878 }
02879 
02880 
02881 
02882 /*******************************************************************
02883  Parse a DRIVER_DIRECTORY_1 structure.
02884 ********************************************************************/  
02885 
02886 BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
02887 {
02888         prs_struct *ps=&buffer->prs;
02889 
02890         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
02891         depth++;
02892 
02893         buffer->struct_start=prs_offset(ps);
02894 
02895         if (!smb_io_unistr(desc, &info->name, ps, depth))
02896                 return False;
02897 
02898         return True;
02899 }
02900 
02901 /*******************************************************************
02902  Parse a PORT_INFO_1 structure.
02903 ********************************************************************/  
02904 
02905 BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
02906 {
02907         prs_struct *ps=&buffer->prs;
02908 
02909         prs_debug(ps, depth, desc, "smb_io_port_1");
02910         depth++;
02911 
02912         buffer->struct_start=prs_offset(ps);
02913 
02914         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
02915                 return False;
02916 
02917         return True;
02918 }
02919 
02920 /*******************************************************************
02921  Parse a PORT_INFO_2 structure.
02922 ********************************************************************/  
02923 
02924 BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
02925 {
02926         prs_struct *ps=&buffer->prs;
02927 
02928         prs_debug(ps, depth, desc, "smb_io_port_2");
02929         depth++;
02930 
02931         buffer->struct_start=prs_offset(ps);
02932 
02933         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
02934                 return False;
02935         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
02936                 return False;
02937         if(!smb_io_relstr("description", buffer, depth, &info->description))
02938                 return False;
02939         if(!prs_uint32("port_type", ps, depth, &info->port_type))
02940                 return False;
02941         if(!prs_uint32("reserved", ps, depth, &info->reserved))
02942                 return False;
02943 
02944         return True;
02945 }
02946 
02947 /*******************************************************************
02948 ********************************************************************/  
02949 
02950 BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
02951 {
02952         prs_struct *ps=&buffer->prs;
02953 
02954         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
02955         depth++;        
02956 
02957         buffer->struct_start=prs_offset(ps);
02958         
02959         if (smb_io_relstr("name", buffer, depth, &info->name))
02960                 return False;
02961 
02962         return True;
02963 }
02964 
02965 /*******************************************************************
02966 ********************************************************************/  
02967 
02968 BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
02969 {
02970         prs_struct *ps=&buffer->prs;
02971 
02972         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
02973         depth++;        
02974 
02975         buffer->struct_start=prs_offset(ps);
02976         
02977         if (smb_io_relstr("name", buffer, depth, &info->name))
02978                 return False;
02979 
02980         return True;
02981 }
02982 
02983 /*******************************************************************
02984 ********************************************************************/  
02985 
02986 BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
02987 {
02988         prs_struct *ps=&buffer->prs;
02989 
02990         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
02991         depth++;        
02992 
02993         buffer->struct_start=prs_offset(ps);
02994 
02995         if (!smb_io_relstr("name", buffer, depth, &info->name))
02996                 return False;
02997 
02998         return True;
02999 }
03000 
03001 /*******************************************************************
03002 ********************************************************************/  
03003 
03004 BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
03005 {
03006         prs_struct *ps=&buffer->prs;
03007 
03008         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
03009         depth++;        
03010 
03011         buffer->struct_start=prs_offset(ps);
03012 
03013         if (!smb_io_relstr("name", buffer, depth, &info->name))
03014                 return False;
03015         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
03016                 return False;
03017         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
03018                 return False;
03019 
03020         return True;
03021 }
03022 
03023 /*******************************************************************
03024 return the size required by a struct in the stream
03025 ********************************************************************/  
03026 
03027 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
03028 {
03029         int size=0;
03030         
03031         size+=size_of_relative_string( &info->printername );
03032         size+=size_of_relative_string( &info->servername );
03033 
03034         size+=size_of_uint32( &info->cjobs);
03035         size+=size_of_uint32( &info->total_jobs);
03036         size+=size_of_uint32( &info->total_bytes);
03037 
03038         size+=size_of_uint16( &info->year);
03039         size+=size_of_uint16( &info->month);
03040         size+=size_of_uint16( &info->dayofweek);
03041         size+=size_of_uint16( &info->day);
03042         size+=size_of_uint16( &info->hour);
03043         size+=size_of_uint16( &info->minute);
03044         size+=size_of_uint16( &info->second);
03045         size+=size_of_uint16( &info->milliseconds);
03046 
03047         size+=size_of_uint32( &info->global_counter);
03048         size+=size_of_uint32( &info->total_pages);
03049 
03050         size+=size_of_uint16( &info->major_version);
03051         size+=size_of_uint16( &info->build_version);
03052 
03053         size+=size_of_uint32( &info->unknown7);
03054         size+=size_of_uint32( &info->unknown8);
03055         size+=size_of_uint32( &info->unknown9);
03056         size+=size_of_uint32( &info->session_counter);
03057         size+=size_of_uint32( &info->unknown11);
03058         size+=size_of_uint32( &info->printer_errors);
03059         size+=size_of_uint32( &info->unknown13);
03060         size+=size_of_uint32( &info->unknown14);
03061         size+=size_of_uint32( &info->unknown15);
03062         size+=size_of_uint32( &info->unknown16);
03063         size+=size_of_uint32( &info->change_id);
03064         size+=size_of_uint32( &info->unknown18);
03065         size+=size_of_uint32( &info->status);
03066         size+=size_of_uint32( &info->unknown20);
03067         size+=size_of_uint32( &info->c_setprinter);
03068         
03069         size+=size_of_uint16( &info->unknown22);
03070         size+=size_of_uint16( &info->unknown23);
03071         size+=size_of_uint16( &info->unknown24);
03072         size+=size_of_uint16( &info->unknown25);
03073         size+=size_of_uint16( &info->unknown26);
03074         size+=size_of_uint16( &info->unknown27);
03075         size+=size_of_uint16( &info->unknown28);
03076         size+=size_of_uint16( &info->unknown29);
03077         
03078         return size;
03079 }
03080 
03081 /*******************************************************************
03082 return the size required by a struct in the stream
03083 ********************************************************************/  
03084 
03085 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
03086 {
03087         int size=0;
03088                 
03089         size+=size_of_uint32( &info->flags );   
03090         size+=size_of_relative_string( &info->description );
03091         size+=size_of_relative_string( &info->name );
03092         size+=size_of_relative_string( &info->comment );
03093 
03094         return size;
03095 }
03096 
03097 /*******************************************************************
03098 return the size required by a struct in the stream
03099 ********************************************************************/
03100 
03101 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
03102 {
03103         uint32 size=0;
03104                 
03105         size += 4;
03106         
03107         size += sec_desc_size( info->secdesc );
03108 
03109         size+=size_of_device_mode( info->devmode );
03110         
03111         size+=size_of_relative_string( &info->servername );
03112         size+=size_of_relative_string( &info->printername );
03113         size+=size_of_relative_string( &info->sharename );
03114         size+=size_of_relative_string( &info->portname );
03115         size+=size_of_relative_string( &info->drivername );
03116         size+=size_of_relative_string( &info->comment );
03117         size+=size_of_relative_string( &info->location );
03118         
03119         size+=size_of_relative_string( &info->sepfile );
03120         size+=size_of_relative_string( &info->printprocessor );
03121         size+=size_of_relative_string( &info->datatype );
03122         size+=size_of_relative_string( &info->parameters );
03123 
03124         size+=size_of_uint32( &info->attributes );
03125         size+=size_of_uint32( &info->priority );
03126         size+=size_of_uint32( &info->defaultpriority );
03127         size+=size_of_uint32( &info->starttime );
03128         size+=size_of_uint32( &info->untiltime );
03129         size+=size_of_uint32( &info->status );
03130         size+=size_of_uint32( &info->cjobs );
03131         size+=size_of_uint32( &info->averageppm );      
03132                 
03133         /* 
03134          * add any adjustments for alignment.  This is
03135          * not optimal since we could be calling this
03136          * function from a loop (e.g. enumprinters), but 
03137          * it is easier to maintain the calculation here and
03138          * not place the burden on the caller to remember.   --jerry
03139          */
03140         if ((size % 4) != 0)
03141                 size += 4 - (size % 4);
03142         
03143         return size;
03144 }
03145 
03146 /*******************************************************************
03147 return the size required by a struct in the stream
03148 ********************************************************************/
03149 
03150 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
03151 {
03152         uint32 size=0;
03153                 
03154         size+=size_of_relative_string( &info->printername );
03155         size+=size_of_relative_string( &info->servername );
03156 
03157         size+=size_of_uint32( &info->attributes );
03158         return size;
03159 }
03160 
03161 /*******************************************************************
03162 return the size required by a struct in the stream
03163 ********************************************************************/
03164 
03165 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
03166 {
03167         uint32 size=0;
03168                 
03169         size+=size_of_relative_string( &info->printername );
03170         size+=size_of_relative_string( &info->portname );
03171 
03172         size+=size_of_uint32( &info->attributes );
03173         size+=size_of_uint32( &info->device_not_selected_timeout );
03174         size+=size_of_uint32( &info->transmission_retry_timeout );
03175         return size;
03176 }
03177 
03178 /*******************************************************************
03179 return the size required by a struct in the stream
03180 ********************************************************************/
03181 
03182 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
03183 {
03184         return sizeof(uint32);
03185 }
03186 
03187 /*******************************************************************
03188 return the size required by a struct in the stream
03189 ********************************************************************/
03190 
03191 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
03192 {
03193         /* The 8 is for the self relative pointer - 8 byte aligned.. */
03194         return 8 + (uint32)sec_desc_size( info->secdesc );
03195 }
03196 
03197 /*******************************************************************
03198 return the size required by a struct in the stream
03199 ********************************************************************/
03200 
03201 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
03202 {
03203         uint32 size=0;
03204                 
03205         size+=size_of_relative_string( &info->guid );
03206         size+=size_of_uint32( &info->action );
03207         return size;
03208 }
03209 
03210 /*******************************************************************
03211 return the size required by a struct in the stream
03212 ********************************************************************/
03213 
03214 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
03215 {
03216         int size=0;
03217         size+=size_of_relative_string( &info->name );
03218 
03219         return size;
03220 }
03221 
03222 /*******************************************************************
03223 return the size required by a struct in the stream
03224 ********************************************************************/
03225 
03226 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
03227 {
03228         int size=0;
03229         size+=size_of_uint32( &info->version ); 
03230         size+=size_of_relative_string( &info->name );
03231         size+=size_of_relative_string( &info->architecture );
03232         size+=size_of_relative_string( &info->driverpath );
03233         size+=size_of_relative_string( &info->datafile );
03234         size+=size_of_relative_string( &info->configfile );
03235 
03236         return size;
03237 }
03238 
03239 /*******************************************************************
03240 return the size required by a string array.
03241 ********************************************************************/
03242 
03243 uint32 spoolss_size_string_array(uint16 *string)
03244 {
03245         uint32 i = 0;
03246 
03247         if (string) {
03248                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
03249         }
03250         i=i+2; /* to count all chars including the leading zero */
03251         i=2*i; /* because we need the value in bytes */
03252         i=i+4; /* the offset pointer size */
03253 
03254         return i;
03255 }
03256 
03257 /*******************************************************************
03258 return the size required by a struct in the stream
03259 ********************************************************************/
03260 
03261 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
03262 {
03263         int size=0;
03264 
03265         size+=size_of_uint32( &info->version ); 
03266         size+=size_of_relative_string( &info->name );
03267         size+=size_of_relative_string( &info->architecture );
03268         size+=size_of_relative_string( &info->driverpath );
03269         size+=size_of_relative_string( &info->datafile );
03270         size+=size_of_relative_string( &info->configfile );
03271         size+=size_of_relative_string( &info->helpfile );
03272         size+=size_of_relative_string( &info->monitorname );
03273         size+=size_of_relative_string( &info->defaultdatatype );
03274         
03275         size+=spoolss_size_string_array(info->dependentfiles);
03276 
03277         return size;
03278 }
03279 
03280 /*******************************************************************
03281 return the size required by a struct in the stream
03282 ********************************************************************/
03283 
03284 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
03285 {
03286         uint32 size=0;
03287 
03288         size+=size_of_uint32( &info->version ); 
03289         size+=size_of_relative_string( &info->name );
03290         size+=size_of_relative_string( &info->architecture );
03291         size+=size_of_relative_string( &info->driverpath );
03292         size+=size_of_relative_string( &info->datafile );
03293         size+=size_of_relative_string( &info->configfile );
03294         size+=size_of_relative_string( &info->helpfile );
03295 
03296         size+=spoolss_size_string_array(info->dependentfiles);
03297 
03298         size+=size_of_relative_string( &info->monitorname );
03299         size+=size_of_relative_string( &info->defaultdatatype );
03300         
03301         size+=spoolss_size_string_array(info->previousdrivernames);
03302 
03303         size+=size_of_nttime(&info->driver_date);
03304         size+=size_of_uint32( &info->padding ); 
03305         size+=size_of_uint32( &info->driver_version_low );      
03306         size+=size_of_uint32( &info->driver_version_high );     
03307         size+=size_of_relative_string( &info->mfgname );
03308         size+=size_of_relative_string( &info->oem_url );
03309         size+=size_of_relative_string( &info->hardware_id );
03310         size+=size_of_relative_string( &info->provider );
03311 
03312         return size;
03313 }
03314 
03315 /*******************************************************************
03316 return the size required by a struct in the stream
03317 ********************************************************************/  
03318 
03319 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
03320 {
03321         int size=0;
03322         size+=size_of_uint32( &info->jobid );
03323         size+=size_of_relative_string( &info->printername );
03324         size+=size_of_relative_string( &info->machinename );
03325         size+=size_of_relative_string( &info->username );
03326         size+=size_of_relative_string( &info->document );
03327         size+=size_of_relative_string( &info->datatype );
03328         size+=size_of_relative_string( &info->text_status );
03329         size+=size_of_uint32( &info->status );
03330         size+=size_of_uint32( &info->priority );
03331         size+=size_of_uint32( &info->position );
03332         size+=size_of_uint32( &info->totalpages );
03333         size+=size_of_uint32( &info->pagesprinted );
03334         size+=size_of_systemtime( &info->submitted );
03335 
03336         return size;
03337 }
03338 
03339 /*******************************************************************
03340 return the size required by a struct in the stream
03341 ********************************************************************/  
03342 
03343 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
03344 {
03345         int size=0;
03346 
03347         size+=4; /* size of sec desc ptr */
03348 
03349         size+=size_of_uint32( &info->jobid );
03350         size+=size_of_relative_string( &info->printername );
03351         size+=size_of_relative_string( &info->machinename );
03352         size+=size_of_relative_string( &info->username );
03353         size+=size_of_relative_string( &info->document );
03354         size+=size_of_relative_string( &info->notifyname );
03355         size+=size_of_relative_string( &info->datatype );
03356         size+=size_of_relative_string( &info->printprocessor );
03357         size+=size_of_relative_string( &info->parameters );
03358         size+=size_of_relative_string( &info->drivername );
03359         size+=size_of_device_mode( info->devmode );
03360         size+=size_of_relative_string( &info->text_status );
03361 /*      SEC_DESC sec_desc;*/
03362         size+=size_of_uint32( &info->status );
03363         size+=size_of_uint32( &info->priority );
03364         size+=size_of_uint32( &info->position );
03365         size+=size_of_uint32( &info->starttime );
03366         size+=size_of_uint32( &info->untiltime );
03367         size+=size_of_uint32( &info->totalpages );
03368         size+=size_of_uint32( &info->size );
03369         size+=size_of_systemtime( &info->submitted );
03370         size+=size_of_uint32( &info->timeelapsed );
03371         size+=size_of_uint32( &info->pagesprinted );
03372 
03373         return size;
03374 }
03375 
03376 /*******************************************************************
03377 return the size required by a struct in the stream
03378 ********************************************************************/
03379 
03380 uint32 spoolss_size_form_1(FORM_1 *info)
03381 {
03382         int size=0;
03383 
03384         size+=size_of_uint32( &info->flag );
03385         size+=size_of_relative_string( &info->name );
03386         size+=size_of_uint32( &info->width );
03387         size+=size_of_uint32( &info->length );
03388         size+=size_of_uint32( &info->left );
03389         size+=size_of_uint32( &info->top );
03390         size+=size_of_uint32( &info->right );
03391         size+=size_of_uint32( &info->bottom );
03392 
03393         return size;
03394 }
03395 
03396 /*******************************************************************
03397 return the size required by a struct in the stream
03398 ********************************************************************/  
03399 
03400 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
03401 {
03402         int size=0;
03403 
03404         size+=size_of_relative_string( &info->port_name );
03405 
03406         return size;
03407 }
03408 
03409 /*******************************************************************
03410 return the size required by a struct in the stream
03411 ********************************************************************/  
03412 
03413 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
03414 {
03415         int size=0;
03416 
03417         size=str_len_uni(&info->name);  /* the string length       */
03418         size=size+1;                    /* add the leading zero    */
03419         size=size*2;                    /* convert in char         */
03420 
03421         return size;
03422 }
03423 
03424 /*******************************************************************
03425 return the size required by a struct in the stream
03426 ********************************************************************/  
03427 
03428 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
03429 {
03430         int size=0;
03431 
03432         size=str_len_uni(&info->name);  /* the string length       */
03433         size=size+1;                    /* add the leading zero    */
03434         size=size*2;                    /* convert in char         */
03435 
03436         return size;
03437 }
03438 
03439 /*******************************************************************
03440 return the size required by a struct in the stream
03441 ********************************************************************/  
03442 
03443 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
03444 {
03445         int size=0;
03446 
03447         size+=size_of_relative_string( &info->port_name );
03448         size+=size_of_relative_string( &info->monitor_name );
03449         size+=size_of_relative_string( &info->description );
03450 
03451         size+=size_of_uint32( &info->port_type );
03452         size+=size_of_uint32( &info->reserved );
03453 
03454         return size;
03455 }
03456 
03457 /*******************************************************************
03458 return the size required by a struct in the stream
03459 ********************************************************************/  
03460 
03461 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
03462 {
03463         int size=0;
03464         size+=size_of_relative_string( &info->name );
03465 
03466         return size;
03467 }
03468 
03469 /*******************************************************************
03470 return the size required by a struct in the stream
03471 ********************************************************************/  
03472 
03473 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
03474 {
03475         int size=0;
03476         size+=size_of_relative_string( &info->name );
03477 
03478         return size;
03479 }
03480 
03481 /*******************************************************************
03482 return the size required by a struct in the stream
03483 ********************************************************************/  
03484 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
03485 {
03486         uint32  size = 0; 
03487         
03488         if (!p)
03489                 return 0;
03490         
03491         /* uint32(offset) + uint32(length) + length) */
03492         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
03493         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
03494         
03495         size += size_of_uint32(&p->type);
03496                        
03497         return size;
03498 }
03499 
03500 /*******************************************************************
03501 return the size required by a struct in the stream
03502 ********************************************************************/  
03503 
03504 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
03505 {
03506         int size=0;
03507         size+=size_of_relative_string( &info->name );
03508 
03509         return size;
03510 }
03511 
03512 /*******************************************************************
03513 return the size required by a struct in the stream
03514 ********************************************************************/  
03515 
03516 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
03517 {
03518         int size=0;
03519         size+=size_of_relative_string( &info->name);
03520         size+=size_of_relative_string( &info->environment);
03521         size+=size_of_relative_string( &info->dll_name);
03522 
03523         return size;
03524 }
03525 
03526 /*******************************************************************
03527  * init a structure.
03528  ********************************************************************/
03529 
03530 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
03531                                const POLICY_HND *hnd,
03532                                const fstring architecture,
03533                                uint32 level, uint32 clientmajor, uint32 clientminor,
03534                                RPC_BUFFER *buffer, uint32 offered)
03535 {      
03536         if (q_u == NULL)
03537                 return False;
03538 
03539         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
03540 
03541         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
03542 
03543         q_u->level=level;
03544         q_u->clientmajorversion=clientmajor;
03545         q_u->clientminorversion=clientminor;
03546 
03547         q_u->buffer=buffer;
03548         q_u->offered=offered;
03549 
03550         return True;
03551 }
03552 
03553 /*******************************************************************
03554  * read a structure.
03555  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
03556  ********************************************************************/
03557 
03558 BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
03559 {
03560         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
03561         depth++;
03562 
03563         if(!prs_align(ps))
03564                 return False;
03565         
03566         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
03567                 return False;
03568         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
03569                 return False;
03570         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
03571                 return False;
03572         
03573         if(!prs_align(ps))
03574                 return False;
03575         if(!prs_uint32("level", ps, depth, &q_u->level))
03576                 return False;
03577                 
03578         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
03579                 return False;
03580 
03581         if(!prs_align(ps))
03582                 return False;
03583 
03584         if(!prs_uint32("offered", ps, depth, &q_u->offered))
03585                 return False;
03586                 
03587         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
03588                 return False;
03589         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
03590                 return False;
03591 
03592         return True;
03593 }
03594 
03595 /*******************************************************************
03596  * read a structure.
03597  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
03598  ********************************************************************/
03599 
03600 BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
03601 {
03602         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
03603         depth++;
03604 
03605         if (!prs_align(ps))
03606                 return False;
03607                 
03608         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
03609                 return False;
03610 
03611         if (!prs_align(ps))
03612                 return False;
03613         if (!prs_uint32("needed", ps, depth, &r_u->needed))
03614                 return False;
03615         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
03616                 return False;
03617         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
03618                 return False;           
03619         if (!prs_werror("status", ps, depth, &r_u->status))
03620                 return False;
03621 
03622         return True;            
03623 }
03624 
03625 /*******************************************************************
03626  * init a structure.
03627  ********************************************************************/
03628 
03629 BOOL make_spoolss_q_enumprinters(
03630         SPOOL_Q_ENUMPRINTERS *q_u, 
03631         uint32 flags, 
03632         char *servername, 
03633         uint32 level, 
03634         RPC_BUFFER *buffer, 
03635         uint32 offered
03636 )
03637 {
03638         q_u->flags=flags;
03639         
03640         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
03641         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
03642 
03643         q_u->level=level;
03644         q_u->buffer=buffer;
03645         q_u->offered=offered;
03646 
03647         return True;
03648 }
03649 
03650 /*******************************************************************
03651  * init a structure.
03652  ********************************************************************/
03653 
03654 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
03655                                 fstring servername, uint32 level, 
03656                                 RPC_BUFFER *buffer, uint32 offered)
03657 {
03658         q_u->name_ptr = (servername != NULL) ? 1 : 0;
03659         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
03660 
03661         q_u->level=level;
03662         q_u->buffer=buffer;
03663         q_u->offered=offered;
03664 
03665         return True;
03666 }
03667 
03668 /*******************************************************************
03669  * read a structure.
03670  * called from spoolss_enumprinters (srv_spoolss.c)
03671  ********************************************************************/
03672 
03673 BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
03674 {
03675         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
03676         depth++;
03677 
03678         if (!prs_align(ps))
03679                 return False;
03680 
03681         if (!prs_uint32("flags", ps, depth, &q_u->flags))
03682                 return False;
03683         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
03684                 return False;
03685 
03686         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
03687                 return False;
03688                 
03689         if (!prs_align(ps))
03690                 return False;
03691         if (!prs_uint32("level", ps, depth, &q_u->level))
03692                 return False;
03693 
03694         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
03695                 return False;
03696 
03697         if (!prs_align(ps))
03698                 return False;
03699         if (!prs_uint32("offered", ps, depth, &q_u->offered))
03700                 return False;
03701 
03702         return True;
03703 }
03704 
03705 /*******************************************************************
03706  Parse a SPOOL_R_ENUMPRINTERS structure.
03707  ********************************************************************/
03708 
03709 BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
03710 {
03711         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
03712         depth++;
03713 
03714         if (!prs_align(ps))
03715                 return False;
03716                 
03717         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
03718                 return False;
03719 
03720         if (!prs_align(ps))
03721                 return False;
03722                 
03723         if (!prs_uint32("needed", ps, depth, &r_u->needed))
03724                 return False;
03725                 
03726         if (!prs_uint32("returned", ps, depth, &r_u->returned))
03727                 return False;
03728                 
03729         if (!prs_werror("status", ps, depth, &r_u->status))
03730                 return False;
03731 
03732         return True;            
03733 }
03734 
03735 /*******************************************************************
03736  * write a structure.
03737  * called from spoolss_r_enum_printers (srv_spoolss.c)
03738  *
03739  ********************************************************************/
03740 
03741 BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
03742 {       
03743         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
03744         depth++;
03745 
03746         if (!prs_align(ps))
03747                 return False;
03748                 
03749         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
03750                 return False;
03751 
03752         if (!prs_align(ps))
03753                 return False;
03754 
03755         if (!prs_uint32("needed", ps, depth, &r_u->needed))
03756                 return False;
03757                 
03758         if (!prs_werror("status", ps, depth, &r_u->status))
03759                 return False;
03760 
03761         return True;            
03762 }
03763 
03764 /*******************************************************************
03765  * read a structure.
03766  * called from spoolss_getprinter (srv_spoolss.c)
03767  ********************************************************************/
03768 
03769 BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
03770 {
03771         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
03772         depth++;
03773 
03774         if (!prs_align(ps))
03775                 return False;
03776 
03777         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
03778                 return False;
03779         if (!prs_uint32("level", ps, depth, &q_u->level))
03780                 return False;
03781 
03782         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
03783                 return False;
03784 
03785         if (!prs_align(ps))
03786                 return False;
03787         if (!prs_uint32("offered", ps, depth, &q_u->offered))
03788                 return False;
03789 
03790         return True;
03791 }
03792 
03793 /*******************************************************************
03794  * init a structure.
03795  ********************************************************************/
03796 
03797 BOOL make_spoolss_q_getprinter(
03798         TALLOC_CTX *mem_ctx,
03799         SPOOL_Q_GETPRINTER *q_u, 
03800         const POLICY_HND *hnd, 
03801         uint32 level, 
03802         RPC_BUFFER *buffer, 
03803         uint32 offered
03804 )
03805 {
03806         if (q_u == NULL)
03807         {
03808                 return False;
03809         }
03810         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
03811 
03812         q_u->level=level;
03813         q_u->buffer=buffer;
03814         q_u->offered=offered;
03815 
03816         return True;
03817 }
03818 
03819 /*******************************************************************
03820  * init a structure.
03821  ********************************************************************/
03822 BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
03823                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
03824                                 uint32 command)
03825 {
03826         SEC_DESC *secdesc;
03827         DEVICEMODE *devmode;
03828 
03829         if (!q_u || !info)
03830                 return False;
03831         
03832         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
03833 
03834         q_u->level = level;
03835         q_u->info.level = level;
03836         q_u->info.info_ptr = 1; /* Info is != NULL, see above */
03837         switch (level) {
03838 
03839           /* There's no such thing as a setprinter level 1 */
03840 
03841         case 2:
03842                 secdesc = info->printers_2->secdesc;
03843                 devmode = info->printers_2->devmode;
03844                 
03845                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
03846 #if 1   /* JERRY TEST */
03847                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
03848                 if (!q_u->secdesc_ctr)
03849                         return False;
03850                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
03851                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
03852                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
03853                 q_u->secdesc_ctr->sec = secdesc;
03854 
03855                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
03856                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
03857                 q_u->devmode_ctr.devmode = devmode;
03858 #else
03859                 q_u->secdesc_ctr = NULL;
03860         
03861                 q_u->devmode_ctr.devmode_ptr = 0;
03862                 q_u->devmode_ctr.size = 0;
03863                 q_u->devmode_ctr.devmode = NULL;
03864 #endif
03865                 break;
03866         case 3:
03867                 secdesc = info->printers_3->secdesc;
03868                 
03869                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
03870                 
03871                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
03872                 if (!q_u->secdesc_ctr)
03873                         return False;
03874                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
03875                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
03876                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
03877                 q_u->secdesc_ctr->sec = secdesc;
03878 
03879                 break;
03880         case 7:
03881                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
03882                 break;
03883 
03884         default: 
03885                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
03886                         break;
03887         }
03888 
03889         
03890         q_u->command = command;
03891 
03892         return True;
03893 }
03894 
03895 
03896 /*******************************************************************
03897 ********************************************************************/  
03898 
03899 BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
03900 {               
03901         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
03902         depth++;
03903 
03904         if(!prs_align(ps))
03905                 return False;
03906         
03907         if(!prs_werror("status", ps, depth, &r_u->status))
03908                 return False;
03909 
03910         return True;
03911 }
03912 
03913 /*******************************************************************
03914  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
03915 ********************************************************************/  
03916 
03917 BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
03918 {
03919         uint32 ptr_sec_desc = 0;
03920 
03921         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
03922         depth++;
03923 
03924         if(!prs_align(ps))
03925                 return False;
03926 
03927         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
03928                 return False;
03929         if(!prs_uint32("level", ps, depth, &q_u->level))
03930                 return False;
03931         
03932         /* check for supported levels and structures we know about */
03933                 
03934         switch ( q_u->level ) {
03935                 case 0:
03936                 case 2:
03937                 case 3:
03938                 case 7:
03939                         /* supported levels */
03940                         break;
03941                 default:
03942                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
03943                                 q_u->level));
03944                         return True;
03945         }
03946                         
03947 
03948         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
03949                 return False;
03950 
03951         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
03952                 return False;
03953         
03954         if(!prs_align(ps))
03955                 return False;
03956 
03957         switch (q_u->level)
03958         {
03959                 case 2:
03960                 {
03961                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
03962                         break;
03963                 }
03964                 case 3:
03965                 {
03966                         /* FIXME ! Our parsing here is wrong I think,
03967                          * but for a level3 it makes no sense for
03968                          * ptr_sec_desc to be NULL. JRA. Based on
03969                          * a Vista sniff from Martin Zielinski <mz@seh.de>.
03970                          */
03971                         if (UNMARSHALLING(ps)) {
03972                                 ptr_sec_desc = 1;
03973                         } else {
03974                                 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
03975                         }
03976                         break;
03977                 }
03978         }
03979         if (ptr_sec_desc)
03980         {
03981                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
03982                         return False;
03983         } else {
03984                 uint32 dummy = 0;
03985 
03986                 /* Parse a NULL security descriptor.  This should really
03987                    happen inside the sec_io_desc_buf() function. */
03988 
03989                 prs_debug(ps, depth, "", "sec_io_desc_buf");
03990                 if (!prs_uint32("size", ps, depth + 1, &dummy))
03991                         return False;
03992                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
03993                         return False;
03994         }
03995         
03996         if(!prs_uint32("command", ps, depth, &q_u->command))
03997                 return False;
03998 
03999         return True;
04000 }
04001 
04002 /*******************************************************************
04003 ********************************************************************/  
04004 
04005 BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
04006 {               
04007         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
04008         depth++;
04009 
04010         if(!prs_align(ps))
04011                 return False;
04012         
04013         if(!prs_werror("status", ps, depth, &r_u->status))
04014                 return False;
04015 
04016         return True;
04017 }
04018 
04019 /*******************************************************************
04020 ********************************************************************/  
04021 
04022 BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
04023 {
04024 
04025         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
04026         depth++;
04027 
04028         if(!prs_align(ps))
04029                 return False;
04030 
04031         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
04032                 return False;
04033 
04034         return True;
04035 }
04036 
04037 
04038 /*******************************************************************
04039 ********************************************************************/  
04040 
04041 BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
04042 {               
04043         prs_debug(ps, depth, desc, "");
04044         depth++;
04045 
04046         if(!prs_align(ps))
04047                 return False;
04048         
04049         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
04050                 return False;
04051 
04052         if(!prs_align(ps))
04053                 return False;
04054         
04055         if(!prs_uint32("needed", ps, depth, &r_u->needed))
04056                 return False;
04057 
04058         if(!prs_werror("status", ps, depth, &r_u->status))
04059                 return False;
04060 
04061         return True;
04062 }
04063 
04064 /*******************************************************************
04065 ********************************************************************/  
04066 
04067 BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
04068 {
04069         prs_debug(ps, depth, desc, "");
04070         depth++;
04071 
04072         if(!prs_align(ps))
04073                 return False;
04074 
04075         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
04076                 return False;
04077         if(!prs_uint32("level", ps, depth, &q_u->level))
04078                 return False;
04079         
04080         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
04081                 return False;
04082 
04083         if(!prs_align(ps))
04084                 return False;
04085         
04086         if(!prs_uint32("offered", ps, depth, &q_u->offered))
04087                 return False;
04088 
04089         return True;
04090 }
04091 
04092 /*******************************************************************
04093 ********************************************************************/  
04094 
04095 BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
04096 {               
04097         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
04098         depth++;
04099 
04100         if (!prs_align(ps))
04101                 return False;
04102                 
04103         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
04104                 return False;
04105 
04106         if (!prs_align(ps))
04107                 return False;
04108                 
04109         if (!prs_uint32("needed", ps, depth, &r_u->needed))
04110                 return False;
04111                 
04112         if (!prs_uint32("returned", ps, depth, &r_u->returned))
04113                 return False;
04114                 
04115         if (!prs_werror("status", ps, depth, &r_u->status))
04116                 return False;
04117 
04118         return True;            
04119 }
04120 
04121 /*******************************************************************
04122 ********************************************************************/  
04123 
04124 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
04125                                 uint32 firstjob,
04126                                 uint32 numofjobs,
04127                                 uint32 level,
04128                                 RPC_BUFFER *buffer,
04129                                 uint32 offered)
04130 {
04131         if (q_u == NULL)
04132         {
04133                 return False;
04134         }
04135         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
04136         q_u->firstjob = firstjob;
04137         q_u->numofjobs = numofjobs;
04138         q_u->level = level;
04139         q_u->buffer= buffer;
04140         q_u->offered = offered;
04141         return True;
04142 }
04143 
04144 /*******************************************************************
04145 ********************************************************************/  
04146 
04147 BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
04148 {
04149         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
04150         depth++;
04151 
04152         if (!prs_align(ps))
04153                 return False;
04154 
04155         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
04156                 return False;
04157                 
04158         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
04159                 return False;
04160         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
04161                 return False;
04162         if (!prs_uint32("level", ps, depth, &q_u->level))
04163                 return False;
04164 
04165         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
04166                 return False;   
04167 
04168         if(!prs_align(ps))
04169                 return False;
04170 
04171         if (!prs_uint32("offered", ps, depth, &q_u->offered))
04172                 return False;
04173 
04174         return True;
04175 }
04176 
04177 /*******************************************************************
04178 ********************************************************************/  
04179 
04180 BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
04181 {               
04182         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
04183         depth++;
04184 
04185         if(!prs_align(ps))
04186                 return False;
04187         
04188         if(!prs_werror("status", ps, depth, &r_u->status))
04189                 return False;
04190 
04191         return True;
04192 }
04193 
04194 /*******************************************************************
04195 ********************************************************************/  
04196 
04197 BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
04198 {
04199         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
04200         depth++;
04201 
04202         if(!prs_align(ps))
04203                 return False;
04204 
04205         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
04206                 return False;
04207         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
04208                 return False;
04209 
04210         return True;
04211 }
04212 
04213 /*******************************************************************
04214 ********************************************************************/  
04215 
04216 BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
04217 {               
04218         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
04219         depth++;
04220 
04221         if(!prs_align(ps))
04222                 return False;
04223         
04224         if(!prs_werror("status", ps, depth, &r_u->status))
04225                 return False;
04226 
04227         return True;
04228 }
04229 
04230 /*******************************************************************
04231 ********************************************************************/  
04232 
04233 BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
04234 {
04235         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
04236         depth++;
04237 
04238         if(!prs_align(ps))
04239                 return False;
04240 
04241         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
04242                 return False;
04243         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
04244                 return False;
04245         /* 
04246          * level is usually 0. If (level!=0) then I'm in trouble !
04247          * I will try to generate setjob command with level!=0, one day.
04248          */
04249         if(!prs_uint32("level", ps, depth, &q_u->level))
04250                 return False;
04251         if(!prs_uint32("command", ps, depth, &q_u->command))
04252                 return False;
04253 
04254         return True;
04255 }
04256 
04257 /*******************************************************************
04258  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
04259 ********************************************************************/  
04260 
04261 BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
04262 {
04263         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
04264         depth++;
04265 
04266         if (!prs_align(ps))
04267                 return False;
04268                 
04269         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
04270                 return False;
04271 
04272         if (!prs_align(ps))
04273                 return False;
04274                 
04275         if (!prs_uint32("needed", ps, depth, &r_u->needed))
04276                 return False;
04277                 
04278         if (!prs_uint32("returned", ps, depth, &r_u->returned))
04279                 return False;
04280                 
04281         if (!prs_werror("status", ps, depth, &r_u->status))
04282                 return False;
04283 
04284         return True;            
04285 }
04286 
04287 /*******************************************************************
04288  * init a structure.
04289  ********************************************************************/
04290 
04291 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
04292                                 const char *name,
04293                                 const char *environment,
04294                                 uint32 level,
04295                                 RPC_BUFFER *buffer, uint32 offered)
04296 {
04297         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
04298         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
04299 
04300         q_u->level=level;
04301         q_u->buffer=buffer;
04302         q_u->offered=offered;
04303 
04304         return True;
04305 }
04306 
04307 /*******************************************************************
04308  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
04309 ********************************************************************/  
04310 
04311 BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
04312 {
04313 
04314         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
04315         depth++;
04316 
04317         if (!prs_align(ps))
04318                 return False;
04319                 
04320         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
04321                 return False;
04322         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
04323                 return False;
04324                 
04325         if (!prs_align(ps))
04326                 return False;
04327         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
04328                 return False;
04329         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
04330                 return False;
04331                 
04332         if (!prs_align(ps))
04333                 return False;
04334         if (!prs_uint32("level", ps, depth, &q_u->level))
04335                 return False;
04336                 
04337         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
04338                 return False;
04339 
04340         if (!prs_align(ps))
04341                 return False;
04342                 
04343         if (!prs_uint32("offered", ps, depth, &q_u->offered))
04344                 return False;
04345 
04346         return True;
04347 }
04348 
04349 /*******************************************************************
04350 ********************************************************************/  
04351 
04352 BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
04353 {
04354 
04355         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
04356         depth++;
04357 
04358         if (!prs_align(ps))
04359                 return False;                   
04360         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
04361                 return False;           
04362         if (!prs_uint32("level", ps, depth, &q_u->level))
04363                 return False;   
04364         
04365         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
04366                 return False;
04367 
04368         if (!prs_align(ps))
04369                 return False;
04370         if (!prs_uint32("offered", ps, depth, &q_u->offered))
04371                 return False;
04372 
04373         return True;
04374 }
04375 
04376 /*******************************************************************
04377 ********************************************************************/  
04378 
04379 BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
04380 {
04381         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
04382         depth++;
04383 
04384         if (!prs_align(ps))
04385                 return False;
04386                 
04387         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
04388                 return False;
04389 
04390         if (!prs_align(ps))
04391                 return False;
04392                 
04393         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
04394                 return False;
04395                 
04396         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
04397                 return False;
04398                 
04399         if (!prs_werror("status", ps, depth, &r_u->status))
04400                 return False;
04401 
04402         return True;
04403 }
04404 
04405 /*******************************************************************
04406 ********************************************************************/  
04407 
04408 BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
04409 {
04410 
04411         prs_debug(ps, depth, desc, "spoolss_io_q_getform");
04412         depth++;
04413 
04414         if (!prs_align(ps))
04415                 return False;                   
04416         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
04417                 return False;           
04418         if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
04419                 return False;
04420 
04421         if (!prs_align(ps))
04422                 return False;
04423 
04424         if (!prs_uint32("level", ps, depth, &q_u->level))
04425                 return False;   
04426         
04427         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
04428                 return False;
04429 
04430         if (!prs_align(ps))
04431                 return False;
04432         if (!prs_uint32("offered", ps, depth, &q_u->offered))
04433                 return False;
04434 
04435         return True;
04436 }
04437 
04438 /*******************************************************************
04439 ********************************************************************/  
04440 
04441 BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
04442 {
04443         prs_debug(ps, depth, desc, "spoolss_io_r_getform");
04444         depth++;
04445 
04446         if (!prs_align(ps))
04447                 return False;
04448                 
04449         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
04450                 return False;
04451 
04452         if (!prs_align(ps))
04453                 return False;
04454                 
04455         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
04456                 return False;
04457                 
04458         if (!prs_werror("status", ps, depth, &r_u->status))
04459                 return False;
04460 
04461         return True;
04462 }
04463 
04464 /*******************************************************************
04465  Parse a SPOOL_R_ENUMPORTS structure.
04466 ********************************************************************/  
04467 
04468 BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
04469 {
04470         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
04471         depth++;
04472 
04473         if (!prs_align(ps))
04474                 return False;
04475                 
04476         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
04477                 return False;
04478 
04479         if (!prs_align(ps))
04480                 return False;
04481                 
04482         if (!prs_uint32("needed", ps, depth, &r_u->needed))
04483                 return False;
04484                 
04485         if (!prs_uint32("returned", ps, depth, &r_u->returned))
04486                 return False;
04487                 
04488         if (!prs_werror("status", ps, depth, &r_u->status))
04489                 return False;
04490 
04491         return True;            
04492 }
04493 
04494 /*******************************************************************
04495 ********************************************************************/  
04496 
04497 BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
04498 {
04499         prs_debug(ps, depth, desc, "");
04500         depth++;
04501 
04502         if (!prs_align(ps))
04503                 return False;
04504 
04505         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
04506                 return False;
04507         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
04508                 return False;
04509 
04510         if (!prs_align(ps))
04511                 return False;
04512         if (!prs_uint32("level", ps, depth, &q_u->level))
04513                 return False;
04514                 
04515         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
04516                 return False;
04517 
04518         if (!prs_align(ps))
04519                 return False;
04520         if (!prs_uint32("offered", ps, depth, &q_u->offered))
04521                 return False;
04522 
04523         return True;
04524 }
04525 
04526 /*******************************************************************
04527  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
04528 ********************************************************************/  
04529 
04530 BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
04531 {       
04532         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
04533         depth++;
04534                 
04535         if(!prs_align(ps))
04536                 return False;
04537 
04538         if(!prs_uint32("flags", ps, depth, &il->flags))
04539                 return False;
04540         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
04541                 return False;
04542         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
04543                 return False;
04544         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
04545                 return False;
04546                 
04547         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
04548                 return False;
04549         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
04550                 return False;
04551         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
04552                 return False;
04553 
04554         return True;
04555 }
04556 
04557 /*******************************************************************
04558  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
04559 ********************************************************************/  
04560 
04561 BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
04562 {       
04563         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
04564         depth++;
04565                 
04566         if(!prs_align(ps))
04567                 return False;
04568 
04569         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
04570                 return False;
04571 
04572         return True;
04573 }
04574 
04575 /*******************************************************************
04576  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
04577 ********************************************************************/  
04578 
04579 BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
04580 {       
04581         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
04582         depth++;
04583                 
04584         if(!prs_align(ps))
04585                 return False;
04586 
04587         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
04588                 return False;
04589         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
04590                 return False;
04591         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
04592                 return False;
04593         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
04594                 return False;
04595 
04596         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
04597                 return False;
04598         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
04599                 return False;
04600         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
04601                 return False;
04602         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
04603                 return False;
04604         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
04605                 return False;
04606         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
04607                 return False;
04608         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
04609                 return False;
04610         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
04611                 return False;
04612         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
04613                 return False;
04614 
04615         if(!prs_uint32("attributes", ps, depth, &il->attributes))
04616                 return False;
04617         if(!prs_uint32("priority", ps, depth, &il->priority))
04618                 return False;
04619         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
04620                 return False;
04621         if(!prs_uint32("starttime", ps, depth, &il->starttime))
04622                 return False;
04623         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
04624                 return False;
04625         if(!prs_uint32("status", ps, depth, &il->status))
04626                 return False;
04627         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
04628                 return False;
04629         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
04630                 return False;
04631 
04632         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
04633                 return False;
04634         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
04635                 return False;
04636         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
04637                 return False;
04638         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
04639                 return False;
04640         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
04641                 return False;
04642         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
04643                 return False;
04644         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
04645                 return False;
04646         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
04647                 return False;
04648         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
04649                 return False;
04650         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
04651                 return False;
04652         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
04653                 return False;
04654 
04655         return True;
04656 }
04657 
04658 BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
04659 {       
04660         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
04661         depth++;
04662                 
04663         if(!prs_align(ps))
04664                 return False;
04665 
04666         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
04667                 return False;
04668         if(!prs_uint32("action", ps, depth, &il->action))
04669                 return False;
04670 
04671         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
04672                 return False;
04673         return True;
04674 }
04675 
04676 /*******************************************************************
04677 ********************************************************************/  
04678 
04679 BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
04680 {
04681         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
04682         depth++;
04683 
04684         if(!prs_align(ps))
04685                 return False;
04686         if(!prs_uint32("level", ps, depth, &il->level))
04687                 return False;
04688         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
04689                 return False;
04690         
04691         /* if no struct inside just return */
04692         if (il->info_ptr==0) {
04693                 if (UNMARSHALLING(ps)) {
04694                         il->info_1=NULL;
04695                         il->info_2=NULL;
04696                 }
04697                 return True;
04698         }
04699                         
04700         switch (il->level) {
04701                 /*
04702                  * level 0 is used by setprinter when managing the queue
04703                  * (hold, stop, start a queue)
04704                  */
04705                 case 0:
04706                         break;
04707                 /* DOCUMENT ME!!! What is level 1 used for? */
04708                 case 1:
04709                 {
04710                         if (UNMARSHALLING(ps)) {
04711                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
04712                                         return False;
04713                         }
04714                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
04715                                 return False;
04716                         break;          
04717                 }
04718                 /* 
04719                  * level 2 is used by addprinter
04720                  * and by setprinter when updating printer's info
04721                  */     
04722                 case 2:
04723                         if (UNMARSHALLING(ps)) {
04724                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
04725                                         return False;
04726                         }
04727                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
04728                                 return False;
04729                         break;          
04730                 /* DOCUMENT ME!!! What is level 3 used for? */
04731                 case 3:
04732                 {
04733                         if (UNMARSHALLING(ps)) {
04734                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
04735                                         return False;
04736                         }
04737                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
04738                                 return False;
04739                         break;          
04740                 }
04741                 case 7:
04742                         if (UNMARSHALLING(ps))
04743                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
04744                                         return False;
04745                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
04746                                 return False;
04747                         break;
04748         }
04749 
04750         return True;
04751 }
04752 
04753 /*******************************************************************
04754 ********************************************************************/  
04755 
04756 BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
04757 {
04758         uint32 ptr_sec_desc = 0;
04759 
04760         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
04761         depth++;
04762 
04763         if(!prs_align(ps))
04764                 return False;
04765 
04766         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
04767                 return False;
04768         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
04769                 return False;
04770 
04771         if(!prs_align(ps))
04772                 return False;
04773 
04774         if(!prs_uint32("info_level", ps, depth, &q_u->level))
04775                 return False;
04776         
04777         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
04778                 return False;
04779         
04780         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
04781                 return False;
04782 
04783         if(!prs_align(ps))
04784                 return False;
04785 
04786         switch (q_u->level) {
04787                 case 2:
04788                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
04789                         break;
04790                 case 3:
04791                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
04792                         break;
04793         }
04794         if (ptr_sec_desc) {
04795                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
04796                         return False;
04797         } else {
04798                 uint32 dummy;
04799 
04800                 /* Parse a NULL security descriptor.  This should really
04801                         happen inside the sec_io_desc_buf() function. */
04802 
04803                 prs_debug(ps, depth, "", "sec_io_desc_buf");
04804                 if (!prs_uint32("size", ps, depth + 1, &dummy))
04805                         return False;
04806                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
04807                         return False;
04808         }
04809 
04810         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
04811                 return False;
04812         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
04813                 return False;
04814 
04815         return True;
04816 }
04817 
04818 /*******************************************************************
04819 ********************************************************************/  
04820 
04821 BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
04822                                prs_struct *ps, int depth)
04823 {
04824         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
04825         depth++;
04826         
04827         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
04828                 return False;
04829 
04830         if(!prs_werror("status", ps, depth, &r_u->status))
04831                 return False;
04832 
04833         return True;
04834 }
04835 
04836 /*******************************************************************
04837 ********************************************************************/  
04838 
04839 BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
04840                                           prs_struct *ps, int depth)
04841 {       
04842         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
04843         
04844         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
04845         depth++;
04846                 
04847         /* reading */
04848         if (UNMARSHALLING(ps)) {
04849                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
04850                 if(il == NULL)
04851                         return False;
04852                 *q_u=il;
04853         }
04854         else {
04855                 il=*q_u;
04856         }
04857         
04858         if(!prs_align(ps))
04859                 return False;
04860 
04861         if(!prs_uint32("cversion", ps, depth, &il->cversion))
04862                 return False;
04863         if(!prs_uint32("name", ps, depth, &il->name_ptr))
04864                 return False;
04865         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
04866                 return False;
04867         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
04868                 return False;
04869         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
04870                 return False;
04871         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
04872                 return False;
04873         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
04874                 return False;
04875         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
04876                 return False;
04877         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
04878                 return False;
04879         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
04880                 return False;
04881         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
04882                 return False;
04883 
04884         if(!prs_align(ps))
04885                 return False;
04886         
04887         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
04888                 return False;
04889         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
04890                 return False;
04891         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
04892                 return False;
04893         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
04894                 return False;
04895         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
04896                 return False;
04897         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
04898                 return False;
04899         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
04900                 return False;
04901         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
04902                 return False;
04903 
04904         if(!prs_align(ps))
04905                 return False;
04906                 
04907         if (il->dependentfiles_ptr)
04908                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
04909 
04910         return True;
04911 }
04912 
04913 /*******************************************************************
04914 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
04915 ********************************************************************/  
04916 
04917 BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
04918                                           prs_struct *ps, int depth)
04919 {       
04920         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
04921         
04922         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
04923         depth++;
04924                 
04925         /* reading */
04926         if (UNMARSHALLING(ps)) {
04927                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
04928                 if(il == NULL)
04929                         return False;
04930                 *q_u=il;
04931         }
04932         else {
04933                 il=*q_u;
04934         }
04935         
04936         if(!prs_align(ps))
04937                 return False;
04938 
04939         /* 
04940          * I know this seems weird, but I have no other explanation.
04941          * This is observed behavior on both NT4 and 2K servers.
04942          * --jerry
04943          */
04944          
04945         if (!prs_align_uint64(ps))
04946                 return False;
04947 
04948         /* parse the main elements the packet */
04949 
04950         if(!prs_uint32("cversion       ", ps, depth, &il->version))
04951                 return False;
04952         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
04953                 return False;
04954         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
04955                 return False;
04956         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
04957                 return False;
04958         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
04959                 return False;
04960         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
04961                 return False;
04962         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
04963                 return False;
04964         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
04965                 return False;
04966         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
04967                 return False;
04968         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
04969                 return False;
04970         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
04971                 return False;
04972         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
04973                 return False;
04974         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
04975                 return False;
04976         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
04977                 return False;
04978         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
04979                 return False;
04980         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
04981                 return False;
04982         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
04983                 return False;
04984         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
04985                 return False;
04986         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
04987                 return False;
04988         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
04989                 return False;
04990 
04991         /* parse the structures in the packet */
04992 
04993         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
04994                 return False;
04995         if(!prs_align(ps))
04996                 return False;
04997 
04998         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
04999                 return False;
05000         if(!prs_align(ps))
05001                 return False;
05002 
05003         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
05004                 return False;
05005         if(!prs_align(ps))
05006                 return False;
05007 
05008         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
05009                 return False;
05010         if(!prs_align(ps))
05011                 return False;
05012 
05013         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
05014                 return False;
05015         if(!prs_align(ps))
05016                 return False;
05017 
05018         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
05019                 return False;
05020         if(!prs_align(ps))
05021                 return False;
05022 
05023         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
05024                 return False;
05025         if(!prs_align(ps))
05026                 return False;
05027 
05028         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
05029                 return False;
05030         if(!prs_align(ps))
05031                 return False;
05032         if (il->dependentfiles_ptr) {
05033                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
05034                         return False;
05035                 if(!prs_align(ps))
05036                         return False;
05037         }
05038         if (il->previousnames_ptr) {
05039                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
05040                         return False;
05041                 if(!prs_align(ps))
05042                         return False;
05043         }
05044         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
05045                 return False;
05046         if(!prs_align(ps))
05047                 return False;
05048         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
05049                 return False;
05050         if(!prs_align(ps))
05051                 return False;
05052         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
05053                 return False;
05054         if(!prs_align(ps))
05055                 return False;
05056         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
05057                 return False;
05058 
05059         return True;
05060 }
05061 
05062 /*******************************************************************
05063  convert a buffer of UNICODE strings null terminated
05064  the buffer is terminated by a NULL
05065  
05066  convert to an dos codepage array (null terminated)
05067  
05068  dynamically allocate memory
05069  
05070 ********************************************************************/  
05071 
05072 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
05073 {
05074         fstring f;
05075         int n = 0;
05076         char *src;
05077 
05078         if (buf5==NULL)
05079                 return False;
05080 
05081         src = (char *)buf5->buffer;
05082         *ar = SMB_MALLOC_ARRAY(fstring, 1);
05083         if (!*ar) {
05084                 return False;
05085         }
05086 
05087         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
05088                 rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
05089                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
05090                 *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
05091                 if (!*ar) {
05092                         return False;
05093                 }
05094                 fstrcpy((*ar)[n], f);
05095                 n++;
05096         }
05097 
05098         fstrcpy((*ar)[n], "");
05099  
05100         return True;
05101 }
05102 
05103 /*******************************************************************
05104  read a UNICODE array with null terminated strings 
05105  and null terminated array 
05106  and size of array at beginning
05107 ********************************************************************/  
05108 
05109 BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
05110 {
05111         if (buffer==NULL) return False;
05112 
05113         buffer->offset=0;
05114         buffer->uni_str_len=buffer->uni_max_len;
05115         
05116         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
05117                 return False;
05118 
05119         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
05120                 return False;
05121 
05122         return True;
05123 }
05124 
05125 /*******************************************************************
05126 ********************************************************************/  
05127 
05128 BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
05129 {
05130         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
05131         depth++;
05132 
05133         if(!prs_align(ps))
05134                 return False;
05135         if(!prs_uint32("level", ps, depth, &il->level))
05136                 return False;
05137         if(!prs_uint32("ptr", ps, depth, &il->ptr))
05138                 return False;
05139 
05140         if (il->ptr==0)
05141                 return True;
05142                 
05143         switch (il->level) {
05144                 case 3:
05145                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
05146                                 return False;
05147                         break;          
05148                 case 6:
05149                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
05150                                 return False;
05151                         break;          
05152         default:
05153                 return False;
05154         }
05155 
05156         return True;
05157 }
05158 
05159 /*******************************************************************
05160  init a SPOOL_Q_ADDPRINTERDRIVER struct
05161  ******************************************************************/
05162 
05163 BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
05164                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
05165                                 uint32 level, PRINTER_DRIVER_CTR *info)
05166 {
05167         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
05168         
05169         if (!srv_name || !info) {
05170                 return False;
05171         }
05172 
05173         q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
05174         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
05175         
05176         q_u->level = level;
05177         
05178         q_u->info.level = level;
05179         q_u->info.ptr = 1;      /* Info is != NULL, see above */
05180         switch (level)
05181         {
05182         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
05183         case 3 :
05184                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
05185                 break;
05186                 
05187         default:
05188                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
05189                 break;
05190         }
05191         
05192         return True;
05193 }
05194 
05195 BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, 
05196         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
05197                                 DRIVER_INFO_3 *info3)
05198 {
05199         uint32          len = 0;
05200         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
05201 
05202         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
05203                 return False;
05204         
05205         inf->cversion   = info3->version;
05206         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
05207         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
05208         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
05209         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
05210         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
05211         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
05212         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
05213         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
05214 
05215         init_unistr2_from_unistr(&inf->name, &info3->name);
05216         init_unistr2_from_unistr(&inf->environment, &info3->architecture);
05217         init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
05218         init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
05219         init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
05220         init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
05221         init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
05222         init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
05223 
05224         if (info3->dependentfiles) {
05225                 BOOL done = False;
05226                 BOOL null_char = False;
05227                 uint16 *ptr = info3->dependentfiles;
05228 
05229                 while (!done) {
05230                         switch (*ptr) {
05231                                 case 0:
05232                                         /* the null_char BOOL is used to help locate
05233                                            two '\0's back to back */
05234                                         if (null_char) {
05235                                                 done = True;
05236                                         } else {
05237                                                 null_char = True;
05238                                         }
05239                                         break;
05240                                         
05241                                 default:
05242                                         null_char = False;
05243                                         break;                          
05244                         }
05245                         len++;
05246                         ptr++;
05247                 }
05248         }
05249 
05250         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
05251         inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
05252         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
05253                 SAFE_FREE(inf);
05254                 return False;
05255         }
05256         
05257         *spool_drv_info = inf;
05258         
05259         return True;
05260 }
05261 
05262 /*******************************************************************
05263  make a BUFFER5 struct from a uint16*
05264  ******************************************************************/
05265 
05266 BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
05267 {
05268 
05269         buf5->buf_len = len;
05270         if (src) {
05271                 if (len) {
05272                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
05273                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
05274                                 return False;
05275                         }
05276                 } else {
05277                         buf5->buffer = NULL;
05278                 }
05279         } else {
05280                 buf5->buffer=NULL;
05281         }
05282         
05283         return True;
05284 }
05285 
05286 /*******************************************************************
05287  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
05288  ********************************************************************/  
05289 
05290 BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
05291 {
05292         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
05293         depth++;
05294 
05295         if(!prs_align(ps))
05296                 return False;
05297 
05298         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
05299                 return False;
05300         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
05301                 return False;
05302                 
05303         if(!prs_align(ps))
05304                 return False;
05305         if(!prs_uint32("info_level", ps, depth, &q_u->level))
05306                 return False;
05307 
05308         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
05309                 return False;
05310 
05311         return True;
05312 }
05313 
05314 /*******************************************************************
05315 ********************************************************************/  
05316 
05317 BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
05318 {
05319         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
05320         depth++;
05321 
05322         if(!prs_werror("status", ps, depth, &q_u->status))
05323                 return False;
05324 
05325         return True;
05326 }
05327 
05328 /*******************************************************************
05329  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
05330  ********************************************************************/  
05331 
05332 BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
05333 {
05334         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
05335         depth++;
05336 
05337         if(!prs_align(ps))
05338                 return False;
05339 
05340         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
05341                 return False;
05342         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
05343                 return False;
05344                 
05345         if(!prs_align(ps))
05346                 return False;
05347         if(!prs_uint32("info_level", ps, depth, &q_u->level))
05348                 return False;
05349 
05350         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
05351                 return False;
05352 
05353         if(!prs_align(ps))
05354                 return False;
05355         if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
05356                 return False;
05357                 
05358         return True;
05359 }
05360 
05361 /*******************************************************************
05362 ********************************************************************/  
05363 
05364 BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
05365 {
05366         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
05367         depth++;
05368 
05369         if(!prs_werror("status", ps, depth, &q_u->status))
05370                 return False;
05371 
05372         return True;
05373 }
05374 
05375 /*******************************************************************
05376 ********************************************************************/  
05377 
05378 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
05379                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
05380 {
05381         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
05382         
05383         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
05384         
05385         if (*asc==NULL)
05386         {
05387                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
05388                 if(*asc == NULL)
05389                         return False;
05390                 ZERO_STRUCTP(*asc);
05391         }       
05392 
05393         d=*asc;
05394 
05395         d->cversion=uni->cversion;
05396 
05397         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
05398         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
05399         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
05400         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
05401         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
05402         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
05403         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
05404         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
05405 
05406         DEBUGADD(8,( "version:         %d\n", d->cversion));
05407         DEBUGADD(8,( "name:            %s\n", d->name));
05408         DEBUGADD(8,( "environment:     %s\n", d->environment));
05409         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
05410         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
05411         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
05412         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
05413         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
05414         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
05415 
05416         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
05417                 return True;
05418         
05419         SAFE_FREE(*asc);
05420         return False;
05421 }
05422 
05423 /*******************************************************************
05424 ********************************************************************/  
05425 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
05426                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
05427 {
05428         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
05429         
05430         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
05431         
05432         if (*asc==NULL)
05433         {
05434                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
05435                 if(*asc == NULL)
05436                         return False;
05437                 ZERO_STRUCTP(*asc);
05438         }       
05439 
05440         d=*asc;
05441 
05442         d->version=uni->version;
05443 
05444         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
05445         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
05446         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
05447         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
05448         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
05449         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
05450         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
05451         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
05452 
05453         DEBUGADD(8,( "version:         %d\n", d->version));
05454         DEBUGADD(8,( "name:            %s\n", d->name));
05455         DEBUGADD(8,( "environment:     %s\n", d->environment));
05456         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
05457         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
05458         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
05459         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
05460         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
05461         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
05462 
05463         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
05464                 goto error;
05465         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
05466                 goto error;
05467         
05468         return True;
05469         
05470 error:
05471         SAFE_FREE(*asc);
05472         return False;
05473 }
05474 
05475 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
05476                               NT_PRINTER_INFO_LEVEL_2  *d)
05477 {
05478         DEBUG(7,("Converting from UNICODE to ASCII\n"));
05479         
05480         d->attributes=uni->attributes;
05481         d->priority=uni->priority;
05482         d->default_priority=uni->default_priority;
05483         d->starttime=uni->starttime;
05484         d->untiltime=uni->untiltime;
05485         d->status=uni->status;
05486         d->cjobs=uni->cjobs;
05487         
05488         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
05489         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
05490         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
05491         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
05492         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
05493         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
05494         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
05495         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
05496         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
05497         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
05498         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
05499 
05500         return True;
05501 }
05502 
05503 /*******************************************************************
05504  * init a structure.
05505  ********************************************************************/
05506 
05507 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
05508                                 fstring servername, fstring env_name, uint32 level,
05509                                 RPC_BUFFER *buffer, uint32 offered)
05510 {
05511         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
05512         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
05513 
05514         q_u->level=level;
05515         q_u->buffer=buffer;
05516         q_u->offered=offered;
05517 
05518         return True;
05519 }
05520 
05521 /*******************************************************************
05522  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
05523 ********************************************************************/  
05524 
05525 BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
05526 {
05527         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
05528         depth++;
05529 
05530         if(!prs_align(ps))
05531                 return False;
05532         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
05533                 return False;
05534         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
05535                 return False;
05536 
05537         if(!prs_align(ps))
05538                 return False;
05539                 
05540         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
05541                 return False;
05542         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
05543                 return False;
05544                 
05545         if(!prs_align(ps))
05546                 return False;
05547 
05548         if(!prs_uint32("level", ps, depth, &q_u->level))
05549                 return False;
05550                 
05551         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
05552                 return False;
05553                 
05554         if(!prs_align(ps))
05555                 return False;
05556                 
05557         if(!prs_uint32("offered", ps, depth, &q_u->offered))
05558                 return False;
05559 
05560         return True;
05561 }
05562 
05563 /*******************************************************************
05564  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
05565 ********************************************************************/  
05566 
05567 BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
05568 {               
05569         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
05570         depth++;
05571 
05572         if (!prs_align(ps))
05573                 return False;
05574                 
05575         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
05576                 return False;
05577 
05578         if (!prs_align(ps))
05579                 return False;
05580                 
05581         if (!prs_uint32("needed", ps, depth, &r_u->needed))
05582                 return False;
05583                 
05584         if (!prs_werror("status", ps, depth, &r_u->status))
05585                 return False;
05586 
05587         return True;            
05588 }
05589 
05590 /*******************************************************************
05591 ********************************************************************/  
05592 
05593 BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
05594 {               
05595         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
05596         depth++;
05597 
05598         if (!prs_align(ps))
05599                 return False;
05600                 
05601         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
05602                 return False;
05603 
05604         if (!prs_align(ps))
05605                 return False;
05606                 
05607         if (!prs_uint32("needed", ps, depth, &r_u->needed))
05608                 return False;
05609                 
05610         if (!prs_uint32("returned", ps, depth, &r_u->returned))
05611                 return False;
05612                 
05613         if (!prs_werror("status", ps, depth, &r_u->status))
05614                 return False;
05615 
05616         return True;            
05617 }
05618 
05619 /*******************************************************************
05620 ********************************************************************/  
05621 
05622 BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
05623 {
05624         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
05625         depth++;
05626 
05627         if (!prs_align(ps))
05628                 return False;
05629                 
05630         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
05631                 return False;
05632         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
05633                 return False;
05634                 
05635         if (!prs_align(ps))
05636                 return False;
05637                 
05638         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
05639                 return False;
05640         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
05641                 return False;
05642         
05643         if (!prs_align(ps))
05644                 return False;
05645                 
05646         if (!prs_uint32("level", ps, depth, &q_u->level))
05647                 return False;
05648                 
05649         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
05650                 return False;
05651 
05652         if (!prs_align(ps))
05653                 return False;
05654 
05655         if (!prs_uint32("offered", ps, depth, &q_u->offered))
05656                 return False;
05657 
05658         return True;
05659 }
05660 
05661 /*******************************************************************
05662 ********************************************************************/  
05663 
05664 BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
05665 {
05666         prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
05667         depth++;
05668 
05669         if (!prs_align(ps))
05670                 return False;
05671                 
05672         if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
05673                 return False;
05674         if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
05675                 return False;
05676                 
05677         if (!prs_align(ps))
05678                 return False;
05679         if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
05680                 return False;
05681                 
05682         if (!prs_align(ps))
05683                 return False;
05684         if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
05685                 return False;
05686 
05687         if (!prs_align(ps))
05688                 return False;
05689         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
05690                 return False;
05691 
05692         return True;
05693 }
05694 
05695 /*******************************************************************
05696 ********************************************************************/  
05697 
05698 BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
05699 {               
05700         prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
05701         depth++;
05702 
05703         if (!prs_align(ps))
05704                 return False;
05705                 
05706         if (!prs_werror("status", ps, depth, &r_u->status))
05707                 return False;
05708 
05709         return True;            
05710 }
05711 
05712 /*******************************************************************
05713 ********************************************************************/  
05714 
05715 BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
05716 {               
05717         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
05718         depth++;
05719 
05720         if (!prs_align(ps))
05721                 return False;
05722                 
05723         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
05724                 return False;
05725 
05726         if (!prs_align(ps))
05727                 return False;
05728                 
05729         if (!prs_uint32("needed", ps, depth, &r_u->needed))
05730                 return False;
05731                 
05732         if (!prs_uint32("returned", ps, depth, &r_u->returned))
05733                 return False;
05734                 
05735         if (!prs_werror("status", ps, depth, &r_u->status))
05736                 return False;
05737 
05738         return True;            
05739 }
05740 
05741 /*******************************************************************
05742 ********************************************************************/  
05743 
05744 BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
05745 {
05746         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
05747         depth++;
05748 
05749         if (!prs_align(ps))
05750                 return False;
05751                 
05752         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
05753                 return False;
05754         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
05755                 return False;
05756                 
05757         if (!prs_align(ps))
05758                 return False;
05759                 
05760         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
05761                 return False;
05762         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
05763                 return False;
05764         
05765         if (!prs_align(ps))
05766                 return False;
05767                 
05768         if (!prs_uint32("level", ps, depth, &q_u->level))
05769                 return False;
05770                 
05771         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
05772                 return False;
05773 
05774         if (!prs_align(ps))
05775                 return False;
05776 
05777         if (!prs_uint32("offered", ps, depth, &q_u->offered))
05778                 return False;
05779 
05780         return True;
05781 }
05782 
05783 /*******************************************************************
05784  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
05785 ********************************************************************/  
05786 
05787 BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
05788 {
05789         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
05790         depth++;
05791 
05792         if (!prs_align(ps))
05793                 return False;
05794                 
05795         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
05796                 return False;
05797         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
05798                 return False;
05799                 
05800         if (!prs_align(ps))
05801                 return False;
05802                                 
05803         if (!prs_uint32("level", ps, depth, &q_u->level))
05804                 return False;
05805                 
05806         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
05807                 return False;
05808 
05809         if (!prs_align(ps))
05810                 return False;
05811 
05812         if (!prs_uint32("offered", ps, depth, &q_u->offered))
05813                 return False;
05814 
05815         return True;
05816 }
05817 
05818 /*******************************************************************
05819 ********************************************************************/  
05820 
05821 BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
05822 {               
05823         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
05824         depth++;
05825 
05826         if (!prs_align(ps))
05827                 return False;
05828                 
05829         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
05830                 return False;
05831 
05832         if (!prs_align(ps))
05833                 return False;
05834                 
05835         if (!prs_uint32("needed", ps, depth, &r_u->needed))
05836                 return False;
05837                 
05838         if (!prs_uint32("returned", ps, depth, &r_u->returned))
05839                 return False;
05840                 
05841         if (!prs_werror("status", ps, depth, &r_u->status))
05842                 return False;
05843 
05844         return True;            
05845 }
05846 
05847 /*******************************************************************
05848 ********************************************************************/  
05849 
05850 BOOL spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
05851 {       
05852         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
05853         depth++;
05854 
05855         if(!prs_align(ps))
05856                 return False;
05857         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
05858                 return False;
05859 
05860         if (UNMARSHALLING(ps) && r_u->valuesize) {
05861                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
05862                 if (!r_u->value) {
05863                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
05864                         return False;
05865                 }
05866         }
05867 
05868         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
05869                 return False;
05870 
05871         if(!prs_align(ps))
05872                 return False;
05873 
05874         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
05875                 return False;
05876 
05877         if(!prs_uint32("type", ps, depth, &r_u->type))
05878                 return False;
05879 
05880         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
05881                 return False;
05882 
05883         if (UNMARSHALLING(ps) && r_u->datasize) {
05884                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
05885                 if (!r_u->data) {
05886                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
05887                         return False;
05888                 }
05889         }
05890 
05891         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
05892                 return False;
05893         if(!prs_align(ps))
05894                 return False;
05895 
05896         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
05897                 return False;
05898         if(!prs_werror("status", ps, depth, &r_u->status))
05899                 return False;
05900 
05901         return True;
05902 }
05903 
05904 /*******************************************************************
05905 ********************************************************************/  
05906 
05907 BOOL spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
05908 {
05909         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
05910         depth++;
05911 
05912         if(!prs_align(ps))
05913                 return False;
05914         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
05915                 return False;
05916         if(!prs_uint32("index", ps, depth, &q_u->index))
05917                 return False;
05918         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
05919                 return False;
05920         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
05921                 return False;
05922 
05923         return True;
05924 }
05925 
05926 /*******************************************************************
05927 ********************************************************************/  
05928 
05929 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
05930                 const POLICY_HND *hnd,
05931                 uint32 idx, uint32 valuelen, uint32 datalen)
05932 {
05933         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
05934         q_u->index=idx;
05935         q_u->valuesize=valuelen;
05936         q_u->datasize=datalen;
05937 
05938         return True;
05939 }
05940 
05941 /*******************************************************************
05942 ********************************************************************/  
05943 
05944 BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
05945                                       const POLICY_HND *hnd, const char *key,
05946                                       uint32 size)
05947 {
05948         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
05949         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
05950         q_u->size = size;
05951 
05952         return True;
05953 }
05954 
05955 /*******************************************************************
05956 ********************************************************************/  
05957 BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
05958                                    char* value, uint32 data_type, char* data, uint32 data_size)
05959 {
05960         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
05961         q_u->type = data_type;
05962         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
05963 
05964         q_u->max_len = q_u->real_len = data_size;
05965         q_u->data = (unsigned char *)data;
05966         
05967         return True;
05968 }
05969 
05970 /*******************************************************************
05971 ********************************************************************/  
05972 BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
05973                                      char *key, char* value, uint32 data_type, char* data, 
05974                                      uint32 data_size)
05975 {
05976         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
05977         q_u->type = data_type;
05978         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
05979         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
05980 
05981         q_u->max_len = q_u->real_len = data_size;
05982         q_u->data = (unsigned char *)data;
05983         
05984         return True;
05985 }
05986 
05987 /*******************************************************************
05988 ********************************************************************/  
05989 
05990 BOOL spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
05991 {
05992         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
05993         depth++;
05994 
05995         if(!prs_align(ps))
05996                 return False;
05997         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
05998                 return False;
05999         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
06000                 return False;
06001 
06002         if(!prs_align(ps))
06003                 return False;
06004 
06005         if(!prs_uint32("type", ps, depth, &q_u->type))
06006                 return False;
06007 
06008         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
06009                 return False;
06010 
06011         switch (q_u->type)
06012         {
06013                 case REG_SZ:
06014                 case REG_BINARY:
06015                 case REG_DWORD:
06016                 case REG_MULTI_SZ:
06017                         if (q_u->max_len) {
06018                                 if (UNMARSHALLING(ps))
06019                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
06020                                 if(q_u->data == NULL)
06021                                         return False;
06022                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
06023                                         return False;
06024                         }
06025                         if(!prs_align(ps))
06026                                 return False;
06027                         break;
06028         }       
06029         
06030         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
06031                 return False;
06032 
06033         return True;
06034 }
06035 
06036 /*******************************************************************
06037 ********************************************************************/  
06038 
06039 BOOL spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
06040 {
06041         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
06042         depth++;
06043 
06044         if(!prs_align(ps))
06045                 return False;
06046         if(!prs_werror("status",     ps, depth, &r_u->status))
06047                 return False;
06048 
06049         return True;
06050 }
06051 
06052 /*******************************************************************
06053 ********************************************************************/  
06054 BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
06055 {
06056         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
06057         depth++;
06058 
06059         if (!prs_align(ps))
06060                 return False;
06061         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06062                 return False;
06063 
06064         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
06065                 return False;
06066                 
06067         if (q_u->datatype_ptr) {
06068                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
06069                 return False;
06070         }
06071 
06072         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
06073                 return False;
06074 
06075         return True;
06076 }
06077 
06078 
06079 /*******************************************************************
06080 ********************************************************************/  
06081 BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
06082 {
06083         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
06084         depth++;
06085 
06086         if(!prs_align(ps))
06087                 return False;
06088         if(!prs_werror("status",     ps, depth, &r_u->status))
06089                 return False;
06090 
06091         return True;
06092 }
06093 
06094 /*******************************************************************
06095 ********************************************************************/  
06096 
06097 static BOOL spoolss_io_addform(const char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
06098 {
06099         prs_debug(ps, depth, desc, "spoolss_io_addform");
06100         depth++;
06101         if(!prs_align(ps))
06102                 return False;
06103 
06104         if (ptr!=0)
06105         {
06106                 if(!prs_uint32("flags",    ps, depth, &f->flags))
06107                         return False;
06108                 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
06109                         return False;
06110                 if(!prs_uint32("size_x",   ps, depth, &f->size_x))
06111                         return False;
06112                 if(!prs_uint32("size_y",   ps, depth, &f->size_y))
06113                         return False;
06114                 if(!prs_uint32("left",     ps, depth, &f->left))
06115                         return False;
06116                 if(!prs_uint32("top",      ps, depth, &f->top))
06117                         return False;
06118                 if(!prs_uint32("right",    ps, depth, &f->right))
06119                         return False;
06120                 if(!prs_uint32("bottom",   ps, depth, &f->bottom))
06121                         return False;
06122 
06123                 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
06124                         return False;
06125         }
06126 
06127         return True;
06128 }
06129 
06130 /*******************************************************************
06131 ********************************************************************/  
06132 
06133 BOOL spoolss_io_q_deleteform(const char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
06134 {
06135         prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
06136         depth++;
06137 
06138         if(!prs_align(ps))
06139                 return False;
06140         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06141                 return False;
06142         if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
06143                 return False;
06144 
06145         return True;
06146 }
06147 
06148 /*******************************************************************
06149 ********************************************************************/  
06150 
06151 BOOL spoolss_io_r_deleteform(const char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
06152 {
06153         prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
06154         depth++;
06155 
06156         if(!prs_align(ps))
06157                 return False;
06158         if(!prs_werror("status",        ps, depth, &r_u->status))
06159                 return False;
06160 
06161         return True;
06162 }
06163 
06164 /*******************************************************************
06165 ********************************************************************/  
06166 
06167 BOOL spoolss_io_q_addform(const char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
06168 {
06169         uint32 useless_ptr=1;
06170         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
06171         depth++;
06172 
06173         if(!prs_align(ps))
06174                 return False;
06175         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06176                 return False;
06177         if(!prs_uint32("level",  ps, depth, &q_u->level))
06178                 return False;
06179         if(!prs_uint32("level2", ps, depth, &q_u->level2))
06180                 return False;
06181 
06182         if (q_u->level==1)
06183         {
06184                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
06185                         return False;
06186                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
06187                         return False;
06188         }
06189 
06190         return True;
06191 }
06192 
06193 /*******************************************************************
06194 ********************************************************************/  
06195 
06196 BOOL spoolss_io_r_addform(const char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
06197 {
06198         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
06199         depth++;
06200 
06201         if(!prs_align(ps))
06202                 return False;
06203         if(!prs_werror("status",        ps, depth, &r_u->status))
06204                 return False;
06205 
06206         return True;
06207 }
06208 
06209 /*******************************************************************
06210 ********************************************************************/  
06211 
06212 BOOL spoolss_io_q_setform(const char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
06213 {
06214         uint32 useless_ptr=1;
06215         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
06216         depth++;
06217 
06218         if(!prs_align(ps))
06219                 return False;
06220         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06221                 return False;
06222         if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
06223                 return False;
06224               
06225         if(!prs_align(ps))
06226                 return False;
06227         
06228         if(!prs_uint32("level",  ps, depth, &q_u->level))
06229                 return False;
06230         if(!prs_uint32("level2", ps, depth, &q_u->level2))
06231                 return False;
06232 
06233         if (q_u->level==1)
06234         {
06235                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
06236                         return False;
06237                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
06238                         return False;
06239         }
06240 
06241         return True;
06242 }
06243 
06244 /*******************************************************************
06245 ********************************************************************/  
06246 
06247 BOOL spoolss_io_r_setform(const char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
06248 {
06249         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
06250         depth++;
06251 
06252         if(!prs_align(ps))
06253                 return False;
06254         if(!prs_werror("status",        ps, depth, &r_u->status))
06255                 return False;
06256 
06257         return True;
06258 }
06259 
06260 /*******************************************************************
06261  Parse a SPOOL_R_GETJOB structure.
06262 ********************************************************************/  
06263 
06264 BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
06265 {               
06266         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
06267         depth++;
06268 
06269         if (!prs_align(ps))
06270                 return False;
06271                 
06272         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
06273                 return False;
06274 
06275         if (!prs_align(ps))
06276                 return False;
06277                 
06278         if (!prs_uint32("needed", ps, depth, &r_u->needed))
06279                 return False;
06280                 
06281         if (!prs_werror("status", ps, depth, &r_u->status))
06282                 return False;
06283 
06284         return True;            
06285 }
06286 
06287 /*******************************************************************
06288  Parse a SPOOL_Q_GETJOB structure.
06289 ********************************************************************/  
06290 
06291 BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
06292 {
06293         prs_debug(ps, depth, desc, "");
06294         depth++;
06295 
06296         if(!prs_align(ps))
06297                 return False;
06298 
06299         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
06300                 return False;
06301         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
06302                 return False;
06303         if(!prs_uint32("level", ps, depth, &q_u->level))
06304                 return False;
06305         
06306         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
06307                 return False;
06308 
06309         if(!prs_align(ps))
06310                 return False;
06311         
06312         if(!prs_uint32("offered", ps, depth, &q_u->offered))
06313                 return False;
06314 
06315         return True;
06316 }
06317 
06318 void free_devmode(DEVICEMODE *devmode)
06319 {
06320         if (devmode!=NULL) {
06321                 SAFE_FREE(devmode->dev_private);
06322                 SAFE_FREE(devmode);
06323         }
06324 }
06325 
06326 void free_printer_info_1(PRINTER_INFO_1 *printer)
06327 {
06328         SAFE_FREE(printer);
06329 }
06330 
06331 void free_printer_info_2(PRINTER_INFO_2 *printer)
06332 {
06333         if (printer!=NULL) {
06334                 free_devmode(printer->devmode);
06335                 printer->devmode = NULL;
06336                 SAFE_FREE(printer);
06337         }
06338 }
06339 
06340 void free_printer_info_3(PRINTER_INFO_3 *printer)
06341 {
06342         SAFE_FREE(printer);
06343 }
06344 
06345 void free_printer_info_4(PRINTER_INFO_4 *printer)
06346 {
06347         SAFE_FREE(printer);
06348 }
06349 
06350 void free_printer_info_5(PRINTER_INFO_5 *printer)
06351 {
06352         SAFE_FREE(printer);
06353 }
06354 
06355 void free_printer_info_6(PRINTER_INFO_6 *printer)
06356 {
06357         SAFE_FREE(printer);
06358 }
06359 
06360 void free_printer_info_7(PRINTER_INFO_7 *printer)
06361 {
06362         SAFE_FREE(printer);
06363 }
06364 
06365 void free_job_info_2(JOB_INFO_2 *job)
06366 {
06367     if (job!=NULL)
06368         free_devmode(job->devmode);
06369 }
06370 
06371 /*******************************************************************
06372  * init a structure.
06373  ********************************************************************/
06374 
06375 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
06376                                const fstring string, uint32 printer, uint32 type)
06377 {      
06378         if (q_u == NULL)
06379                 return False;
06380 
06381         init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
06382 
06383         q_u->printer=printer;
06384         q_u->type=type;
06385 
06386         q_u->unknown0=0x0;
06387         q_u->unknown1=0x0;
06388 
06389         return True;
06390 }
06391 
06392 /*******************************************************************
06393  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
06394 ********************************************************************/  
06395 
06396 BOOL spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
06397 {
06398         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
06399         depth++;
06400 
06401         if(!prs_align(ps))
06402                 return False;
06403 
06404         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
06405                 return False;
06406 
06407         if(!prs_align(ps))
06408                 return False;
06409 
06410         if(!prs_uint32("printer", ps, depth, &q_u->printer))
06411                 return False;
06412         if(!prs_uint32("type", ps, depth, &q_u->type))
06413                 return False;
06414         
06415         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
06416                 return False;
06417         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
06418                 return False;
06419 
06420         return True;
06421 }
06422 
06423 /*******************************************************************
06424  Parse a SPOOL_R_REPLYOPENPRINTER structure.
06425 ********************************************************************/  
06426 
06427 BOOL spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
06428 {               
06429         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
06430         depth++;
06431 
06432         if (!prs_align(ps))
06433                 return False;
06434 
06435         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
06436                 return False;
06437 
06438         if (!prs_werror("status", ps, depth, &r_u->status))
06439                 return False;
06440 
06441         return True;            
06442 }
06443 
06444 /*******************************************************************
06445  * init a structure.
06446  ********************************************************************/
06447 BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd, 
06448                                         uint32 condition, uint32 change_id)
06449 {
06450 
06451         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
06452 
06453         q_u->condition = condition;
06454         q_u->change_id = change_id;
06455 
06456         /* magic values */
06457         q_u->unknown1 = 0x1;
06458         memset(q_u->unknown2, 0x0, 5);
06459         q_u->unknown2[0] = 0x1;
06460 
06461         return True;
06462 }
06463 
06464 /*******************************************************************
06465  Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
06466 ********************************************************************/
06467 BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
06468 {
06469 
06470         prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
06471         depth++;
06472 
06473         if (!prs_align(ps))
06474                 return False;
06475 
06476         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
06477                 return False;
06478 
06479         if (!prs_uint32("condition", ps, depth, &q_u->condition))
06480                 return False;
06481 
06482         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
06483                 return False;
06484 
06485         if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
06486                 return False;
06487 
06488         if (!prs_uint8s(False, "dev_private",  ps, depth, q_u->unknown2, 5))
06489                 return False;
06490 
06491         return True;
06492 }
06493 
06494 /*******************************************************************
06495  Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
06496 ********************************************************************/
06497 BOOL spoolss_io_r_routerreplyprinter (const char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
06498 {
06499         prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
06500         depth++;
06501 
06502         if (!prs_align(ps))
06503                 return False;
06504 
06505         if (!prs_werror("status", ps, depth, &r_u->status))
06506                 return False;
06507 
06508         return True;
06509 }
06510 
06511 /*******************************************************************
06512  * init a structure.
06513  ********************************************************************/
06514 
06515 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
06516 {      
06517         if (q_u == NULL)
06518                 return False;
06519 
06520         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
06521 
06522         return True;
06523 }
06524 
06525 /*******************************************************************
06526  Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
06527 ********************************************************************/  
06528 
06529 BOOL spoolss_io_q_replycloseprinter(const char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
06530 {
06531         prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
06532         depth++;
06533 
06534         if(!prs_align(ps))
06535                 return False;
06536 
06537         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
06538                 return False;
06539 
06540         return True;
06541 }
06542 
06543 /*******************************************************************
06544  Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
06545 ********************************************************************/  
06546 
06547 BOOL spoolss_io_r_replycloseprinter(const char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
06548 {               
06549         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
06550         depth++;
06551 
06552         if (!prs_align(ps))
06553                 return False;
06554 
06555         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
06556                 return False;
06557 
06558         if (!prs_werror("status", ps, depth, &r_u->status))
06559                 return False;
06560 
06561         return True;            
06562 }
06563 
06564 #if 0   /* JERRY - not currently used but could be :-) */
06565 
06566 /*******************************************************************
06567  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
06568  ******************************************************************/
06569 static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
06570                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
06571 {
06572         int i;
06573 
06574         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
06575         
06576         for (i=0; i<n; i++) {
06577                 int len;
06578                 uint16 *s = NULL;
06579                 
06580                 if (src->size != POINTER) 
06581                         continue;
06582                 len = src->notify_data.data.length;
06583                 s = SMB_MALLOC_ARRAY(uint16, len);
06584                 if (s == NULL) {
06585                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
06586                         return False;
06587                 }
06588                 
06589                 memcpy(s, src->notify_data.data.string, len*2);
06590                 dst->notify_data.data.string = s;
06591         }
06592         
06593         return True;
06594 }
06595 
06596 /*******************************************************************
06597  Deep copy a SPOOL_NOTIFY_INFO structure
06598  ******************************************************************/
06599 static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
06600 {
06601         if (!dst) {
06602                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
06603                 return False;
06604         }
06605                 
06606         dst->version = src->version;
06607         dst->flags   = src->flags;
06608         dst->count   = src->count;
06609         
06610         if (dst->count) 
06611         {
06612                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
06613                 
06614                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
06615                         dst->count));
06616 
06617                 if (dst->data == NULL) {
06618                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
06619                                 dst->count));
06620                         return False;
06621                 }
06622                 
06623                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
06624         }
06625         
06626         return True;
06627 }
06628 #endif  /* JERRY */
06629 
06630 /*******************************************************************
06631  * init a structure.
06632  ********************************************************************/
06633 
06634 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
06635                                 uint32 change_low, uint32 change_high,
06636                                 SPOOL_NOTIFY_INFO *info)
06637 {      
06638         if (q_u == NULL)
06639                 return False;
06640 
06641         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
06642 
06643         q_u->change_low=change_low;
06644         q_u->change_high=change_high;
06645 
06646         q_u->unknown0=0x0;
06647         q_u->unknown1=0x0;
06648 
06649         q_u->info_ptr=0x0FF0ADDE;
06650 
06651         q_u->info.version=2;
06652         
06653         if (info->count) {
06654                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
06655                         info->count));
06656                 q_u->info.version = info->version;
06657                 q_u->info.flags   = info->flags;
06658                 q_u->info.count   = info->count;
06659                 /* pointer field - be careful! */
06660                 q_u->info.data    = info->data;
06661         }
06662         else  {
06663         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
06664         q_u->info.count=0;
06665         }
06666 
06667         return True;
06668 }
06669 
06670 /*******************************************************************
06671  Parse a SPOOL_Q_REPLY_RRPCN structure.
06672 ********************************************************************/  
06673 
06674 BOOL spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
06675 {
06676         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
06677         depth++;
06678 
06679         if(!prs_align(ps))
06680                 return False;
06681 
06682         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
06683                 return False;
06684 
06685         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
06686                 return False;
06687 
06688         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
06689                 return False;
06690 
06691         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
06692                 return False;
06693 
06694         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
06695                 return False;
06696 
06697         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
06698                 return False;
06699 
06700         if(q_u->info_ptr!=0)
06701                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
06702                         return False;
06703                 
06704         return True;
06705 }
06706 
06707 /*******************************************************************
06708  Parse a SPOOL_R_REPLY_RRPCN structure.
06709 ********************************************************************/  
06710 
06711 BOOL spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
06712 {               
06713         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
06714         depth++;
06715 
06716         if (!prs_align(ps))
06717                 return False;
06718 
06719         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
06720                 return False;
06721 
06722         if (!prs_werror("status", ps, depth, &r_u->status))
06723                 return False;
06724 
06725         return True;            
06726 }
06727 
06728 /*******************************************************************
06729  * read a structure.
06730  * called from spoolss_q_getprinterdataex (srv_spoolss.c)
06731  ********************************************************************/
06732 
06733 BOOL spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
06734 {
06735         if (q_u == NULL)
06736                 return False;
06737 
06738         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
06739         depth++;
06740 
06741         if (!prs_align(ps))
06742                 return False;
06743         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
06744                 return False;
06745         if (!prs_align(ps))
06746                 return False;
06747         if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
06748                 return False;
06749         if (!prs_align(ps))
06750                 return False;
06751         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
06752                 return False;
06753         if (!prs_align(ps))
06754                 return False;
06755         if (!prs_uint32("size", ps, depth, &q_u->size))
06756                 return False;
06757 
06758         return True;
06759 }
06760 
06761 /*******************************************************************
06762  * write a structure.
06763  * called from spoolss_r_getprinterdataex (srv_spoolss.c)
06764  ********************************************************************/
06765 
06766 BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
06767 {
06768         if (r_u == NULL)
06769                 return False;
06770 
06771         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
06772         depth++;
06773 
06774         if (!prs_align(ps))
06775                 return False;
06776         if (!prs_uint32("type", ps, depth, &r_u->type))
06777                 return False;
06778         if (!prs_uint32("size", ps, depth, &r_u->size))
06779                 return False;
06780         
06781         if (UNMARSHALLING(ps) && r_u->size) {
06782                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
06783                 if(!r_u->data)
06784                         return False;
06785         }
06786 
06787         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
06788                 return False;
06789                 
06790         if (!prs_align(ps))
06791                 return False;
06792         
06793         if (!prs_uint32("needed", ps, depth, &r_u->needed))
06794                 return False;
06795         if (!prs_werror("status", ps, depth, &r_u->status))
06796                 return False;
06797                 
06798         return True;
06799 }
06800 
06801 /*******************************************************************
06802  * read a structure.
06803  ********************************************************************/  
06804 
06805 BOOL spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
06806 {
06807         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
06808         depth++;
06809 
06810         if(!prs_align(ps))
06811                 return False;
06812         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06813                 return False;
06814         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
06815                 return False;
06816 
06817         if(!prs_align(ps))
06818                 return False;
06819 
06820         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
06821                 return False;
06822 
06823         if(!prs_align(ps))
06824                 return False;
06825 
06826         if(!prs_uint32("type", ps, depth, &q_u->type))
06827                 return False;
06828 
06829         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
06830                 return False;
06831 
06832         switch (q_u->type)
06833         {
06834                 case 0x1:
06835                 case 0x3:
06836                 case 0x4:
06837                 case 0x7:
06838                         if (q_u->max_len) {
06839                                 if (UNMARSHALLING(ps))
06840                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
06841                                 if(q_u->data == NULL)
06842                                         return False;
06843                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
06844                                         return False;
06845                         }
06846                         if(!prs_align(ps))
06847                                 return False;
06848                         break;
06849         }       
06850         
06851         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
06852                 return False;
06853 
06854         return True;
06855 }
06856 
06857 /*******************************************************************
06858  * write a structure.
06859  ********************************************************************/  
06860 
06861 BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
06862 {
06863         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
06864         depth++;
06865 
06866         if(!prs_align(ps))
06867                 return False;
06868         if(!prs_werror("status",     ps, depth, &r_u->status))
06869                 return False;
06870 
06871         return True;
06872 }
06873 
06874 /*******************************************************************
06875  * read a structure.
06876  ********************************************************************/  
06877 BOOL make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
06878                                    POLICY_HND *hnd, const char *key, 
06879                                    uint32 size)
06880 {
06881         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
06882 
06883         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
06884         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
06885         q_u->size = size;
06886 
06887         return True;
06888 }
06889 
06890 /*******************************************************************
06891  * read a structure.
06892  ********************************************************************/  
06893 
06894 BOOL spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
06895 {
06896         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
06897         depth++;
06898 
06899         if(!prs_align(ps))
06900                 return False;
06901         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06902                 return False;
06903                 
06904         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
06905                 return False;
06906 
06907         if(!prs_align(ps))
06908                 return False;
06909         
06910         if(!prs_uint32("size", ps, depth, &q_u->size))
06911                 return False;
06912 
06913         return True;
06914 }
06915 
06916 /*******************************************************************
06917  * write a structure.
06918  ********************************************************************/  
06919 
06920 BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
06921 {
06922         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
06923         depth++;
06924 
06925         if(!prs_align(ps))
06926                 return False;
06927 
06928         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
06929                 return False;
06930         
06931         if(!prs_align(ps))
06932                 return False;
06933 
06934         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
06935                 return False;
06936 
06937         if(!prs_werror("status",     ps, depth, &r_u->status))
06938                 return False;
06939 
06940         return True;
06941 }
06942 
06943 /*******************************************************************
06944  * read a structure.
06945  ********************************************************************/  
06946 
06947 BOOL make_spoolss_q_deleteprinterkey(SPOOL_Q_DELETEPRINTERKEY *q_u, 
06948                                      POLICY_HND *hnd, char *keyname)
06949 {
06950         DEBUG(5,("make_spoolss_q_deleteprinterkey\n"));
06951 
06952         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
06953         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
06954 
06955         return True;
06956 }
06957 
06958 /*******************************************************************
06959  * read a structure.
06960  ********************************************************************/  
06961 
06962 BOOL spoolss_io_q_deleteprinterkey(const char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
06963 {
06964         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
06965         depth++;
06966 
06967         if(!prs_align(ps))
06968                 return False;
06969         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
06970                 return False;
06971                 
06972         if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
06973                 return False;
06974 
06975         return True;
06976 }
06977 
06978 /*******************************************************************
06979  * write a structure.
06980  ********************************************************************/  
06981 
06982 BOOL spoolss_io_r_deleteprinterkey(const char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
06983 {
06984         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
06985         depth++;
06986 
06987         if(!prs_align(ps))
06988                 return False;
06989                 
06990         if(!prs_werror("status",     ps, depth, &r_u->status))
06991                 return False;
06992 
06993         return True;
06994 }
06995 
06996 
06997 /*******************************************************************
06998  * read a structure.
06999  ********************************************************************/  
07000 
07001 BOOL spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
07002 {
07003         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
07004         depth++;
07005 
07006         if(!prs_align(ps))
07007                 return False;
07008         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
07009                 return False;
07010                 
07011         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
07012                 return False;
07013 
07014         if(!prs_align(ps))
07015                 return False;
07016         
07017         if(!prs_uint32("size", ps, depth, &q_u->size))
07018                 return False;
07019 
07020         return True;
07021 }
07022 
07023 /*******************************************************************
07024 ********************************************************************/  
07025 
07026 static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
07027                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
07028 {
07029         int     i;
07030         uint32  valuename_offset,
07031                 data_offset,
07032                 current_offset;
07033         const uint32 basic_unit = 20; /* size of static portion of enum_values */
07034 
07035         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
07036         depth++;        
07037 
07038         /* 
07039          * offset data begins at 20 bytes per structure * size_of_array.
07040          * Don't forget the uint32 at the beginning 
07041          * */
07042         
07043         current_offset = basic_unit * ctr->size_of_array;
07044         
07045         /* first loop to write basic enum_value information */
07046         
07047         if (UNMARSHALLING(ps) && ctr->size_of_array) {
07048                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
07049                 if (!ctr->values)
07050                         return False;
07051         }
07052 
07053         for (i=0; i<ctr->size_of_array; i++) {
07054                 uint32 base_offset, return_offset;
07055 
07056                 base_offset = prs_offset(ps);
07057 
07058                 valuename_offset = current_offset;
07059                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
07060                         return False;
07061 
07062                 /* Read or write the value. */
07063 
07064                 return_offset = prs_offset(ps);
07065 
07066                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
07067                         return False;
07068                 }
07069 
07070                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
07071                         return False;
07072 
07073                 /* And go back. */
07074                 if (!prs_set_offset(ps, return_offset))
07075                         return False;
07076 
07077                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
07078                         return False;
07079         
07080                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
07081                         return False;
07082         
07083                 data_offset = ctr->values[i].value_len + valuename_offset;
07084                 
07085                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
07086                         return False;
07087 
07088                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
07089                         return False;
07090                         
07091                 /* Read or write the data. */
07092 
07093                 return_offset = prs_offset(ps);
07094 
07095                 if (!prs_set_offset(ps, base_offset + data_offset)) {
07096                         return False;
07097                 }
07098 
07099                 if ( ctr->values[i].data_len ) {
07100                         if ( UNMARSHALLING(ps) ) {
07101                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
07102                                 if (!ctr->values[i].data)
07103                                         return False;
07104                         }
07105                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
07106                                 return False;
07107                 }
07108 
07109                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
07110                 /* account for 2 byte alignment */
07111                 current_offset += (current_offset % 2);
07112 
07113                 /* Remember how far we got. */
07114                 data_offset = prs_offset(ps);
07115 
07116                 /* And go back. */
07117                 if (!prs_set_offset(ps, return_offset))
07118                         return False;
07119 
07120         }
07121 
07122         /* Go to the last data offset we got to. */
07123 
07124         if (!prs_set_offset(ps, data_offset))
07125                 return False;
07126 
07127         /* And ensure we're 2 byte aligned. */
07128 
07129         if ( !prs_align_uint16(ps) )
07130                 return False;
07131 
07132         return True;    
07133 }
07134 
07135 /*******************************************************************
07136  * write a structure.
07137  ********************************************************************/  
07138 
07139 BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
07140 {
07141         uint32 data_offset, end_offset;
07142         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
07143         depth++;
07144 
07145         if(!prs_align(ps))
07146                 return False;
07147 
07148         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
07149                 return False;
07150 
07151         data_offset = prs_offset(ps);
07152 
07153         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
07154                 return False;
07155 
07156         if(!prs_align(ps))
07157                 return False;
07158 
07159         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
07160                 return False;
07161 
07162         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
07163                 return False;
07164 
07165         if(!prs_werror("status",     ps, depth, &r_u->status))
07166                 return False;
07167 
07168         r_u->ctr.size_of_array = r_u->returned;
07169 
07170         end_offset = prs_offset(ps);
07171 
07172         if (!prs_set_offset(ps, data_offset))
07173                 return False;
07174 
07175         if (r_u->ctr.size)
07176                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
07177                         return False;
07178 
07179         if (!prs_set_offset(ps, end_offset))
07180                 return False;
07181         return True;
07182 }
07183 
07184 /*******************************************************************
07185  * write a structure.
07186  ********************************************************************/  
07187 
07188 /* 
07189    uint32 GetPrintProcessorDirectory(
07190        [in] unistr2 *name,
07191        [in] unistr2 *environment,
07192        [in] uint32 level,
07193        [in,out] RPC_BUFFER buffer,
07194        [in] uint32 offered,
07195        [out] uint32 needed,
07196        [out] uint32 returned
07197    );
07198 
07199 */
07200 
07201 BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
07202 {
07203         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
07204 
07205         init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
07206         init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
07207 
07208         q_u->level = level;
07209 
07210         q_u->buffer = buffer;
07211         q_u->offered = offered;
07212 
07213         return True;
07214 }
07215 
07216 BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
07217 {
07218         uint32 ptr;
07219 
07220         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
07221         depth++;
07222 
07223         if(!prs_align(ps))
07224                 return False;   
07225 
07226         if (!prs_uint32("ptr", ps, depth, &ptr)) 
07227                 return False;
07228 
07229         if (ptr) {
07230                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
07231                         return False;
07232         }
07233 
07234         if (!prs_align(ps))
07235                 return False;
07236 
07237         if (!prs_uint32("ptr", ps, depth, &ptr))
07238                 return False;
07239 
07240         if (ptr) {
07241                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
07242                                    ps, depth))
07243                         return False;
07244         }
07245 
07246         if (!prs_align(ps))
07247                 return False;
07248 
07249         if(!prs_uint32("level",   ps, depth, &q_u->level))
07250                 return False;
07251 
07252         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
07253                 return False;
07254         
07255         if(!prs_align(ps))
07256                 return False;
07257 
07258         if(!prs_uint32("offered", ps, depth, &q_u->offered))
07259                 return False;
07260 
07261         return True;
07262 }
07263 
07264 /*******************************************************************
07265  * write a structure.
07266  ********************************************************************/  
07267 
07268 BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
07269 {
07270         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
07271         depth++;
07272 
07273         if(!prs_align(ps))
07274                 return False;
07275 
07276         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
07277                 return False;
07278         
07279         if(!prs_align(ps))
07280                 return False;
07281 
07282         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
07283                 return False;
07284                 
07285         if(!prs_werror("status",     ps, depth, &r_u->status))
07286                 return False;
07287 
07288         return True;
07289 }
07290 
07291 BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
07292 {
07293         prs_struct *ps=&buffer->prs;
07294 
07295         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
07296         depth++;
07297 
07298         buffer->struct_start=prs_offset(ps);
07299 
07300         if (!smb_io_unistr(desc, &info->name, ps, depth))
07301                 return False;
07302 
07303         return True;
07304 }
07305 
07306 /*******************************************************************
07307  * init a structure.
07308  ********************************************************************/
07309 
07310 BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle, 
07311                             int level, FORM *form)
07312 {
07313         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07314         q_u->level = level;
07315         q_u->level2 = level;
07316         memcpy(&q_u->form, form, sizeof(FORM));
07317 
07318         return True;
07319 }
07320 
07321 /*******************************************************************
07322  * init a structure.
07323  ********************************************************************/
07324 
07325 BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle, 
07326                             int level, const char *form_name, FORM *form)
07327 {
07328         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07329         q_u->level = level;
07330         q_u->level2 = level;
07331         memcpy(&q_u->form, form, sizeof(FORM));
07332         init_unistr2(&q_u->name, form_name, UNI_STR_TERMINATE);
07333 
07334         return True;
07335 }
07336 
07337 /*******************************************************************
07338  * init a structure.
07339  ********************************************************************/
07340 
07341 BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, 
07342                                const char *form)
07343 {
07344         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07345         init_unistr2(&q_u->name, form, UNI_STR_TERMINATE);
07346         return True;
07347 }
07348 
07349 /*******************************************************************
07350  * init a structure.
07351  ********************************************************************/
07352 
07353 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, 
07354                             const char *formname, uint32 level, 
07355                             RPC_BUFFER *buffer, uint32 offered)
07356 {
07357         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07358         q_u->level = level;
07359         init_unistr2(&q_u->formname, formname, UNI_STR_TERMINATE);
07360         q_u->buffer=buffer;
07361         q_u->offered=offered;
07362 
07363         return True;
07364 }
07365 
07366 /*******************************************************************
07367  * init a structure.
07368  ********************************************************************/
07369 
07370 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
07371                               uint32 level, RPC_BUFFER *buffer,
07372                               uint32 offered)
07373 {
07374         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07375         q_u->level = level;
07376         q_u->buffer=buffer;
07377         q_u->offered=offered;
07378 
07379         return True;
07380 }
07381 
07382 /*******************************************************************
07383  * init a structure.
07384  ********************************************************************/
07385 
07386 BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, 
07387                            uint32 jobid, uint32 level, uint32 command)
07388 {
07389         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07390         q_u->jobid = jobid;
07391         q_u->level = level;
07392 
07393         /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
07394            the server side code has it marked as unused. */
07395 
07396         q_u->command = command;
07397 
07398         return True;
07399 }
07400 
07401 /*******************************************************************
07402  * init a structure.
07403  ********************************************************************/
07404 
07405 BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
07406                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
07407                            uint32 offered)
07408 {
07409         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07410         q_u->jobid = jobid;
07411         q_u->level = level;
07412         q_u->buffer = buffer;
07413         q_u->offered = offered;
07414 
07415         return True;
07416 }
07417 
07418 /*******************************************************************
07419  * init a structure.
07420  ********************************************************************/
07421 
07422 BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, 
07423                                      POLICY_HND *handle)
07424 {
07425         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07426 
07427         return True;
07428 }
07429 
07430 /*******************************************************************
07431  * init a structure.
07432  ********************************************************************/
07433 
07434 BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, 
07435                                    POLICY_HND *handle)
07436 {
07437         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07438 
07439         return True;
07440 }
07441 
07442 /*******************************************************************
07443  * init a structure.
07444  ********************************************************************/
07445 
07446 BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, 
07447                                     POLICY_HND *handle, uint32 level,
07448                                     char *docname, char *outputfile,
07449                                     char *datatype)
07450 {
07451         DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
07452 
07453         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07454 
07455         ctr->level = level;
07456 
07457         switch (level) {
07458         case 1:
07459                 ctr->docinfo.switch_value = level;
07460 
07461                 ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
07462                 ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
07463                 ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
07464 
07465                 init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, UNI_STR_TERMINATE);
07466                 init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, UNI_STR_TERMINATE);
07467                 init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, UNI_STR_TERMINATE);
07468 
07469                 break;
07470         case 2:
07471                 /* DOC_INFO_2 is only used by Windows 9x and since it
07472                    doesn't do printing over RPC we don't have to worry
07473                    about it. */
07474         default:
07475                 DEBUG(3, ("unsupported info level %d\n", level));
07476                 return False;
07477         }
07478 
07479         return True;
07480 }
07481 
07482 /*******************************************************************
07483  * init a structure.
07484  ********************************************************************/
07485 
07486 BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, 
07487                                   POLICY_HND *handle)
07488 {
07489         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07490 
07491         return True;
07492 }
07493 
07494 /*******************************************************************
07495  * init a structure.
07496  ********************************************************************/
07497 
07498 BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, 
07499                                  POLICY_HND *handle, uint32 data_size,
07500                                  char *data)
07501 {
07502         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07503         q_u->buffer_size = q_u->buffer_size2 = data_size;
07504         q_u->buffer = (unsigned char *)data;
07505         return True;
07506 }
07507 
07508 /*******************************************************************
07509  * init a structure.
07510  ********************************************************************/
07511 
07512 BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u, 
07513                                  POLICY_HND *handle, char *valuename)
07514 {
07515         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07516         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
07517 
07518         return True;
07519 }
07520 
07521 /*******************************************************************
07522  * init a structure.
07523  ********************************************************************/
07524 
07525 BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u, 
07526                                         POLICY_HND *handle, char *key,
07527                                         char *value)
07528 {
07529         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07530         init_unistr2(&q_u->valuename, value, UNI_STR_TERMINATE);
07531         init_unistr2(&q_u->keyname, key, UNI_STR_TERMINATE);
07532 
07533         return True;
07534 }
07535 
07536 /*******************************************************************
07537  * init a structure.
07538  ********************************************************************/
07539 
07540 BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
07541                              uint32 flags, uint32 options, const char *localmachine,
07542                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
07543 {
07544         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
07545 
07546         q_u->flags = flags;
07547         q_u->options = options;
07548 
07549         q_u->localmachine_ptr = 1;
07550 
07551         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
07552 
07553         q_u->printerlocal = printerlocal;
07554 
07555         if (option)
07556                 q_u->option_ptr = 1;
07557 
07558         q_u->option = option;
07559 
07560         return True;
07561 }
07562 
07563 
07564 /*******************************************************************
07565  ********************************************************************/  
07566 
07567 BOOL spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth)
07568 {
07569         prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport");
07570         depth++;
07571 
07572         if(!prs_align(ps))
07573                 return False;   
07574 
07575         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
07576                 return False;
07577                 
07578         if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth))
07579                 return False;
07580 
07581         if (!prs_align(ps))
07582                 return False;
07583 
07584         if(!prs_rpcbuffer("", ps, depth, &q_u->indata))
07585                 return False;
07586                 
07587         if (!prs_align(ps))
07588                 return False;
07589 
07590         if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len))
07591                 return False;
07592         if (!prs_uint32("offered", ps, depth, &q_u->offered))
07593                 return False;
07594         if (!prs_uint32("unknown", ps, depth, &q_u->unknown))
07595                 return False;
07596         
07597         return True;
07598 }
07599 
07600 /*******************************************************************
07601  ********************************************************************/  
07602 
07603 BOOL spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth)
07604 {
07605         prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport");
07606         depth++;
07607 
07608         if(!prs_align(ps))
07609                 return False;
07610         if(!prs_rpcbuffer("", ps, depth, &r_u->outdata))
07611                 return False;
07612                 
07613         if (!prs_align(ps))
07614                 return False;
07615 
07616         if (!prs_uint32("needed", ps, depth, &r_u->needed))
07617                 return False;
07618         if (!prs_uint32("unknown", ps, depth, &r_u->unknown))
07619                 return False;
07620 
07621         if(!prs_werror("status", ps, depth, &r_u->status))
07622                 return False;
07623 
07624         return True;
07625 }
07626 
07627 /*******************************************************************
07628  ********************************************************************/  
07629 
07630 BOOL make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
07631 {
07632         UNISTR string;
07633         
07634         if ( !buf )
07635                 return False;
07636 
07637         init_unistr( &string, dllname );
07638 
07639         if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) )
07640                 return False;
07641 
07642         return True;
07643 }
07644 
07645 /*******************************************************************
07646  ********************************************************************/  
07647  
07648 #define PORT_DATA_1_PAD    540
07649 
07650 static BOOL smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
07651 {
07652         prs_struct *ps = &buf->prs;
07653         uint8 padding[PORT_DATA_1_PAD];
07654 
07655         prs_debug(ps, depth, desc, "smb_io_port_data_1");
07656         depth++;
07657 
07658         if(!prs_align(ps))
07659                 return False;   
07660 
07661         if( !prs_uint16s(True, "portname", ps, depth, p1->portname, MAX_PORTNAME))
07662                 return False;
07663 
07664         if (!prs_uint32("version", ps, depth, &p1->version))
07665                 return False;
07666         if (!prs_uint32("protocol", ps, depth, &p1->protocol))
07667                 return False;
07668         if (!prs_uint32("size", ps, depth, &p1->size))
07669                 return False;
07670         if (!prs_uint32("reserved", ps, depth, &p1->reserved))
07671                 return False;
07672 
07673         if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress, MAX_NETWORK_NAME))
07674                 return False;
07675         if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity, MAX_SNMP_COMM_NAME))
07676                 return False;
07677 
07678         if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
07679                 return False;
07680                 
07681         if( !prs_uint16s(True, "queue", ps, depth, p1->queue, MAX_QUEUE_NAME))
07682                 return False;
07683         if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress, MAX_IPADDR_STRING))
07684                 return False;
07685 
07686         if( !prs_uint8s(False, "", ps, depth, padding, PORT_DATA_1_PAD))
07687                 return False;
07688                 
07689         if (!prs_uint32("port", ps, depth, &p1->port))
07690                 return False;
07691         if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
07692                 return False;
07693         if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
07694                 return False;
07695                 
07696         return True;
07697 }
07698 
07699 /*******************************************************************
07700  ********************************************************************/  
07701 
07702 BOOL convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
07703 {
07704         SPOOL_PORT_DATA_1 spdata_1;
07705         
07706         ZERO_STRUCT( spdata_1 );
07707         
07708         if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
07709                 return False;
07710                 
07711         rpcstr_pull(port1->name, spdata_1.portname, sizeof(port1->name), -1, 0);
07712         rpcstr_pull(port1->queue, spdata_1.queue, sizeof(port1->queue), -1, 0);
07713         rpcstr_pull(port1->hostaddr, spdata_1.hostaddress, sizeof(port1->hostaddr), -1, 0);
07714         
07715         port1->port = spdata_1.port;
07716         
07717         switch ( spdata_1.protocol ) {
07718         case 1:
07719                 port1->protocol = PORT_PROTOCOL_DIRECT;
07720                 break;
07721         case 2:
07722                 port1->protocol = PORT_PROTOCOL_LPR;
07723                 break;
07724         default:
07725                 DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
07726                         spdata_1.protocol));
07727                 return False;
07728         }
07729 
07730         return True;
07731 }
07732 

Sambaに対してSat Aug 29 21:23:19 2009に生成されました。  doxygen 1.4.7