⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nt_printing.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			return 0;		}		*list = tl;		(*list)[n] = form;		n++;	}		return n;}/****************************************************************************write a form struct list****************************************************************************/int write_ntforms(nt_forms_struct **list, int number){	pstring buf, key;	int len;	TDB_DATA kbuf,dbuf;	int i;	for (i=0;i<number;i++) {		/* save index, so list is rebuilt in correct order */		len = tdb_pack(buf, sizeof(buf), "dddddddd",			       i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,			       (*list)[i].left, (*list)[i].top, (*list)[i].right,			       (*list)[i].bottom);		if (len > sizeof(buf)) break;		slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);		kbuf.dsize = strlen(key)+1;		kbuf.dptr = key;		dbuf.dsize = len;		dbuf.dptr = buf;		if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;       }       return i;}/****************************************************************************add a form struct at the end of the list****************************************************************************/BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count){	int n=0;	BOOL update;	fstring form_name;	nt_forms_struct *tl;	/*	 * NT tries to add forms even when	 * they are already in the base	 * only update the values if already present	 */	update=False;		unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);	for (n=0; n<*count; n++) {		if ( strequal((*list)[n].name, form_name) ) {			update=True;			break;		}	}	if (update==False) {		if((tl=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {			DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));			return False;		}		*list = tl;		unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);		(*count)++;	}		(*list)[n].flag=form->flags;	(*list)[n].width=form->size_x;	(*list)[n].length=form->size_y;	(*list)[n].left=form->left;	(*list)[n].top=form->top;	(*list)[n].right=form->right;	(*list)[n].bottom=form->bottom;	DEBUG(6,("add_a_form: Successfully %s form [%s]\n", 		update ? "updated" : "added", form_name));	return True;}/**************************************************************************** Delete a named form struct.****************************************************************************/BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret){	pstring key;	TDB_DATA kbuf;	int n=0;	fstring form_name;	*ret = WERR_OK;	unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);	for (n=0; n<*count; n++) {		if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {			DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));			break;		}	}	if (n == *count) {		DEBUG(10,("delete_a_form, [%s] not found\n", form_name));		*ret = WERR_INVALID_PARAM;		return False;	}	slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);	kbuf.dsize = strlen(key)+1;	kbuf.dptr = key;	if (tdb_delete(tdb_forms, kbuf) != 0) {		*ret = WERR_NOMEM;		return False;	}	return True;}/**************************************************************************** Update a form struct.****************************************************************************/void update_a_form(nt_forms_struct **list, const FORM *form, int count){	int n=0;	fstring form_name;	unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);	DEBUG(106, ("[%s]\n", form_name));	for (n=0; n<count; n++) {		DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));		if (!strncmp((*list)[n].name, form_name, strlen(form_name)))			break;	}	if (n==count) return;	(*list)[n].flag=form->flags;	(*list)[n].width=form->size_x;	(*list)[n].length=form->size_y;	(*list)[n].left=form->left;	(*list)[n].top=form->top;	(*list)[n].right=form->right;	(*list)[n].bottom=form->bottom;}/**************************************************************************** Get the nt drivers list. Traverse the database and look-up the matching names.****************************************************************************/int get_ntdrivers(fstring **list, const char *architecture, uint32 version){	int total=0;	const char *short_archi;	fstring *fl;	pstring key;	TDB_DATA kbuf, newkey;	short_archi = get_short_archi(architecture);	slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);	for (kbuf = tdb_firstkey(tdb_drivers);	     kbuf.dptr;	     newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {		if (strncmp(kbuf.dptr, key, strlen(key)) != 0)			continue;				if((fl = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {			DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));			return -1;		}		else *list = fl;		fstrcpy((*list)[total], kbuf.dptr+strlen(key));		total++;	}	return(total);}/****************************************************************************function to do the mapping between the long architecture name andthe short one.****************************************************************************/const char *get_short_archi(const char *long_archi){        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(10,("Unknown architecture [%s] !\n", long_archi));                return NULL;        }	/* this might be client code - but shouldn't this be an fstrcpy etc? */        DEBUGADD(108,("index: [%d]\n", i));        DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));        DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));	return archi_table[i].short_archi;}/**************************************************************************** Version information in Microsoft files is held in a VS_VERSION_INFO structure. There are two case to be covered here: PE (Portable Executable) and NE (New Executable) files. Both files support the same INFO structure, but PE files store the signature in unicode, and NE files store it as !unicode. returns -1 on error, 1 on version info found, and 0 on no version info found.****************************************************************************/static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor){	int     i;	char    *buf = NULL;	ssize_t byte_count;	if ((buf=SMB_MALLOC(PE_HEADER_SIZE)) == NULL) {		DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",				fname, PE_HEADER_SIZE));		goto error_exit;	}	/* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */	if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {		DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",			 fname, (unsigned long)byte_count));		goto no_version_info;	}	/* Is this really a DOS header? */	if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {		DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",				fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));		goto no_version_info;	}	/* Skip OEM header (if any) and the DOS stub to start of Windows header */	if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {		DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",				fname, errno));		/* Assume this isn't an error... the file just looks sort of like a PE/NE file */		goto no_version_info;	}	if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {		DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",			 fname, (unsigned long)byte_count));		/* Assume this isn't an error... the file just looks sort of like a PE/NE file */		goto no_version_info;	}	/* The header may be a PE (Portable Executable) or an NE (New Executable) */	if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {		unsigned int num_sections;		unsigned int section_table_bytes;				if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {			DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",					fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));			/* At this point, we assume the file is in error. It still could be somthing			 * else besides a PE file, but it unlikely at this point.			 */			goto error_exit;		}		/* get the section table */		num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);		section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;		if (section_table_bytes == 0)			goto error_exit;		SAFE_FREE(buf);		if ((buf=SMB_MALLOC(section_table_bytes)) == NULL) {			DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",					fname, section_table_bytes));			goto error_exit;		}		if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {			DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",				 fname, (unsigned long)byte_count));			goto error_exit;		}		/* Iterate the section table looking for the resource section ".rsrc" */		for (i = 0; i < num_sections; i++) {			int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;			if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {				unsigned int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);				unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);				if (section_bytes == 0)					goto error_exit;				SAFE_FREE(buf);				if ((buf=SMB_MALLOC(section_bytes)) == NULL) {					DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",							fname, section_bytes));					goto error_exit;				}				/* Seek to the start of the .rsrc section info */				if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {					DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",							fname, errno));					goto error_exit;				}				if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {					DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",						 fname, (unsigned long)byte_count));					goto error_exit;				}				if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)					goto error_exit;				for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {					/* Scan for 1st 3 unicoded bytes followed by word aligned magic value */					if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {						/* Align to next long address */						int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;						if (IVAL(buf,pos) == VS_MAGIC_VALUE) {							*major = IVAL(buf,pos+VS_MAJOR_OFFSET);							*minor = IVAL(buf,pos+VS_MINOR_OFFSET);														DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",									  fname, *major, *minor,									  (*major>>16)&0xffff, *major&0xffff,									  (*minor>>16)&0xffff, *minor&0xffff));							SAFE_FREE(buf);							return 1;						}					}				}			}		}		/* Version info not found, fall back to origin date/time */		DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));		SAFE_FREE(buf);		return 0;	} else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {		if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {			DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",					fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));			/* At this point, we assume the file is in error. It still could be somthing			 * else besides a NE file, but it unlikely at this point. */			goto error_exit;		}		/* Allocate a bit more space to speed up things */		SAFE_FREE(buf);		if ((buf=SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {			DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",					fname, PE_HEADER_SIZE));			goto error_exit;		}		/* This is a HACK! I got tired of trying to sort through the messy		 * 'NE' file format. If anyone wants to clean this up please have at		 * it, but this works. 'NE' files will eventually fade away. JRR */		while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {			/* Cover case that should not occur in a well formed 'NE' .dll file */			if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;			for(i=0; i<byte_count; i++) {				/* Fast skip past data that can't possibly match */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -