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

📄 virtual.c

📁 该项目主要是将wingdows程序直接运行在linux上
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * virtual.c * * Copyright (C) 2006  Insigme Co., Ltd * * Authors:  * - Liwei Zhou * * 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. *//*  * virtual.c: virtual memory handling * Reference to ReactOS code */#include "virtual.h"#include "attach.h"#include "../thread.h"#include "../process.h"#include "../section.h"#include "../object.h"#include "../w32syscall.h"#include <asm/page.h>#include <linux/mm.h>#include <linux/mman.h>#include <linux/slab.h>#include <asm/uaccess.h>#include <linux/personality.h>#ifdef CONFIG_UNIFIED_KERNELpgprot_t protection_map[16] = {        __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,        __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111};/* * NtQueryVirtualMemory * Get the information of the virtual memory  */NTSTATUS STDCALLNtQueryVirtualMemory (IN HANDLE ProcessHandle,		IN PVOID Address,		IN CINT VirtualMemoryInformationClass,		OUT PVOID VirtualMemoryInformation,		IN ULONG Length,		OUT PULONG UnsafeResultLength){	NTSTATUS	status;	ULONG		result_len, gap_size, base_addr;	struct win32_object	*obj;	struct ethread		*thread, *first_thread;	struct eprocess		*process;	struct mm_struct	*mm;	struct vm_area_struct 	*vma;	MEMORY_BASIC_INFORMATION Info;	ktrace("NtQueryVirtualMemory\n");	thread = thread_find();	if (!thread)		return -EINVAL;	if (ProcessHandle==NtCurrentProcess() || !ProcessHandle)		process = thread->threads_process;	else {		etget(thread);		obj = GetObject(thread, ProcessHandle, &process_objclass);		etput(thread);		if (IS_ERR(obj))			return PTR_ERR(obj);		process = obj->o_private;	}	first_thread = get_first_thread(process);	mm = first_thread->et_task->mm;	vma = find_vma(mm, (ULONG)Address);	base_addr = (ULONG)Address & PAGE_MASK;		switch (VirtualMemoryInformationClass) {		case MemoryBasicInformation:			if (Length !=sizeof(MEMORY_BASIC_INFORMATION))				return -EFAULT;			if (!vma || vma->vm_start > (ULONG)Address) {				gap_size = vma ? vma->vm_start - base_addr : mm->start_stack- base_addr;				Info.Type = 0;				Info.State = MEM_FREE;				Info.Protect = PAGE_NOACCESS;				Info.AllocationProtect = 0;				Info.BaseAddress = (PVOID)base_addr;				Info.AllocationBase = NULL;				Info.RegionSize = gap_size;				status = STATUS_SUCCESS;				result_len = sizeof(MEMORY_BASIC_INFORMATION);	    		}			else {				ULONG offset = pgd_index((ULONG)Address);				/* Setup state */				if (((pgd_t *)(mm->pgd + offset))->pgd)					Info.State = MEM_COMMIT;				else Info.State = MEM_RESERVE;				/* Setup allocation protect */				if (vma->vm_flags & VM_READ) {					if (vma->vm_flags & VM_EXEC)						Info.AllocationProtect = PAGE_EXECUTE_READ;					else Info.AllocationProtect = PAGE_READ;				} 				else if (vma->vm_flags & VM_WRITE) {					if (vma->vm_flags & VM_EXEC)						Info.AllocationProtect = PAGE_EXECUTE_READWRITE;					else Info.AllocationProtect = PAGE_READWRITE;				}				else if (vma->vm_flags & VM_EXEC) {					if (vma->vm_flags & VM_SHARED)						Info.AllocationProtect = PAGE_EXECUTE_WRITECOPY;					else Info.AllocationProtect = PAGE_EXECUTE;				}				else if (vma->vm_flags & VM_SHARED)					Info.AllocationProtect = PAGE_WRITECOPY;				else Info.AllocationProtect = 0;				Info.Type = 0;				Info.Protect = Info.AllocationProtect;				Info.BaseAddress = (PVOID)base_addr;				Info.AllocationBase = (PVOID)vma->vm_start;				Info.RegionSize = vma->vm_end - vma->vm_start;				status = STATUS_SUCCESS;				result_len = sizeof(MEMORY_BASIC_INFORMATION);			}			break;		default: 			ktrace("Unimplemented information class\n");			return  -EFAULT;	}	if ((ULONG)VirtualMemoryInformation < TASK_SIZE) {		if (copy_to_user(VirtualMemoryInformation, &Info, sizeof(MEMORY_BASIC_INFORMATION)))			return -EFAULT;	}	else *(PMEMORY_BASIC_INFORMATION)VirtualMemoryInformation = Info;	if (UnsafeResultLength) {		if ((ULONG)UnsafeResultLength < TASK_SIZE) {			if (copy_to_user(UnsafeResultLength, &result_len, sizeof(ULONG)))				return -EFAULT;		}		else *UnsafeResultLength = result_len;	}	return status;} /* end NtQueryVirtualMemory *//*  * MmCreateMemoryArea * Create a memory area  */NTSTATUS STDCALLMmCreateMemoryArea(struct eprocess *Process,		PMADDRESS_SPACE AddressSpace,		ULONG Type,		PVOID *BaseAddress,		ULONG_PTR Length,		ULONG Attributes,		PMEMORY_AREA *Result,		BOOLEAN FixedAddress,		BOOLEAN TopDown,		PHYSICAL_ADDRESS bound_addr_multi){	struct mm_struct	*mm;	struct task_struct	*task;	struct ethread	*thread, *first_thread;	struct vm_area_struct	*vma;	ULONG	flags, prot;	ULONG	addr_page, size_page, address;	NTSTATUS	status = STATUS_SUCCESS;	ktrace("MmCreateMemoryArea\n");	thread = thread_find();	if (!thread)		return -EINVAL;		if (Process == get_eprocess(thread))		task = current;	else {		first_thread = get_first_thread(Process);		task = first_thread->et_task;	}	mm = task->mm;	addr_page = (ULONG)(*BaseAddress) & PAGE_MASK;	size_page = PAGE_ALIGN((ULONG)(*BaseAddress) + Length) - ((ULONG)addr_page);	if (addr_page) {		if (mm->start_stack && mm->end_data)			if (mm->start_stack < addr_page + size_page || mm->end_data > addr_page)				return -EFAULT;				vma = find_vma(mm, addr_page);		if (vma && vma->vm_start < addr_page + size_page)			return -EFAULT;	}	switch (Attributes) {		case PAGE_READ:			prot = PROT_READ;			flags = MAP_PRIVATE;			break;		case PAGE_READWRITE:			prot = PROT_READ | PROT_WRITE;			flags= MAP_PRIVATE;			break;		case PAGE_WRITECOPY:			prot = 0;			flags = MAP_SHARED;			break;		case PAGE_EXECUTE:			prot = PROT_EXEC;			flags = MAP_PRIVATE;			break;		case PAGE_EXECUTE_READ:			prot = PROT_EXEC | PROT_READ;			flags = MAP_PRIVATE;			break;		case PAGE_EXECUTE_READWRITE:			prot = PROT_EXEC | PROT_READ | PROT_WRITE;			flags = MAP_PRIVATE;			break;		case PAGE_EXECUTE_WRITECOPY:			prot = PROT_EXEC;			flags = MAP_SHARED;			break;		default:			prot = 0;			flags = 0;			break;	}	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);	down_write(&mm->mmap_sem);	address = win32_do_mmap_pgoff(task, TopDown, NULL, addr_page, size_page, prot, flags, 0);	up_write(&mm->mmap_sem);	*BaseAddress = (PVOID)address;	return status;} /* end MmCreateMemoryArea *//*  * NtAllocateVirtualMemory * Allocate a block of virtual memory in the process address space  */NTSTATUS STDCALLNtAllocateVirtualMemory(IN HANDLE ProcessHandle,			IN OUT PVOID*  UBaseAddress,			IN ULONG ZeroBits,			IN OUT PULONG URegionSize,			IN ULONG AllocationType,			IN ULONG Protect){	struct ethread		*thread, *first_thread;	struct eprocess		*process;	struct win32_object	*obj;	struct mm_struct	*mm;	struct vm_area_struct	*vma;	PVOID		address, addr_page;	ULONG		size, size_page;	NTSTATUS 	status;	PHYSICAL_ADDRESS bound_addr_multi;		ktrace("NtAllocateVirtualMemory(%p,%p,%d,%p,%d,%d)\n",			ProcessHandle, UBaseAddress, ZeroBits, URegionSize, AllocationType, Protect);	bound_addr_multi.QuadPart = 0;		/* Check the validity of the parameters */	if ((Protect & PAGE_FLAGS_VALID_FROM_USER_MODE) != Protect)		return -EFAULT;	if ((AllocationType & (MEM_COMMIT | MEM_RESERVE)) == 0)		return -EFAULT;	if ((ULONG)UBaseAddress < TASK_SIZE) {		if (copy_from_user(&address, UBaseAddress, sizeof(PVOID)))			return -EFAULT;	}	else address = *UBaseAddress;	if ((ULONG)URegionSize < TASK_SIZE) {		if (copy_from_user(&size,URegionSize,sizeof(ULONG)))			return -EFAULT;	}	else size = *URegionSize;	thread = thread_find();	if (!thread)		return -EINVAL;		if (ProcessHandle == NtCurrentProcess() || !ProcessHandle)		process = thread->threads_process;	else {		etget(thread);		obj = GetObject(thread, ProcessHandle, &process_objclass);		etput(thread);		if (IS_ERR(obj))			return PTR_ERR(obj);		process = obj->o_private;	}	first_thread = get_first_thread(process);

⌨️ 快捷键说明

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