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

📄 event.c

📁 该项目主要是将wingdows程序直接运行在linux上
💻 C
字号:
/* * event.c * * Copyright (C) 2006  Insigme Co., Ltd * * Authors:  * - Limin Jin * * 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 - Created. *//*  * event.c: event syscall functions * Reference to Kernel-win32 code */#include <linux/module.h>#include "event.h"#include "process.h"#include "thread.h"#include "objwait.h"#include <asm/uaccess.h>#ifdef CONFIG_UNIFIED_KERNELstatic int  EventConstructor(win32_object *, void *);static int  EventReconstructor(win32_object *, void *);static void EventDestructor(win32_object *);static int  EventPoll(struct wait_table_entry *, struct ethread *);struct win32_object_class event_objclass = {	oc_type:	"EVENT",	constructor:	EventConstructor,	reconstructor:	NULL,	destructor:	EventDestructor,	poll:		EventPoll,};/* * notify all waiters of event signal * - returns 1 if no new waiter found (no change made) */extern inline int EventNotifyAllWaiters(win32_object *obj){	struct list_head *waiter;	int i = 0;		spin_lock(&obj->o_wait.lock);	list_for_each(waiter,&obj->o_wait.task_list) {                struct wait_table_entry *wte =			list_entry(waiter,				   struct wait_table_entry,				   wte_wait.task_list);		/* set i to 1 if we change a bit */		i |= test_and_set_bit(0, (unsigned long *)&wte->wte_data) ^ 1;	}	spin_unlock(&obj->o_wait.lock);	return ~i & 1;} /* end EventNotifyAllWaiters() *//* * initialise the event win32_object class */void EventClassInit(void){	InitObjectClass(&event_objclass);} /* end EventClassInit() *//* * open a event object, creating if non-existent */NTSTATUSSTDCALLNtCreateEvent(OUT PHANDLE EventHandle,              IN ACCESS_MASK DesiredAccess,              IN POBJECT_ATTRIBUTES ObjectAttributes,              IN EVENT_TYPE EventType,              IN BOOLEAN InitialState){	HANDLE Handle;		win32_object *obj;		   	struct event_args args;		OBJECT_ATTRIBUTES _ObjectAttributes;	struct ethread *thread;	UNICODE_STRING _ObjectName;	if(!(thread=thread_find())) {		kdebug("***error find thread\n");		return -EINVAL;	}	args.DesiredAccess=DesiredAccess;	args.EventType=EventType;	args.InitialState=InitialState;	if(copy_from_user(&_ObjectAttributes,		ObjectAttributes,sizeof(OBJECT_ATTRIBUTES)))		return -EFAULT;	if(copy_from_user(&_ObjectName,		_ObjectAttributes.ObjectName,sizeof(UNICODE_STRING)))		return -EFAULT;		obj = CreateObject(thread,&event_objclass,		(char*)_ObjectName.Buffer,&args,&Handle);	if (IS_ERR(obj))		return PTR_ERR(obj);	ktrace("*** NtCreateEvent(%p)=%p\n",obj,Handle);	objput(obj);	if(copy_to_user(EventHandle,&Handle,sizeof(HANDLE)))		return -EFAULT;			return STATUS_SUCCESS;	} /* end NtCreateEvent() *//* * open a event object, failing if non-existent */NTSTATUSSTDCALLNtOpenEvent(OUT PHANDLE EventHandle,            IN ACCESS_MASK DesiredAccess,            IN POBJECT_ATTRIBUTES ObjectAttributes){	HANDLE Handle;	win32_object *obj;			struct ethread *thread;	OBJECT_ATTRIBUTES _ObjectAttributes;	UNICODE_STRING _ObjectName;	if(!(thread=thread_find())) {		kdebug("***error find thread\n");		return -EINVAL;			}		if(copy_from_user(&_ObjectAttributes,		ObjectAttributes,sizeof(OBJECT_ATTRIBUTES)))		return -EFAULT;			if(copy_from_user(&_ObjectName,		_ObjectAttributes.ObjectName,sizeof(UNICODE_STRING)))		return -EFAULT;		obj = OpenObject(thread,&event_objclass,		(char*)_ObjectName.Buffer,&Handle);	if (IS_ERR(obj))		return PTR_ERR(obj);		ktrace("*** NtOpenEvent(%p)=%p\n",obj,Handle);	objput(obj);	if(copy_to_user(EventHandle,&Handle,sizeof(HANDLE)))		return -EFAULT;	return STATUS_SUCCESS;}/* end NtOpenEvent() *//* * set an event */NTSTATUSSTDCALLNtSetEvent(IN HANDLE EventHandle,           OUT PLONG PreviousState){	struct win32_event *event;	win32_object *obj;		struct ethread *thread;	if(!(thread=thread_find())) {		kdebug("***error find thread\n");		return -EINVAL;	}		obj = GetObject(thread,EventHandle,&event_objclass);	if (IS_ERR(obj))		return PTR_ERR(obj);		event = obj->o_private;	if(copy_to_user(PreviousState,&(event->we_state),sizeof(LONG)))		return -EFAULT;	write_lock(&event->we_lock);	if (1==event->we_state) {				/* if already set, do nothing */		kdebug("SetEvent: 0\n");	}	else if (waitqueue_active(&obj->o_wait)) {		/* waiters pending */		if (EventNotifyAllWaiters(obj)) {			/* no unnotified waiters attached */			kdebug("SetEvent: 1\n");			event->we_state = 1;		}		else {			/* at least one waiter was notified */			kdebug("SetEvent: 2\n");			event->we_state = event->we_manreset;		}	}	else {		/* no one was waiting */		kdebug("SetEvent: 3\n");		event->we_state = 1;	}	write_unlock(&event->we_lock);	signal_object(obj,1);	ktrace("*** [%d] SetEvent(%p) = 1\n",current->pid,obj);	objput(obj);	return STATUS_SUCCESS;}/* end NtSetEvent() *//* * reset an event */NTSTATUSSTDCALLNtResetEvent(IN HANDLE EventHandle,             OUT PLONG PreviousState){	struct win32_event *event;	win32_object *obj;			struct ethread *thread;	if(!(thread=thread_find())) {		kdebug("***error find thread\n");		return -EINVAL;	}			obj = GetObject(thread,EventHandle,&event_objclass);	if (IS_ERR(obj))		return PTR_ERR(obj);	event = obj->o_private;	if(copy_to_user(PreviousState,&(event->we_state),sizeof(LONG)))		return -EFAULT;			write_lock(&event->we_lock);	event->we_state = 0;	write_unlock(&event->we_lock);	ktrace("*** [%d] ResetEvent(%p) = 1\n",current->pid,obj);	objput(obj);		return STATUS_SUCCESS;}/* end NtResetEvent() *//* * pulse an event */NTSTATUSSTDCALLNtPulseEvent(IN HANDLE EventHandle,             OUT PLONG PreviousState){	struct win32_event *event;	win32_object *obj;		struct ethread *thread;	if(!(thread=thread_find())) {		kdebug("***error find thread\n");		return -EINVAL;	}				obj = GetObject(thread,EventHandle,&event_objclass);	if (IS_ERR(obj))		return PTR_ERR(obj);		event=obj->o_private;	if(copy_to_user(PreviousState,&(event->we_state),sizeof(LONG)))			return -EFAULT;	/* just kick all the waiters */	EventNotifyAllWaiters(obj);	signal_object(obj,1);	ktrace("*** [%d] PulseEvent(%p) = 1\n",current->pid,obj);	objput(obj);	return STATUS_SUCCESS;}/* end NtPulseEvent() *//* * poll the state of an event for WaitFor*() functions * - signal status for this wait entry is stored in wte->wte_data * - wte->wte_data is initialised to 0 by do_wait_for_objects() */static int EventPoll(struct wait_table_entry *wte, struct ethread *filp){	struct win32_event *event = wte->wte_obj->o_private;	int ret;	ktrace("*** [%d] EventPoll(%p[%x],%d)\n",	       current->pid,wte->wte_obj,wte->wte_data,event->we_state);	if (test_bit(0, (unsigned long *)&wte->wte_data)) {		/* already marked as received signal */		ret = POLL_SIG;	}	else {		/* not marked as received signal		 * check event status (may be first iteration)		 */		write_lock(&event->we_lock);		if (event->we_state) {			event->we_state = event->we_manreset;			ret = POLL_SIG;		}		else {			ret = POLL_NOTSIG;		}		write_unlock(&event->we_lock);	}	return ret;} /* end EventPoll() *//* * construct a event (allocate its private data) * - called by CreateObject if the event does not already exists * - called with the object class lock held */static int EventConstructor(win32_object *obj, void *data){	struct event_args *args = data;	struct win32_event *event;	ktrace("EventConstructor(%p,%d,%d)\n",	       obj,!(args->EventType),args->InitialState);	event = (struct win32_event *) kmalloc(sizeof(struct win32_event),					     GFP_KERNEL);	if (!event)		return -ENOMEM;	obj->o_private = event;	rwlock_init(&event->we_lock);	event->we_manreset = !(args->EventType);	event->we_state	= args->InitialState;	return 0;} /* end EventConstructor() *//* * reconstruct a event * - called by CreateObject if the event already exists * - called without the win32_object class lock held */static int EventReconstructor(win32_object *obj, void *data){	/* TODO */	ktrace("EventReconstructor(%p)\n",obj);	return 0;} /* end EventReconstructor() *//* * destroy a event (discard its private data) */static void EventDestructor(win32_object *obj){	ktrace("EventDestructor(%p)\n",obj);	kfree(obj->o_private);} /* end EventDestructor() */#endif

⌨️ 快捷键说明

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