📄 srv_spoolss_nt.c
字号:
return False; } rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0); rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0); nt_devmode->specversion=devmode->specversion; nt_devmode->driverversion=devmode->driverversion; nt_devmode->size=devmode->size; nt_devmode->fields=devmode->fields; nt_devmode->orientation=devmode->orientation; nt_devmode->papersize=devmode->papersize; nt_devmode->paperlength=devmode->paperlength; nt_devmode->paperwidth=devmode->paperwidth; nt_devmode->scale=devmode->scale; nt_devmode->copies=devmode->copies; nt_devmode->defaultsource=devmode->defaultsource; nt_devmode->printquality=devmode->printquality; nt_devmode->color=devmode->color; nt_devmode->duplex=devmode->duplex; nt_devmode->yresolution=devmode->yresolution; nt_devmode->ttoption=devmode->ttoption; nt_devmode->collate=devmode->collate; nt_devmode->logpixels=devmode->logpixels; nt_devmode->bitsperpel=devmode->bitsperpel; nt_devmode->pelswidth=devmode->pelswidth; nt_devmode->pelsheight=devmode->pelsheight; nt_devmode->displayflags=devmode->displayflags; nt_devmode->displayfrequency=devmode->displayfrequency; nt_devmode->icmmethod=devmode->icmmethod; nt_devmode->icmintent=devmode->icmintent; nt_devmode->mediatype=devmode->mediatype; nt_devmode->dithertype=devmode->dithertype; nt_devmode->reserved1=devmode->reserved1; nt_devmode->reserved2=devmode->reserved2; nt_devmode->panningwidth=devmode->panningwidth; nt_devmode->panningheight=devmode->panningheight; /* * Only change private and driverextra if the incoming devmode * has a new one. JRA. */ if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) { SAFE_FREE(nt_devmode->nt_dev_private); nt_devmode->driverextra=devmode->driverextra; if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) return False; memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra); } *pp_nt_devmode = nt_devmode; return True;}/******************************************************************** * _spoolss_enddocprinter_internal. ********************************************************************/static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle){ Printer_entry *Printer=find_printer_index_by_hnd(p, handle); int snum; if (!Printer) { DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); return WERR_BADFID; } if (!get_printer_snum(p, handle, &snum)) return WERR_BADFID; Printer->document_started=False; print_job_end(snum, Printer->jobid,True); /* error codes unhandled so far ... */ return WERR_OK;}/******************************************************************** * api_spoolss_closeprinter ********************************************************************/WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u){ POLICY_HND *handle = &q_u->handle; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); if (Printer && Printer->document_started) _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */ if (!close_printer_handle(p, handle)) return WERR_BADFID; /* clear the returned printer handle. Observed behavior from Win2k server. Don't think this really matters. Previous code just copied the value of the closed handle. --jerry */ memset(&r_u->handle, '\0', sizeof(r_u->handle)); return WERR_OK;}/******************************************************************** * api_spoolss_deleteprinter ********************************************************************/WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u){ POLICY_HND *handle = &q_u->handle; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); WERROR result; if (Printer && Printer->document_started) _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */ memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle)); result = delete_printer_handle(p, handle); update_c_setprinter(False); return result;}/******************************************************************* * static function to lookup the version id corresponding to an * long architecture string ******************************************************************/static int get_version_id (char * arch){ int i; struct table_node archi_table[]= { {"Windows 4.0", "WIN40", 0 }, {"Windows NT x86", "W32X86", 2 }, {"Windows NT R4000", "W32MIPS", 2 }, {"Windows NT Alpha_AXP", "W32ALPHA", 2 }, {"Windows NT PowerPC", "W32PPC", 2 }, {"Windows IA64", "IA64", 3 }, {"Windows x64", "x64", 3 }, {NULL, "", -1 } }; for (i=0; archi_table[i].long_archi != NULL; i++) { if (strcmp(arch, archi_table[i].long_archi) == 0) return (archi_table[i].version); } return -1;}/******************************************************************** * _spoolss_deleteprinterdriver ********************************************************************/WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u){ fstring driver; fstring arch; NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; struct current_user user; WERROR status; WERROR status_win2k = WERR_ACCESS_DENIED; SE_PRIV se_printop = SE_PRINT_OPERATOR; get_current_user(&user, p); /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, and not a printer admin, then fail */ if ( (user.uid != 0) && !user_has_privileges(user.nt_user_token, &se_printop ) && !user_in_list(uidtoname(user.uid), lp_printer_admin(-1), user.groups, user.ngroups) ) { return WERR_ACCESS_DENIED; } unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); /* check that we have a valid driver name first */ if ((version=get_version_id(arch)) == -1) return WERR_INVALID_ENVIRONMENT; ZERO_STRUCT(info); ZERO_STRUCT(info_win2k); if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { /* try for Win2k driver if "Windows NT x86" */ if ( version == 2 ) { version = 3; if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } } /* otherwise it was a failure */ else { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } } if (printer_driver_in_use(info.info_3)) { status = WERR_PRINTER_DRIVER_IN_USE; goto done; } if ( version == 2 ) { if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) { /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False ); free_a_printer_driver( info_win2k, 3 ); /* this should not have failed---if it did, report to client */ if ( !W_ERROR_IS_OK(status_win2k) ) { status = status_win2k; goto done; } } } status = delete_printer_driver(info.info_3, &user, version, False); /* if at least one of the deletes succeeded return OK */ if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) ) status = WERR_OK; done: free_a_printer_driver( info, 3 ); return status;}/******************************************************************** * spoolss_deleteprinterdriverex ********************************************************************/WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u){ fstring driver; fstring arch; NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; uint32 flags = q_u->delete_flags; BOOL delete_files; struct current_user user; WERROR status; WERROR status_win2k = WERR_ACCESS_DENIED; SE_PRIV se_printop = SE_PRINT_OPERATOR; get_current_user(&user, p); /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, and not a printer admin, then fail */ if ( (user.uid != 0) && !user_has_privileges(user.nt_user_token, &se_printop ) && !user_in_list(uidtoname(user.uid), lp_printer_admin(-1), user.groups, user.ngroups) ) { return WERR_ACCESS_DENIED; } unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); /* check that we have a valid driver name first */ if ((version=get_version_id(arch)) == -1) { /* this is what NT returns */ return WERR_INVALID_ENVIRONMENT; } if ( flags & DPD_DELETE_SPECIFIC_VERSION ) version = q_u->version; ZERO_STRUCT(info); ZERO_STRUCT(info_win2k); status = get_a_printer_driver(&info, 3, driver, arch, version); if ( !W_ERROR_IS_OK(status) ) { /* * if the client asked for a specific version, * or this is something other than Windows NT x86, * then we've failed */ if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) goto done; /* try for Win2k driver if "Windows NT x86" */ version = 3; if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } } if ( printer_driver_in_use(info.info_3) ) { status = WERR_PRINTER_DRIVER_IN_USE; goto done; } /* * we have a couple of cases to consider. * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set, * then the delete should fail if **any** files overlap with * other drivers * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all * non-overlapping files * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES * is set, the do not delete any files * Refer to MSDN docs on DeletePrinterDriverEx() for details. */ delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { /* no idea of the correct error here */ status = WERR_ACCESS_DENIED; goto done; } /* also check for W32X86/3 if necessary; maybe we already have? */ if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) { if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { /* no idea of the correct error here */ free_a_printer_driver( info_win2k, 3 ); status = WERR_ACCESS_DENIED; goto done; } /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files); free_a_printer_driver( info_win2k, 3 ); /* this should not have failed---if it did, report to client */ if ( !W_ERROR_IS_OK(status_win2k) ) goto done; } } status = delete_printer_driver(info.info_3, &user, version, delete_files); if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) ) status = WERR_OK;done: free_a_printer_driver( info, 3 ); return status;}/**************************************************************************** Internal routine for retreiving printerdata ***************************************************************************/static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size ){ REGISTRY_VALUE *val; uint32 size; int data_len; if ( !(val = get_printer_data( printer->info_2, key, value)) ) return WERR_BADFILE; *type = regval_type( val ); DEBUG(5,("get_printer_dataex: allocating %d\n", in_size)); size = regval_size( val ); /* copy the min(in_size, len) */ if ( in_size ) { data_len = (size > in_size) ? in_size : size*sizeof(uint8); /* special case for 0 length values */ if ( data_len ) { if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL ) return WERR_NOMEM; } else { if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL ) return WERR_NOMEM; } } else *data = NULL; *needed = size; DEBUG(5,("get_printer_dataex: copy done\n")); return WERR_OK;}/**************************************************************************** Internal routine for removing printerdata ***************************************************************************/static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value ){ return delete_printer_data( printer->info_2, key, value );}/**************************************************************************** Internal routine for storing printerdata ***************************************************************************/WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -