📄 process.c
字号:
/* * process.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. */ /* * process.c: win32 process handling * Reference to Kernel-win32 code */#include <linux/module.h>#include <linux/win32_process.h>#include <linux/mm.h>#include <asm/uaccess.h>#include <linux/nls.h>#include <linux/file.h>#include "objwait.h"#include "thread.h"#include "process.h"#include "win32.h"#include "file.h"#ifdef CONFIG_UNIFIED_KERNELstatic int ProcessConstructor(win32_object *, void *);static int ProcessReconstructor(win32_object *, void *);static void ProcessDestructor(win32_object *);static int ProcessPoll(struct wait_table_entry *, struct ethread *);struct win32_object_class process_objclass = { oc_type: "PROC ", constructor: ProcessConstructor, reconstructor: NULL, destructor: ProcessDestructor, poll: ProcessPoll,};extern fastcall void do_exit_task(task_t *tsk, long code);#if 0static int init_std_handles(struct win32_object **handles){ int i; struct file *file; struct files_struct *files = current->files; for (i = 0; i < 2; i++) { file = files->fd[i]; if (file) { struct win32_object *wo; struct win32_file *wf; wo = kmalloc(sizeof(struct win32_object), GFP_KERNEL); memset(wo, 0, sizeof(*wo)); wf = kmalloc(sizeof(struct win32_file), GFP_KERNEL); memset(wf, 0, sizeof(*wf)); atomic_set(&wo->o_count, 1); wo->o_private = wf; get_file(file); wf->wf_file = file; if (!i) wf->wf_access = GENERIC_READ; /* stdin */ else wf->wf_access = GENERIC_WRITE; /* stdout and stderr */ handles[i] = wo; } } return 0;}#endif/* * initialise the process object class */void ProcessClassInit(void){ InitObjectClass(&process_objclass);} /* end ProcessClassInit() *//* * poll the state of a process for WaitFor*() functions * - if signalled, sets to non-signalled before returning */static int ProcessPoll(struct wait_table_entry *wte, struct ethread *thread){ struct eprocess *process = wte->wte_obj->o_private; int ret; ret = (process->pcb.state==PROCESS_STATE_ACTIVE) ? POLL_NOTSIG : POLL_SIG; return ret;} /* end ProcessPoll() *//* * construct a process (allocate its private data) * - called by Createwin32_object if the process does not already exists * - called with the object class lock held */static int ProcessConstructor(win32_object *obj, void *data){ struct eprocess *process; ktrace("ProcessConstructor\n"); process = (struct eprocess *) get_zeroed_page(GFP_KERNEL); if (!process) return -ENOMEM; obj->o_private = process; process->ep_nls = load_nls("cp936"); process->unique_processid = (HANDLE)current->pid; /* FIXME */ process->pcb.state = PROCESS_STATE_ACTIVE; process->ep_obj = obj; INIT_LIST_HEAD(&process->thread_list_head); rwlock_init(&process->ep_lock); EProcessInit(process); process->ep_handles = process->ep_handles_array; return 0;} /* end ProcessConstructor() *//* * reconstruct a process (allocate its private data) * - called by Createwin32_object if the process already exists * - called without the object class lock held */static int ProcessReconstructor(win32_object *obj, void *data){ /* TODO */ return -ENOANO;} /* end ProcessReconstructor() *//* * destroy a process (discard its private data) */static void ProcessDestructor(win32_object *obj){ struct eprocess *process; win32_object **ppobj, **epobj, **qpobj; ktrace("ProcessDestructor\n"); process = obj->o_private; epobj = &process->ep_handles[MAXHANDLES]; for (ppobj=&process->ep_handles[0]; ppobj<epobj; ppobj++) { if (!*ppobj) continue; /* see if this is the last attachment to this "process" */ if ((*ppobj)->o_class->detach) { for (qpobj=ppobj+1; qpobj<epobj; qpobj++) if (*qpobj==*ppobj) break; if (qpobj>=epobj) /* yes */ (*ppobj)->o_class->detach(*ppobj,process); } objput(*ppobj); } unload_nls(process->ep_nls); free_page((unsigned long)process);} /* end ProcessDestructor() *//* initialize eprocess */void EProcessInit(struct eprocess *process){ physical_address_t dir_table_base; ktrace("EProcessInit\n"); process->debug_port = NULL; /* FIXME */ process->exception_port = NULL; /* FIXME */ process->section_base_address = 0; /* FIXME */ /* FIXME: KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE); */ /* FIXME: process->object_table = process->default_object_table; */ /* FIXME: Status = PspInitializeProcessSecurity(Process, pParentProcess); */ /* * FIXME: * affinity == active processors, used 1 here * directory_table_base, used 0 here */ dir_table_base.quad = 0LL; KProcessInit(&process->pcb, PROCESS_PRIO_NORMAL, 1, dir_table_base);}/* initialize kprocess */void KProcessInit(struct kprocess *process, char prio, unsigned long affinity, physical_address_t dir_table_base){ ktrace("KProcessInit\n"); INIT_DISP_HEADER(&process->header, process_object, sizeof(struct kprocess), false); /* Initialize Scheduler Data, Disable Alignment Faults and Set the PDE */ process->affinity = affinity; process->base_priority = prio; process->quantum_reset = 6; process->directory_table_base = dir_table_base; process->auto_alignment = true;#if defined(_M_IX86) process->iopm_offset = 0xffff;#endif process->state = PROCESS_STATE_ACTIVE; /* Initialize the Thread List */ INIT_LIST_HEAD(&process->thread_list_head);} /* end KProcessInit *//* * close a handle */NTSTATUS STDCALLNtClose(HANDLE handle){ struct ethread *thread; struct eprocess *process; win32_object **ppobj, **epobj, *obj; int last; NTSTATUS Status = STATUS_SUCCESS; ktrace("NtClose\n"); thread = thread_find(); if (!thread) return -EINVAL; /* validate the handle */ if (handle<MINHANDLE || handle>=MAXHANDLE || ((__u32)handle & (sizeof(win32_object*)-1))) return -EINVAL; process = get_eprocess(thread); write_lock(&process->ep_lock); ppobj = (win32_object**) ((char*)process->ep_handles + (__u32)handle - sizeof(win32_object*) ); obj = *ppobj; *ppobj = NULL; /* see if this was the last attachment from this "process" */ epobj = &process->ep_handles[MAXHANDLES]; last = 1; if (obj && obj->o_class->detach) { for (ppobj=process->ep_handles; ppobj<epobj; ppobj++) { if (*ppobj==obj) { last = 0; /* yes */ break; } } } write_unlock(&process->ep_lock); if (!obj) return -EBADF; if (last && obj->o_class->detach) obj->o_class->detach(obj,process); /* last attachment gone */ objput(obj); return Status;} /* end NtClose() *//* create PEB */int create_peb(struct eprocess *process){ PPEB kpeb, peb; int ret = 0; unsigned long brk_res; ktrace("create_peb\n"); kpeb = kmalloc(sizeof(PEB), GFP_KERNEL); if (!kpeb) return -ENOMEM; memset(kpeb, 0, sizeof(PEB)); /* TODO: load NLS */ kpeb->ImageBaseAddress = process->section_base_address; kpeb->OSMajorVersion = 5; kpeb->OSMinorVersion = 0; kpeb->OSBuildNumber = 13; kpeb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */ kpeb->OSCSDVersion = 0; /* NtOSCSDVersion */ kpeb->AnsiCodePageData = 0; /* FIXME */ kpeb->OemCodePageData = 0; /* FIXME */ kpeb->UnicodeCaseTableData = 0; /* FIXME */ kpeb->NumberOfProcessors = 1; /* FIXME */ kpeb->BeingDebugged = (BOOLEAN)(process->debug_port ? TRUE : FALSE); /* alloc a page used to PEB */ down_write(¤t->mm->mmap_sem); brk_res = do_brk(PEB_BASE, PAGE_SIZE); up_write(¤t->mm->mmap_sem); if (brk_res == PEB_BASE) peb = (PPEB)PEB_BASE; else { ret = -EINVAL; goto out; } if (copy_to_user(peb, kpeb, sizeof(PEB))) { ret = -EFAULT; goto out; } process->peb = peb;out: kfree(kpeb); return ret;} /* end create_peb *//* copy unicode string to PPB */static inline intcopy_param_str(void *ptr, PUNICODE_STRING dst, PUNICODE_STRING src){ int ret = 0; dst->Length = src->Length; dst->MaximumLength = src->MaximumLength; dst->Buffer = (PWSTR)ptr; if (src->Length) ret = copy_to_user(dst->Buffer, src->Buffer, src->Length + sizeof(wchar_t)); return ret ? -EFAULT : ALIGN_TO_LONG(dst->MaximumLength);}static int str2unistr(struct nls_table *nls, PUNICODE_STRING dst, char *src){ int len, i; int ret = -ENOMEM; char *ksrc, *p; wchar_t *wc; if ((int) src > TASK_SIZE) { ksrc = src; len = strlen(src) + 1; goto ksrc_ready; } if (!src || !(len = strlen_user(src))) { dst->Length = 0; dst->MaximumLength = sizeof(wchar_t); dst->Buffer = (PWSTR)L""; return 0; } if (!(ksrc = kmalloc(len, GFP_KERNEL))) return ret; ret = -EFAULT; if (copy_from_user(ksrc, src, len)) goto out_free_src;ksrc_ready: dst->Length = 0; dst->MaximumLength = len * sizeof(wchar_t); dst->Buffer = kmalloc(dst->MaximumLength, GFP_KERNEL); ret = -ENOMEM; if (!dst->Buffer) goto out_free_src; wc = dst->Buffer; p = ksrc; while (p < ksrc + len - 1) { i = nls->char2uni(p, sizeof(wchar_t), wc++); if (i < 0) { ret = -EINVAL; goto out_free_dst; } p += i; dst->Length += sizeof(wchar_t); } *wc = L'\0'; ret = 0; goto out_free_src;out_free_dst: kfree(dst->Buffer);out_free_src:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -