📄 nt_printing.c
字号:
* For Windows 95/98 the version is 0 (so the value sent is correct) * For Windows NT (the architecture doesn't matter) * NT 3.1: cversion=0 * NT 3.5/3.51: cversion=1 * NT 4: cversion=2 * NT2K: cversion=3 */ if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1) return err; return WERR_OK;} /********************************************************************************************************************************************************/static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user){ const char *architecture; fstring new_name; char *p; int i; WERROR err; /* clean up the driver name. * we can get .\driver.dll * or worse c:\windows\system\driver.dll ! */ /* using an intermediate string to not have overlaping memcpy()'s */ if ((p = strrchr(driver->driverpath,'\\')) != NULL) { fstrcpy(new_name, p+1); fstrcpy(driver->driverpath, new_name); } if ((p = strrchr(driver->datafile,'\\')) != NULL) { fstrcpy(new_name, p+1); fstrcpy(driver->datafile, new_name); } if ((p = strrchr(driver->configfile,'\\')) != NULL) { fstrcpy(new_name, p+1); fstrcpy(driver->configfile, new_name); } if ((p = strrchr(driver->helpfile,'\\')) != NULL) { fstrcpy(new_name, p+1); fstrcpy(driver->helpfile, new_name); } if (driver->dependentfiles) { for (i=0; *driver->dependentfiles[i]; i++) { if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) { fstrcpy(new_name, p+1); fstrcpy(driver->dependentfiles[i], new_name); } } } architecture = get_short_archi(driver->environment); /* jfm:7/16/2000 the client always sends the cversion=0. * The server should check which version the driver is by reading * the PE header of driver->driverpath. * * For Windows 95/98 the version is 0 (so the value sent is correct) * For Windows NT (the architecture doesn't matter) * NT 3.1: cversion=0 * NT 3.5/3.51: cversion=1 * NT 4: cversion=2 * NT2K: cversion=3 */ if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1) return err; return WERR_OK;}/********************************************************************************************************************************************************/WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user){ switch (level) { case 3: { NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver; driver=driver_abstract.info_3; return clean_up_driver_struct_level_3(driver, user); } case 6: { NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver; driver=driver_abstract.info_6; return clean_up_driver_struct_level_6(driver, user); } default: return WERR_INVALID_PARAM; }}/**************************************************************************** This function sucks and should be replaced. JRA.****************************************************************************/static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src){ dst->cversion = src->version; fstrcpy( dst->name, src->name); fstrcpy( dst->environment, src->environment); fstrcpy( dst->driverpath, src->driverpath); fstrcpy( dst->datafile, src->datafile); fstrcpy( dst->configfile, src->configfile); fstrcpy( dst->helpfile, src->helpfile); fstrcpy( dst->monitorname, src->monitorname); fstrcpy( dst->defaultdatatype, src->defaultdatatype); dst->dependentfiles = src->dependentfiles;}#if 0 /* Debugging function */static char* ffmt(unsigned char *c){ int i; static char ffmt_str[17]; for (i=0; i<16; i++) { if ((c[i] < ' ') || (c[i] > '~')) ffmt_str[i]='.'; else ffmt_str[i]=c[i]; } ffmt_str[16]='\0'; return ffmt_str;}#endif/********************************************************************************************************************************************************/WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, WERROR *perr){ NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver; NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver; const char *architecture; pstring new_dir; pstring old_name; pstring new_name; DATA_BLOB null_pw; connection_struct *conn; NTSTATUS nt_status; pstring inbuf; pstring outbuf; fstring res_type; BOOL bad_path; SMB_STRUCT_STAT st; int ver = 0; int i; int err; memset(inbuf, '\0', sizeof(inbuf)); memset(outbuf, '\0', sizeof(outbuf)); *perr = WERR_OK; if (level==3) driver=driver_abstract.info_3; else if (level==6) { convert_level_6_to_level3(&converted_driver, driver_abstract.info_6); driver = &converted_driver; } else { DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level )); return WERR_UNKNOWN_LEVEL; } architecture = get_short_archi(driver->environment); /* * Connect to the print$ share under the same account as the user connected to the rpc pipe. * Note we must be root to do this. */ null_pw = data_blob(NULL, 0); fstrcpy(res_type, "A:"); become_root(); conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status); unbecome_root(); if (conn == NULL) { DEBUG(0,("move_driver_to_download_area: Unable to connect\n")); *perr = ntstatus_to_werror(nt_status); return WERR_NO_SUCH_SHARE; } /* * Save who we are - we are temporarily becoming the connection user. */ if (!become_user(conn, conn->vuid)) { DEBUG(0,("move_driver_to_download_area: Can't become user!\n")); return WERR_ACCESS_DENIED; } /* * make the directories version and version\driver_name * under the architecture directory. */ DEBUG(5,("Creating first directory\n")); slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion); driver_unix_convert(new_dir, conn, NULL, &bad_path, &st); mkdir_internal(conn, new_dir, bad_path); /* For each driver file, archi\filexxx.yyy, if there is a duplicate file * listed for this driver which has already been moved, skip it (note: * drivers may list the same file name several times. Then check if the * file already exists in archi\cversion\, if so, check that the version * info (or time stamps if version info is unavailable) is newer (or the * date is later). If it is, move it to archi\cversion\filexxx.yyy. * Otherwise, delete the file. * * If a file is not moved to archi\cversion\ because of an error, all the * rest of the 'unmoved' driver files are removed from archi\. If one or * more of the driver's files was already moved to archi\cversion\, it * potentially leaves the driver in a partially updated state. Version * trauma will most likely occur if an client attempts to use any printer * bound to the driver. Perhaps a rewrite to make sure the moves can be * done is appropriate... later JRR */ DEBUG(5,("Moving files now !\n")); if (driver->driverpath && strlen(driver->driverpath)) { slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { driver_unix_convert(new_name, conn, NULL, &bad_path, &st); if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); *perr = WERR_ACCESS_DENIED; ver = -1; } } } if (driver->datafile && strlen(driver->datafile)) { if (!strequal(driver->datafile, driver->driverpath)) { slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { driver_unix_convert(new_name, conn, NULL, &bad_path, &st); if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); *perr = WERR_ACCESS_DENIED; ver = -1; } } } } if (driver->configfile && strlen(driver->configfile)) { if (!strequal(driver->configfile, driver->driverpath) && !strequal(driver->configfile, driver->datafile)) { slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { driver_unix_convert(new_name, conn, NULL, &bad_path, &st); if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); *perr = WERR_ACCESS_DENIED; ver = -1; } } } } if (driver->helpfile && strlen(driver->helpfile)) { if (!strequal(driver->helpfile, driver->driverpath) && !strequal(driver->helpfile, driver->datafile) && !strequal(driver->helpfile, driver->configfile)) { slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { driver_unix_convert(new_name, conn, NULL, &bad_path, &st); if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); *perr = WERR_ACCESS_DENIED; ver = -1; } } } } if (driver->dependentfiles) { for (i=0; *driver->dependentfiles[i]; i++) { if (!strequal(driver->dependentfiles[i], driver->driverpath) && !strequal(driver->dependentfiles[i], driver->datafile) && !strequal(driver->dependentfiles[i], driver->configfile) && !strequal(driver->dependentfiles[i], driver->helpfile)) { int j; for (j=0; j < i; j++) { if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) { goto NextDriver; } } slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]); slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { driver_unix_convert(new_name, conn, NULL, &bad_path, &st); if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE| OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); *perr = WERR_ACCESS_DENIED; ver = -1; } } } NextDriver: ; } } close_cnum(conn, user->vuid); unbecome_user(); return ver != -1 ? WERR_OK : WERR_UNKNOWN_PRINTER_DRIVER;}/********************************************************************************************************************************************************/static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver){ int len, buflen; const char *architecture; pstring directory; fstring temp_name; pstring key; char *buf; int i, ret; TDB_DATA kbuf, dbuf; architecture = get_short_archi(driver->environment); /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx * \\server is added in the rpc server layer. * It does make sense to NOT store the server's name in the printer TDB. */ slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion); /* .inf files do not always list a file for each of the four standard files. * Don't prepend a path to a null filename, or client claims: * "The server on which the printer resides does not have a suitable * <printer driver name> printer driver installed. Click OK if you * wish to install the driver on your local machine." */ if (strlen(driver->driverpath)) { fstrcpy(temp_name, driver->driverpath); slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name); } if (strlen(driver->datafile)) { fstrcpy(temp_name, driver->datafile); slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name); } if (strlen(driver->configfile)) { fstrcpy(temp_name, driver->configfile); slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name); } if (strlen(driver->helpfile)) { fstrcpy(temp_name, driver->helpfile); slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name); } if (driver->dependentfiles) { for (i=0; *driver->dependentfiles[i]; i++) { fstrcpy(temp_name, driver->dependentfiles[i]); slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", direc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -