summaryrefslogtreecommitdiff
path: root/source3/rpcclient/cmd_spoolss.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpcclient/cmd_spoolss.c')
-rw-r--r--source3/rpcclient/cmd_spoolss.c239
1 files changed, 235 insertions, 4 deletions
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index f79a7042d2..35e09c76e1 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -37,6 +37,49 @@ extern FILE* out_hnd;
extern struct user_creds *usr_creds;
/****************************************************************************
+function to do the mapping between the long architecture name and
+the short one.
+****************************************************************************/
+static BOOL get_short_archi(char *short_archi, char *long_archi)
+{
+ struct table {
+ char *long_archi;
+ char *short_archi;
+ };
+
+ struct table archi_table[]=
+ {
+ {"Windows 4.0", "WIN40" },
+ {"Windows NT x86", "W32X86" },
+ {"Windows NT R4000", "W32MIPS" },
+ {"Windows NT Alpha_AXP", "W32ALPHA" },
+ {"Windows NT PowerPC", "W32PPC" },
+ {NULL, "" }
+ };
+
+ int i=-1;
+
+ DEBUG(107,("Getting architecture dependant directory\n"));
+ do {
+ i++;
+ } while ( (archi_table[i].long_archi!=NULL ) &&
+ StrCaseCmp(long_archi, archi_table[i].long_archi) );
+
+ if (archi_table[i].long_archi==NULL) {
+ DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
+ return FALSE;
+ }
+
+ StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
+
+ DEBUGADD(108,("index: [%d]\n", i));
+ DEBUGADD(108,("long architecture: [%s]\n", long_archi));
+ DEBUGADD(108,("short architecture: [%s]\n", short_archi));
+
+ return TRUE;
+}
+
+/****************************************************************************
nt spoolss query
****************************************************************************/
uint32 cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[])
@@ -520,7 +563,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
/* check (and copy) the command line arguments */
if (argc < 3) {
report(out_hnd, "spooladdprinterex <name> <driver> <port>\n");
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_INVALID_PARAMETER;
}
else
{
@@ -559,7 +602,6 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
report (out_hnd, "cmd_spoolss_addprinterex: FAILED to enumerate ports\n");
return NT_STATUS_NOPROBLEMO;
}
-
}
/*
@@ -584,7 +626,6 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
return NT_STATUS_NOPROBLEMO;
}
-
/*
* Need to build the PRINTER_INFO_2 struct here.
* I think it would be better only to deal with a PRINTER_INFO_2
@@ -641,6 +682,196 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
********************************************************************************/
uint32 cmd_spoolss_addprinterdriver(struct client_info *info, int argc, char *argv[])
{
+ PRINTER_DRIVER_CTR driver_info;
+ DRIVER_INFO_3 info3;
+ fstring arch;
+ fstring srv_name;
+ uint32 result = NT_STATUS_NO_PROBLEMO;
+
+ /* parse the command arguements */
+ if (argc < 2)
+ {
+ report (out_hnd, "spooladdprinterdriver <arch>\\\n");
+ report (out_hnd, "\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
+ report (out_hnd, "\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
+ report (out_hnd, "\t<Default Data Type>:<Comma Separated list of Files>\n");
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ ZERO_STRUCT(info3);
+
+ /* get the enviorment for the driver */
+ if (!get_short_archi(arch, argv[1]))
+ {
+ report (out_hnd, "Unknown architechture [%s]\n", argv[1]);
+ return NT_STATUS_INVALID_PARAMETER;
+
+ }
+ else
+ {
+ set_drv_info_3_env(&info3, arch);
+ }
+
+ /* fill in the other struct members */
+ if (!init_drv_info_3_members(&info3, argv[2]))
+ {
+ report (out_hnd, "Invalid parameter list.\n");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ /* get the server name */
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ /* call AddPrinterDriver() woth an info level 3 */
+ driver_info.info3 = &info3;
+ if ((result=spoolss_addprinterdriver(srv_name, 3, &driver_info)) != NT_STATUS_NO_PROBLEMO)
+ {
+ report( out_hnd, "spoolss_addprinterdriver: Add Printer failed [%d]\n",
+ result);
+ }
+
+ free_drv_info_3(&info3);
+
+ return result;
}
+
+/*******************************************************************************
+ set the version and environment fields of a DRIVER_INFO_3 struct
+ ******************************************************************************/
+void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
+{
+ if (strcmp(arch, "WIN40") == 0)
+ {
+ info->version = 0;
+ init_unistr(&info->architecture, "Windows 4.0");
+ }
+ else if (strcmp(arch, "W32X86") == 0)
+ {
+ info->version = 2;
+ init_unistr(&info->architecture, "Windows NT x86");
+ }
+ else if (strcmp(arch, "W32MIPS") == 0)
+ {
+ info->version = 2;
+ init_unistr(&info->architecture, "Windows NT R4000");
+ }
+ else if (strcmp(arch, "W32ALPHA") == 0)
+ {
+ info->version = 2;
+ init_unistr(&info->architecture, "Windows NT Alpha_AXP");
+ }
+ else if (strcmp(arch, "W32PPC") == 0)
+ {
+ info->version = 2;
+ init_unistr(&info->architecture, "Windows NT PowerPC");
+ }
+ else
+ {
+ DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
+ }
+
+ return;
+}
+
+/********************************************************************************
+ fill in the members of a DRIVER_INFO_3 struct using a character
+ string in the form of
+ <Long Printer Name>:<Driver File Name>:<Data File Name>:\
+ <Config File Name>:<Help File Name>:<Language Monitor Name>:\
+ <Default Data Type>:<Comma Separated list of Files>
+ *******************************************************************************/
+BOOL init_drv_info_3_members (DRIVER_INFO_3 *info, char *args)
+{
+ char *str, *str2;
+ uint32 len, i;
+
+ /* <Long Printer Name> */
+ if ((str = strtok(args, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->name, str);
+
+ /* <Driver File Name> */
+ if ((str = strtok(NULL, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->driverpath, str);
+
+ /* <Data File Name > */
+ if ((str = strtok(NULL, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->datafile, str);
+
+ /* <Config File Name> */
+ if ((str = strtok(NULL, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->configfile, str);
+
+ /* <Help File Name> */
+ if ((str = strtok(NULL, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->helpfile, str);
+
+ /* <Language Monitor Name> */
+ if ((str = strtok(NULL, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->monitorname, str);
+
+ /* <Default Data Type> */
+ if ((str = strtok(NULL, ":")) == NULL)
+ return False;
+ else
+ init_unistr(&info->defaultdatatype, str);
+
+ /* <Comma Separated List of Dependent Files> */
+ str = strtok(NULL, ":"); /* get the list of dependent files */
+ str2 = str; /* save the beginning of the string */
+ str = strtok(str, ","); /* begin to strip out each filename */
+ len = 0;
+ while (str != NULL)
+ {
+ /* keep a cumlative count of the str lengths */
+ len += strlen(str)+1;
+ str = strtok(NULL, ",");
+ }
+
+ /* allocate the space; add one extra slot for a terminating NULL.
+ Each filename is NULL terminated and the end contains a double
+ NULL */
+ if ((info->dependentfiles=(uint16*)malloc((len+1)*sizeof(uint16))) == NULL)
+ {
+ DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
+ return False;
+ }
+ for (i=0; i<len; i++)
+ {
+ info->dependentfiles[i] = (uint16)str2[i];
+ info->dependentfiles[i] = info->dependentfiles[i] << 8;
+ }
+ info->dependentfiles[len+1] = '\0';
+
+ return True;
+}
+
+/*****************************************************************************
+ free any dynamically allocated members
+ ****************************************************************************/
+void free_drv_info_3 (DRIVER_INFO_3 *info)
+{
+ if (info->dependentfiles != NULL)
+ {
+ free(info->dependentfiles);
+ info->dependentfiles = NULL;
+ }
+
+ return;
+}