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

📄 object.c

📁 该项目主要是将wingdows程序直接运行在linux上
💻 C
字号:
/* * object.c * * Authors:  * - Chenzhan Hu, Lixing Chu, Limin Jin, Liwei Zhou, Zhiqiang Jiao * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute,   * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). *  * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * This program is free software; you can redistribute it and/or modify it * under the terms of  the GNU General  Public License as published by the * Free Software Foundation; either version 2 of the  License, or (at your * option) any later version. * * Revision History: *   Jan 2006 - Modified. */ /* * object.c:win32 object handling * Reference to Kernel-win32 code */#include <linux/module.h>#include <linux/win32_process.h>#include <linux/mm.h>#include <asm/uaccess.h>#include "win32.h"#ifdef CONFIG_UNIFIED_KERNELextern struct list_head object_class_list;extern spinlock_t object_list_lock;extern int unistr2charstr(PWSTR,LPCSTR);extern wchar_t *getwname(const wchar_t *);extern void putwname(const wchar_t *);/* * fetch an object name into kernelspace, * and object name will be convert into char string */int fetch_oname(struct oname *oname, const char *name){	PWSTR uniname;	int ret;	/* anonymous */	if (!name) {		oname->name = NULL;		oname->nhash = 0;		return 0;	}	/* retrieve the name */	uniname = getwname((PWSTR) name);	oname->name = __getname();		if (IS_ERR(oname->name)) {		ret = PTR_ERR(oname->name);		goto clean_up;	}	if((ret = unistr2charstr(uniname,oname->name)) < 0)		goto clean_up;	oname->nhash = full_name_hash(oname->name,strlen(oname->name));	ret = 0;clean_up:	putwname(uniname);	return ret;} /* end fetch_oname() *//* * initialise the system bits of the object class */void InitObjectClass(struct win32_object_class *clss){	int i;			rwlock_init(&clss->oc_lock);	for (i=0; i<OBJCLASSNOBJSSIZE; i++)		INIT_LIST_HEAD(&clss->oc_nobjs[i]);	INIT_LIST_HEAD(&clss->oc_aobjs);	list_add(&clss->oc_next,&object_class_list);} /* end InitObjectClass() *//* * find an already extant internal object record * - call with object class lock held * - name must be in kernelspace * - leaves object usage incremented * - check the result with IS_ERR() */static win32_object *__FindObject(struct win32_object_class *clss, const struct oname *name){	struct list_head *olist;	win32_object *obj;	/* can't find an anonymous object by name */	if (!name->name)		return ERR_PTR(-ENOENT);		/* search the object class */	list_for_each(olist,&clss->oc_nobjs[name->nhash&OBJCLASSNOBJSMASK]) {		obj = (win32_object*) olist;		if (obj->o_name.nhash==name->nhash &&				strcmp(obj->o_name.name,name->name)==0		   )			goto found_object;	}	return ERR_PTR(-ENOENT);found_object:	objget(obj);	return obj;} /* end __FindObject() *//* * find an already extant internal object record * - name must be in userspace * - leaves object usage incremented * - check the result with IS_ERR() */win32_object *FindObject(struct win32_object_class *clss, const char *name){	struct oname oname;	win32_object *obj;	int err;	/* retrieve the name */	err = fetch_oname(&oname,name);	if (err<0)		return ERR_PTR(err);	/* allocate an object */	read_lock(&clss->oc_lock);	obj = __FindObject(clss,&oname);	read_unlock(&clss->oc_lock);	if (oname.name) 		putname(oname.name);	return obj;} /* end FindObject() *//* * allocate and initialise an internal object record * - name buffer may be stolen from caller (in which case name->name set to 0) * - leaves object usage incremented * - check the result with IS_ERR() * - data is passed to the object class (re)constructor function */static win32_object *_AllocObject(struct win32_object_class *clss,		struct oname *name,		void *data){	win32_object *obj;	int err;	/* need to do the whole thing inside of the class lock, since Win32	 * object-create will open an object of the same name if one exists,	 * and create one if not; but there must be no gap between the search	 * and creation or else two separate processes can create objects of	 * the same name	 */	write_lock(&clss->oc_lock);	/* see if the object already exists */	obj = __FindObject(clss,name);	if (obj!=ERR_PTR(-ENOENT)) {		if (IS_ERR(obj))			goto cleanup_1;		/* call the object reconstructor without the class lock held		 * (since it may wait and since we aren't actually modifying		 * the object class anyway)		 */		write_unlock(&clss->oc_lock);		if (clss->reconstructor) {			err = clss->reconstructor(obj,data);			if (err<0) {				objput(obj);				obj = ERR_PTR(err);			}		}		goto cleanup_0;	}	/* create and initialise an object */	err = -ENOMEM;	obj = (win32_object *) kmalloc(sizeof(win32_object),GFP_KERNEL);	if (!obj) goto cleanup_2;	memset(obj,0,sizeof(win32_object));	atomic_set(&obj->o_count,1);	init_waitqueue_head(&obj->o_wait);#ifdef OBJECT_MAGIC	obj->o_magic = OBJECT_MAGIC;#endif	/* name anonymous objects as "class:objaddr" if so requested */	if (!name->name && ~clss->oc_flags&OCF_DONT_NAME_ANON) {		err = -ENOMEM;		obj->o_name.name = __getname();		if (!obj->o_name.name)			goto cleanup_3;		sprintf(obj->o_name.name,"%s:%p",clss->oc_type,obj);		obj->o_name.nhash = full_name_hash(obj->o_name.name,				strlen(obj->o_name.name));	}	/* cut'n'paste the name from the caller's name buffer */	else {		obj->o_name.name = name->name;		obj->o_name.nhash = name->nhash;		name->name = NULL;	}	/* attach to appropriate object class list */	obj->o_class = clss;	if (obj->o_name.name)		list_add(&obj->o_objlist,				&clss->oc_nobjs[obj->o_name.nhash&OBJCLASSNOBJSMASK]);	else		list_add(&obj->o_objlist,&clss->oc_aobjs);	err = clss->constructor(obj,data); /* call the object constructor */	if (err==0)		goto cleanup_1;	list_del(&obj->o_objlist);cleanup_3:	if (obj->o_name.name) putname(obj->o_name.name);	kfree(obj);cleanup_2:	obj = ERR_PTR(err);cleanup_1:	write_unlock(&clss->oc_lock);cleanup_0:	return obj;} /* end _AllocObject() *//* * allocate an object with the specified name (may be NULL for anonymous) */win32_object *AllocObject(struct win32_object_class *clss,		const char *name,		void *data){	struct oname oname;	win32_object *obj;	int err;	/* retrieve the name */	err = fetch_oname(&oname,name);	if (err<0)		return ERR_PTR(err);	/* allocate an object */	obj = _AllocObject(clss,&oname,data);	if (oname.name) putname(oname.name);	return obj;} /* end AllocObject() *//* * create an object and attach it to a process handle * - pulls name into a kmalloc'd buffer * - leaves object usage incremented * - check the result with IS_ERR() * - handle returned in *hObject */win32_object *CreateObject(struct ethread *thread,		struct win32_object_class *clss,		const char *name,		void *data,		HANDLE *hObject		){	struct eprocess *process;	struct oname oname;	win32_object *obj, **ppobj, **epobj;	int err;	*hObject = NULL;	/* retrieve the name */	err = fetch_oname(&oname,name);	if (err<0)		return ERR_PTR(err);	/* allocate an object */	obj = _AllocObject(clss,&oname,data);	if (oname.name) 		putname(oname.name);	if (IS_ERR(obj))		return obj;	/* find a handle slot */	process = get_eprocess(thread);	epobj = &process->ep_handles[MAXHANDLES];	write_lock(&process->ep_lock);	for (ppobj=process->ep_handles; ppobj<epobj; ppobj++) {		if (!*ppobj)			goto found_handle;	}	write_unlock(&process->ep_lock);	objput(obj);	return ERR_PTR(-EMFILE);found_handle:	/* make link to object */	objget(obj);	*ppobj = obj;	write_unlock(&process->ep_lock);	ppobj++; /* don't use the NULL handle */	*hObject = (HANDLE) ((char*)ppobj - (char*)process->ep_handles);	return obj;} /* end CreateObject() *//* * search for an object by name, and attach to it if in existence * - leaves object usage incremented * - check the result with IS_ERR() * - handle returned in Win32serverIoctl structure */win32_object *OpenObject(struct ethread *thread,		struct win32_object_class *clss,		const char *name,		HANDLE *hObject		){	struct eprocess *process;	struct oname oname;	win32_object *obj, **ppobj, **epobj;	int err;	*hObject = NULL;	/* retrieve the name */	err = fetch_oname(&oname,name);	if (err<0)		return ERR_PTR(err);	/* allocate an object */	read_lock(&clss->oc_lock);	obj = __FindObject(clss,&oname);	read_unlock(&clss->oc_lock);	if (oname.name) putname(oname.name);	if (IS_ERR(obj))		return obj;	/* find a handle slot */	process = get_eprocess(thread);	epobj = &process->ep_handles[MAXHANDLES];	write_lock(&process->ep_lock);	for (ppobj=process->ep_handles; ppobj<epobj; ppobj++)		if (!*ppobj)			goto found_handle;	write_unlock(&process->ep_lock);	objput(obj);	return ERR_PTR(-EMFILE);found_handle:	/* make link to object */	objget(obj);	*ppobj = obj;	write_unlock(&process->ep_lock);	ppobj++; /* don't use the NULL handle */	*hObject = (HANDLE) ((char*)ppobj - (char*)process->ep_handles);	return obj;} /* end OpenObject() *//* * find the object associated with a handle * - leaves object usage incremented * - check the result with IS_ERR() */win32_object *GetObject(struct ethread *thread,		HANDLE handle,		struct win32_object_class *clss){	struct eprocess *process;	win32_object *obj;	/* validate the handle */	if (handle<MINHANDLE ||			handle>=MAXHANDLE ||			((__u32)handle & (sizeof(win32_object*)-1))	   )		return ERR_PTR(-EINVAL);	process = get_eprocess(thread);	read_lock(&process->ep_lock);	obj = *(win32_object**) ((char*)process->ep_handles +			(int)handle - sizeof(win32_object*)			);	if (!obj)		goto out;	if (clss && obj->o_class!=clss)		goto bad_object_type;	objget(obj);	read_unlock(&process->ep_lock);out:	return obj ? obj : ERR_PTR(-EBADF);	/* trying to do operation not available on this object type */bad_object_type:	read_unlock(&process->ep_lock);	return ERR_PTR(-EIO);} /* end GetObject() *//* * decrement an object's usage count * - when usage count reaches zero, the object is destroyed * - uses the class's rwlock to govern access to the count */void objput(win32_object *obj){	if (!obj) return;#ifdef OBJECT_MAGIC	if (obj->o_magic!=OBJECT_MAGIC)		panic("bad object magic\n");#endif	write_lock(&obj->o_class->oc_lock);	if (!atomic_dec_and_test(&obj->o_count))		goto still_in_use;#ifdef OBJECT_MAGIC	obj->o_magic = 0x01010101;#endif	list_del(&obj->o_objlist);	obj->o_class->destructor(obj);	write_unlock(&obj->o_class->oc_lock);	/* quick insanity check */	if (waitqueue_active(&obj->o_wait)) {		kdebug(KERN_ALERT				"win32:"				" object being deleted is still being waited upon\n");		return;	}	if (obj->o_name.name) 		putname(obj->o_name.name);	kfree(obj);	return;still_in_use:	write_unlock(&obj->o_class->oc_lock);} /* end objput() */#endif

⌨️ 快捷键说明

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