📄 process.c
字号:
/* * process.c * * Copyright (C) 2006 Insigme Co., Ltd * * Authors: * - Chenzhan Hu * * 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: * Reference to Reactos Kernel code */#include <linux/win32_process.h>#include <linux/mm.h>#include "../win32.h"#include "../thread.h"#include "../object.h"#include "../process.h"#include "../section.h"#ifdef CONFIG_UNIFIED_KERNEL//#define ktrace(fmt ...)//#define kdebug(fmt ...)extern struct win32_object_class section_objclass;/* INTERNAL FUNCTIONS *****************************************************************/#define NtCurrentThread() ((HANDLE)(ULONG_PTR)-2)//#define PROCESS_PRIO_NORMAL 8extern long do_fork_from_task(task_t *ptsk, unsigned long process_flags, unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr);extern VOID STDCALLKeInitializeEvent(struct kevent *event, enum event_type type, BOOLEAN state);extern NTSTATUS STDCALL LdrpMapSystemDll(struct task_struct *tsk, char *name, unsigned long *ntdll_load_addr, unsigned long *interp_load_addr);extern NTSTATUS STDCALL MmCreateProcessAddressSpace(struct eprocess *, struct win32_section *);extern NTSTATUS STDCALL MmCreatePeb(PEPROCESS Process);extern NTSTATUS STDCALL NtClose(HANDLE handle);extern fastcall void do_exit_task(task_t *tsk, long code);#define DEFAULT_SYSTEM_DLL "/usr/local/lib/wine/ntdll.dll.so"/* * PspCreateProcess * create process */NTSTATUSSTDCALLPspCreateProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcessHandle OPTIONAL, IN BOOLEAN InheritObjectTable, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL){ HANDLE hProcess, hThread; struct eprocess *child_eprocess; struct eprocess *parent_eprocess = NULL; NTSTATUS Status = STATUS_SUCCESS; char *system_dll_name = DEFAULT_SYSTEM_DLL; long cpid; struct task_struct *child_task = NULL, *parent_task = NULL; struct ethread *current_ethread = thread_find(); struct ethread *parent_ethread = NULL; struct win32_object *proc_obj, *thread_obj; struct win32_object *parent_obj = NULL, *sec_obj = NULL; struct ktrap_frame *trap_frame = NULL; struct win32_section *section = NULL; struct ethread_cons_data etcd; unsigned long system_dll_load_addr, interp_load_addr; if (!ProcessHandle) return -EINVAL; if (!current_ethread) return -EINVAL; /* Reference the Parent if there is one */ if (ParentProcessHandle) { if (ParentProcessHandle == NtCurrentProcess()) { parent_eprocess = current_ethread->threads_process; parent_ethread = current_ethread; } else { parent_obj = GetObject(current_ethread, ParentProcessHandle, &process_objclass); if (!parent_obj) { kdebug("Failed to reference the parent process: Status: 0x%x\n", Status); return Status; } parent_eprocess = (struct eprocess *)parent_obj->o_private; parent_ethread = get_first_thread(parent_eprocess); } trap_frame = parent_ethread->tcb.trap_frame; parent_task = parent_ethread->et_task; cpid = do_fork_from_task(parent_task, CREATE_PROCESS, SIGCHLD | CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, /* SIGCHLD ????? */ trap_frame->esp, (struct pt_regs *)trap_frame, 0, NULL, NULL); if (parent_obj) objput(parent_obj); if (cpid < 0) goto out; child_task = find_task_by_pid(cpid); /* Create EPROCESS */ proc_obj = CreateObject(current_ethread, &process_objclass, NULL, NULL, &hProcess); if (IS_ERR(proc_obj)) { Status = (NTSTATUS)PTR_ERR(proc_obj); goto cleanup_child_task; } child_eprocess = (struct eprocess *)proc_obj->o_private; /* allocate a Win32 thread object */ etcd.etcd_task = child_task; etcd.etcd_process = proc_obj; etcd.etcd_stack_top = 0xbfff0000; thread_obj = CreateObject(current_ethread, &thread_objclass, NULL, &etcd, &hThread); if (IS_ERR(thread_obj)) { Status = (NTSTATUS)PTR_ERR(thread_obj); objput(proc_obj); goto cleanup_proc_handle; } /* the thread object can now be put, since a reference is held * by the Linux task structure. Similarly the process object * is now referenced by the thread object and can also be put */ objput(proc_obj); objput(thread_obj); child_eprocess->fork_in_progress = thread_obj->o_private; /* Inherit stuff from the Parent since we now have the object created */ if (parent_eprocess) { child_eprocess->inherited_from_unique_pid = parent_eprocess->unique_processid; child_eprocess->session = parent_eprocess->session; } /* FIXME: Set up the Quota Block from the Parent * PspInheritQuota(Parent, child_eprocess); */ /* FIXME: Set up Dos Device Map from the Parent * ObInheritDeviceMap(Parent, child_eprocess) */ /* Set the Process' LPC Ports */ /* Setup the Lock Event */ KeInitializeEvent(&child_eprocess->lock_event, synchronization_event, FALSE); /* Add the Section */ if (SectionHandle) { sec_obj = GetObject(parent_ethread, SectionHandle, §ion_objclass); if (!sec_obj) goto cleanup_thread_handle; section = (struct win32_section *)sec_obj->o_private; } /* Create the Process' Address Space */ Status = MmCreateProcessAddressSpace(child_eprocess, section); if (Status != STATUS_SUCCESS) { kdebug("Failed to create Address Space\n"); goto cleanup_thread_handle; } if (section) { /* Map the System Dll */ ktrace("Mapping System DLL!!!!!!!!!!!!!!!!!!\n"); LdrpMapSystemDll(child_task, system_dll_name, &system_dll_load_addr, &interp_load_addr); } /* Create PEB only for User-Mode Processes */ if (parent_eprocess) { Status = MmCreatePeb(child_eprocess); if (Status != STATUS_SUCCESS) { kdebug("NtCreateProcess() Peb creation failed: Status %x\n",Status); goto cleanup_thread_handle; } } /* Let's take advantage of this time to kill the reference too */ parent_eprocess = NULL; } /* Set the Creation Time */ *ProcessHandle = hProcess; return STATUS_SUCCESS;cleanup_thread_handle: if (hThread) NtClose(hThread);cleanup_proc_handle: if (hProcess) NtClose(hProcess);cleanup_child_task: do_exit_task(child_task, 0);out: printk("PspCreateProcess return %d\n", Status); return Status;} /* end PspCreateProcess *//* * FUNCTION: Creates a process. * ARGUMENTS: * ProcessHandle (OUT) = Caller supplied storage for the resulting * handle * DesiredAccess = Specifies the allowed or desired access to the * process can be a combination of * STANDARD_RIGHTS_REQUIRED| .. * ObjectAttribute = Initialized attributes for the object, contains * the rootdirectory and the filename * ParentProcessHandle = Handle to the parent process. * InheritObjectTable = Specifies to inherit the objects of the parent * process if true. * SectionHandle = Handle to a section object to back the image file * DebugPort = Handle to a DebugPort if NULL the system default debug * port will be used. * ExceptionPort = Handle to a exception port. * REMARKS: * This function maps to the win32 CreateProcess. * RETURNS: Status * * @implemented */NTSTATUSSTDCALLNtCreateProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcessHandle, IN BOOLEAN InheritObjectTable, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL){ ktrace("NtCreateProcess\n"); return ParentProcessHandle /* Create a user Process */ ? PspCreateProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ParentProcessHandle, InheritObjectTable, SectionHandle, DebugPort, ExceptionPort) : -EINVAL;} /* end NtCreateProcess */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -