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

📄 thread.c

📁 该项目主要是将wingdows程序直接运行在linux上
💻 C
字号:
/* * thread.c * * Copyright (C) 2006  Insigme Co., Ltd * * 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 - Created. */ /* * thread.c: win32 thread handling * Reference to Kernel-win32 code */#include <linux/module.h>#include <linux/win32_process.h>#include <linux/mm.h>#include <asm/uaccess.h>#include <asm/ldt.h>#include "objwait.h"#include "thread.h"#include "apc.h"#ifdef CONFIG_UNIFIED_KERNELstatic int  ThreadConstructor(win32_object *, void *);static int  ThreadReconstructor(win32_object *, void *);static void ThreadDestructor(win32_object *);static int  ThreadPoll(struct wait_table_entry *, struct ethread *);asmlinkage int set_win_fs(struct user_desc *info);struct win32_object_class thread_objclass = {		oc_type:	"THRD ",		constructor:	ThreadConstructor,		reconstructor:	NULL,		destructor:	ThreadDestructor,		poll:		ThreadPoll,};static void ThreadClose(struct ethread *);static int  ThreadSignal(struct ethread *, int);static void ThreadExit(struct ethread *, int);static void ThreadExecve(struct ethread *);static void ThreadFork(struct ethread *,		struct task_struct *,		struct task_struct *,		unsigned long);static const struct ethread_operations ethread_ops = {		name:		"ethread",		owner:		THIS_MODULE,		close:		ThreadClose,		exit:		ThreadExit,		signal:		ThreadSignal,		execve:		ThreadExecve,		fork:		ThreadFork};#define	arch_init_thread	i386_init_thread#define	i386_init_thread(th, ctx)	do { } while (0)void __attribute__((regparm(3)))set_trap_frame(unsigned long esp, task_t *tsk){	if (tsk->ethread) 		tsk->ethread->tcb.trap_frame = (struct ktrap_frame *)esp;}       /* * initialise the thread object class */void ThreadClassInit(void){	InitObjectClass(&thread_objclass);} /* end ThreadClassInit() *//* * poll the state of a thread for WaitFor*() functions * - if signalled, sets to non-signalled before returning */static int ThreadPoll(struct wait_table_entry *wte, struct ethread *_thread){	struct ethread *thread = wte->wte_obj->o_private;	int ret;	ret = (thread->tcb.state==Running) ? POLL_NOTSIG : POLL_SIG;	return ret;} /* end ThreadPoll() *//* * construct a thread (allocate its private data) * - called by CreateObject if the thread does not already exist * - called with the object class lock held */static int ThreadConstructor(win32_object *obj, void *data){	struct ethread_cons_data *etcd = data;	struct eprocess *process;	struct ethread *thread;	ktrace("ThreadConstructor\n");	if (!etcd->etcd_process ||			etcd->etcd_process->o_class!=&process_objclass	   ) {		return -EINVAL;	}	process = (struct eprocess *) etcd->etcd_process->o_private;		thread = (struct ethread *) kmalloc(sizeof(struct ethread),			GFP_KERNEL);	if (!thread)		return -ENOMEM;	obj->o_private = thread;		thread->et_obj = obj;	thread->et_task = etcd->etcd_task;	thread->et_ops = (struct ethread_operations *)&ethread_ops;	atomic_set(&thread->et_count,0);	/* attach to the containing process */	write_lock(&process->ep_lock);	objget(etcd->etcd_process);	thread->threads_process = process;	write_unlock(&process->ep_lock);	EThreadInit(thread, process);	/* create a thread object and hook in to the Linux task */	try_module_get(THIS_MODULE);	add_ethread(thread->et_task, thread);	objget(obj);	return 0;} /* end ThreadConstructor() *//* initialize ethread */void EThreadInit(struct ethread *thread, struct eprocess *process){	ktrace("EThreadInit\n");	/* FIXME: PsCreateCidHandle(Thread, PsThreadType, &Thread->Cid.UniqueThread) */	INIT_LIST_HEAD(&thread->lpc_reply_chain);	INIT_LIST_HEAD(&thread->irp_list);	INIT_LIST_HEAD(&thread->active_timer_list_head);	thread->active_timer_list_lock = SPIN_LOCK_UNLOCKED;	sema_init(&thread->lpc_reply_semaphore, 0);	thread->cid.unique_process = process->unique_processid;	thread->threads_process = process;	thread->win32_start_address = 0;	/* context->Eax, default is 0 */	list_add_tail(&thread->thread_list_entry, &process->thread_list_head);} /* end EThreadInit *//* initialize kthread */void KThreadInit(struct kthread *thread, struct eprocess *process){	ktrace("KThreadInit\n");	INIT_DISP_HEADER(&thread->header, thread_object, sizeof(struct ethread), false);	/* initialize the mutant list */	INIT_LIST_HEAD(&thread->mutant_list_head);	/* setup apc fields */	INIT_LIST_HEAD(&thread->apc_state.apc_list_head[0]);	INIT_LIST_HEAD(&thread->apc_state.apc_list_head[1]);	INIT_LIST_HEAD(&thread->saved_apc_state.apc_list_head[0]);	INIT_LIST_HEAD(&thread->saved_apc_state.apc_list_head[1]);	thread->apc_state.process = (struct kprocess * )process;	thread->apc_state_pointer[OriginalApcEnvironment] = &thread->apc_state;	thread->apc_state_pointer[AttachedApcEnvironment] = &thread->saved_apc_state;	thread->apc_state_index = OriginalApcEnvironment;	thread->apc_queue_lock = SPIN_LOCK_UNLOCKED;	thread->apc_queueable = true;	/* initialize the suspend semaphore */	/* FIXME: sema_init(&thread->suspend_semaphore, 0); */	/* FIXME: keinitializetimer(&thread->timer); */	/*	 * establish the pde's for the new stack and the thread structure within the	 * address space of the new process. they are accessed while taskswitching or	 * while handling page faults. at this point it isn't possible to call the	 * page fault handler for the missing pde's.	 */	arch_init_thread(thread, context);	thread->base_priority = process->pcb.base_priority;	thread->quantum = process->pcb.quantum_reset;	thread->quantum_reset = process->pcb.quantum_reset;	thread->affinity = process->pcb.affinity;	thread->priority = process->pcb.base_priority;	thread->user_affinity = process->pcb.affinity;	thread->disable_boost = process->pcb.disable_boost;	thread->auto_alignment = process->pcb.auto_alignment;#if defined(_M_IX86)	thread->iopl = process->pcb.iopl;#endif	/* set the thread to initalized */	thread->state = Initialized;	list_add_tail(&thread->thread_list_entry, &process->pcb.thread_list_head);} /* end KThreadInit *//* * reconstruct a thread (allocate its private data) * - called by CreateObject if the thread already exists * - called without the object class lock held */static int ThreadReconstructor(win32_object *obj, void *data){	/* TODO */	return -ENOANO;} /* end ThreadReconstructor() *//* * destroy a thread (discard its private data) */static void ThreadDestructor(win32_object *obj){	struct ethread *thread;	struct eprocess *process;	BOOLEAN last;	ktrace("ThreadDestructor, obj %p\n", obj);	thread = obj->o_private;	process = thread->threads_process;	/* detach from the containing process */	list_del(&thread->thread_list_entry);	list_del(&thread->tcb.thread_list_entry);	last = list_empty(&process->thread_list_head);	if (thread->tcb.state != Terminated)		remove_ethread(thread->et_task, thread);	/* if it's the last thread, terminate the process */	if (last)		objput(process->ep_obj);	kfree(obj->o_private);} /* end ThreadDestructor() *//* * thread object destructor */static void ThreadClose(struct ethread *thread){	/* detach the thread record from the Linux task */	ktrace("ThreadClose, obj %p\n", thread->et_obj);	thread->et_task = NULL;	thread->tcb.state = Terminated;	objput(thread->et_obj);} /* end ThreadClose() *//* * notification of exit * - the exit_status is as sys_wait() would return * - notification includes fatal signals */static void ThreadExit(struct ethread *thread, int exit_status){	ktrace("ThreadExit\n");	thread->exit_status = exit_status;} /* end ThreadExit() *//* * notification of signal */static int ThreadSignal(struct ethread *thread, int signal){	return WIN32_THREAD_SIGNAL_OKAY;} /* end ThreadSignal() *//* * notification of execve * - if this is NULL, a thread object will be destroyed on execve */static void ThreadExecve(struct ethread *thread){	/* TODO */} /* end ThreadExecve() *//* * notification that fork/clone has set up the new process and * is just about to dispatch it * - no threads will have been copied by default */static void ThreadFork(struct ethread *thread,		struct task_struct *parent,		struct task_struct *child,		unsigned long clone_flags){	/* TODO */} /* end ThreadFork() *//* find the current thread */struct ethread *thread_find(void){	struct ethread *thread;	ktrace("thread_find\n");	read_lock(&current->alloc_lock);	thread = current->ethread;	read_unlock(&current->alloc_lock);	return thread;} /* end thread_find() *//* * set teb on fs */int set_teb_selector(long teb){	struct user_desc info;	unsigned int	fs = TEB_SELECTOR;	info.entry_number = fs >> 3;	info.base_addr = teb;	info.limit = 1;	info.contents = 0;	info.read_exec_only = 0;	info.seg_not_present = 0;	info.seg_32bit = 1;	info.limit_in_pages = 1;	info.useable = 0;	return set_win_fs(&info);} /* end set_teb_selector *//* create teb */PTEB create_teb(struct eprocess *process,            PCLIENT_ID client_id,			unsigned long stack_top){	PTEB teb, kteb;	unsigned long	addr = TEB_BASE + PAGE_SIZE;	unsigned long	brk_res;	struct mm_struct	*mm = current->mm;	struct vm_area_struct	*vma;	ktrace("create_teb\n");	/* Allocate the TEB */	kteb = kmalloc(sizeof(TEB), GFP_KERNEL);	if (!kteb)		return ERR_PTR(-ENOMEM);	do	{		addr -= PAGE_SIZE;		vma = find_vma(mm, addr);	} while (vma && vma->vm_start < addr + PAGE_SIZE);	down_write(&mm->mmap_sem);	brk_res = do_brk(addr, PAGE_SIZE);	up_write(&mm->mmap_sem);	if (brk_res == addr)		teb = (PTEB)addr;	else {		kfree(kteb);		return ERR_PTR(-EINVAL);	}	/* Initialize the PEB */	memset(kteb, 0, sizeof(TEB));	/* Set TIB Data */	kteb->Tib.ExceptionList = (PVOID)0xFFFFFFFF;	kteb->Tib.DUMMYUNIONNAME.Version = 1;	kteb->Tib.Self = (PNT_TIB)teb;	/* Set TEB Data */	if (client_id) {		kteb->Cid = *client_id;		kteb->RealClientId = *client_id;	}	else {		memset(&kteb->Cid, 0, sizeof(CLIENT_ID));		memset(&kteb->RealClientId, 0, sizeof(CLIENT_ID));	}	kteb->Peb = process->peb;	kteb->CurrentLocale = 0;	/* FIXME: PsDefaultThreadLocaleId; */	kteb->Tib.StackBase = (PVOID)stack_top;	kteb->Tib.StackLimit = (PVOID)(stack_top - 0x400000);	kteb->DeallocationStack = 0;	if (copy_to_user(teb, kteb, sizeof(TEB))) {		kfree(kteb);		return ERR_PTR(-EFAULT);	}	/* Return TEB Address */	kfree(kteb);	return teb;}#endif

⌨️ 快捷键说明

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