static void lynx_request_interrupt (void) { ptid_t inferior_ptid = thread_to_gdb_id (get_first_thread ()); kill (lynx_ptid_get_pid (inferior_ptid), SIGINT); }
NTSTATUS SERVICECALL NtTerminateProcess(IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus) { struct eprocess *process; struct ethread *cur_thread; NTSTATUS status; ktrace("\n"); if ((status = ref_object_by_handle(ProcessHandle ? ProcessHandle : NtCurrentProcess(), PROCESS_TERMINATE, process_object_type, get_pre_mode(), (PVOID *) &process, NULL))) return status; cur_thread = (struct ethread *) get_current_ethread(); terminate_process(process->win32process, ExitStatus); release_object(process->win32process); lock_process(process); if (process->exit_time.quad) { unlock_process(process); deref_object(process); return STATUS_PROCESS_IS_TERMINATING; } query_sys_time(&process->exit_time); process->exit_status = (unsigned long)ExitStatus; unlock_process(process); deref_object(process); if (process == get_current_eprocess()) { cur_thread->exit_status = ExitStatus; do_group_exit((ExitStatus & 0xff) << 8); } else { struct ethread *first_thread = get_first_thread(process); first_thread->exit_status = ExitStatus; send_sig_info(SIGKILL, SEND_SIG_FORCED, first_thread->et_task->group_leader); } return STATUS_SUCCESS; }
void set_desired_thread (int use_general) { struct thread_info *found; if (use_general == 1) found = find_thread_ptid (general_thread); else found = find_thread_ptid (cont_thread); if (found == NULL) current_thread = get_first_thread (); else current_thread = found; }
/* * map_section_view * map a view of the section to the process's address space */ NTSTATUS STDCALL map_section_view( IN PVOID SectionObject, IN struct eprocess* Process, IN OUT PVOID *BaseAddress, IN ULONG ZeroBits, IN ULONG CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect ) { NTSTATUS status; size_t size; unsigned long offset; unsigned long addr; unsigned long flags = 0; struct win32_section *section = SectionObject; struct vm_area_struct *vma; struct ethread *thread; struct task_struct *tsk; if (!(thread = get_first_thread(Process))) return STATUS_THREAD_NOT_IN_PROCESS; /* map offset, aligned to PAGE_SIZE */ if ((offset = SectionOffset ? SectionOffset->u.LowPart : 0)) offset &= PAGE_MASK; /* map size */ size = PAGE_ALIGN(*ViewSize); tsk = thread->et_task; /* get the win32_section struct */ flags |= section->ws_flags; if (offset >= section->ws_len || offset + size > section->ws_pagelen) { status = STATUS_INVALID_PARAMETER; goto out; } /* map total section len */ if (!size) size = section->ws_pagelen - offset; if ((addr = (unsigned long)*BaseAddress)) { /* fixed address map, align to 64k */ addr = (addr + BASE_ADDRESS_ALIGN - 1) & ~(BASE_ADDRESS_ALIGN - 1); if ((vma = find_vma(tsk->mm, addr)) && vma->vm_start < addr + size) { status = STATUS_INVALID_ADDRESS; goto out; } flags |= MAP_FIXED; } if (section->ws_mmap) { /* do the mmap operation */ status = section->ws_mmap(tsk, section, &addr, size, flags, offset >> PAGE_SHIFT); if (NT_SUCCESS(status)) { *BaseAddress = (PVOID)addr; insert_mapped_area(Process, addr, addr + size, Protect, section); } } else
/* * map a view of the section to the process's address space */ NTSTATUS SERVICECALL NtMapViewOfSection( IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG ZeroBits, IN ULONG CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect ) { NTSTATUS Status; size_t size = 0; MODE previous_mode; unsigned long addr = 0L; struct win32_section *section; struct ethread *thread; struct eprocess *process; LARGE_INTEGER sec_off = { .QuadPart = 0LL }; ktrace("\n"); if (!(thread = get_current_ethread())) return STATUS_UNSUCCESSFUL; /* FIXME */ previous_mode = (unsigned long)BaseAddress > TASK_SIZE ? KernelMode : UserMode; if (!BaseAddress) return STATUS_INVALID_PARAMETER; if (!ViewSize) return STATUS_INVALID_PARAMETER; if (previous_mode == UserMode) { if (copy_from_user(&addr, BaseAddress, sizeof(PVOID))) return STATUS_INVALID_ADDRESS; if (copy_from_user(&size, ViewSize, sizeof(size))) return STATUS_INVALID_ADDRESS; if (SectionOffset && copy_from_user(&sec_off, SectionOffset, sizeof(sec_off))) return STATUS_INVALID_ADDRESS; } else { addr = (unsigned long)*BaseAddress; size = (size_t)*ViewSize; if (SectionOffset) sec_off = *SectionOffset; } if (addr > WIN32_TASK_SIZE || size > WIN32_TASK_SIZE) return STATUS_INVALID_PARAMETER; /* TODO: not support 64bit offset */ if (sec_off.u.HighPart) return STATUS_INVALID_PARAMETER; /* access the section object */ Status = ref_object_by_handle( SectionHandle, SECTION_ALL_ACCESS, section_object_type, KernelMode, (PVOID *)§ion, NULL ); if (Status) return Status; if (!ProcessHandle || ProcessHandle == NtCurrentProcess()) { process = thread->threads_process; ref_object((PVOID)process); } else { Status = ref_object_by_handle( ProcessHandle, PROCESS_ALL_ACCESS, process_object_type, KernelMode, (PVOID *)&process, NULL ); if (Status) goto cleanup_section; } Status = map_section_view( (PVOID)section, process, (PVOID *)&addr, ZeroBits, CommitSize, SectionOffset ? (PLARGE_INTEGER)&sec_off : NULL, (PSIZE_T)&size, InheritDisposition, AllocationType, Protect ); if (!NT_SUCCESS(Status)) goto cleanup_process; Status = STATUS_INVALID_ADDRESS; if (previous_mode == UserMode) { if (copy_to_user(BaseAddress, &addr, sizeof(PVOID))) goto cleanup_process; if (copy_to_user(ViewSize, &size, sizeof(PVOID))) goto cleanup_process; } else { *BaseAddress = (PVOID)addr; *ViewSize = size; } Status = STATUS_SUCCESS; cleanup_process: deref_object(process); cleanup_section: deref_object(section); return Status; } /* end NtMapViewOfSection() */ EXPORT_SYMBOL(NtMapViewOfSection); /* * unmap a mapped view of the file * - the view must start _exactly_ on the address */ NTSTATUS SERVICECALL NtUnmapViewOfSection( IN HANDLE ProcessHandle, IN PVOID BaseAddress ) { struct mm_struct *mm; struct eprocess *process; struct ethread *thread; NTSTATUS ret; ktrace("\n"); if (!ProcessHandle || ProcessHandle == NtCurrentProcess()) { mm = current->mm; process = get_current_eprocess(); ref_object((PVOID)process); } else { ret = ref_object_by_handle( ProcessHandle, PROCESS_ALL_ACCESS, process_object_type, KernelMode, (PVOID *)&process, NULL ); if (!NT_SUCCESS(ret)) return ret; thread = get_first_thread(process); if (!thread) { ret = STATUS_THREAD_NOT_IN_PROCESS; goto out; } mm = thread->et_task->mm; } ret = unmap_section_view(process, mm, (unsigned long)BaseAddress); out: deref_object(process); return ret; } /* NtUnmapViewOfSection() */ EXPORT_SYMBOL(NtUnmapViewOfSection); NTSTATUS SERVICECALL NtOpenSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) { HANDLE hSection; POBJECT_ATTRIBUTES obj_attr = NULL; MODE previous_mode; NTSTATUS Status = STATUS_SUCCESS; ktrace("\n"); previous_mode = (unsigned long)ObjectAttributes > TASK_SIZE ? KernelMode : UserMode; if (ObjectAttributes) { if (previous_mode == UserMode) { if (copy_object_attr_from_user(ObjectAttributes, &obj_attr)) return STATUS_NO_MEMORY; } else obj_attr = ObjectAttributes; } if (obj_attr && obj_attr->RootDirectory) obj_attr->RootDirectory = base_dir_handle; Status = open_object_by_name(obj_attr, section_object_type, NULL, KernelMode, DesiredAccess, NULL, &hSection); if (!NT_SUCCESS(Status)) goto cleanup; if (previous_mode == UserMode) { if (copy_to_user(SectionHandle, &hSection, sizeof(HANDLE))) { Status = STATUS_INVALID_ADDRESS; goto cleanup; } } else *SectionHandle = hSection; cleanup: if (obj_attr && previous_mode == UserMode) kfree(obj_attr); return Status; } /* end NtOpenSection */
NTSTATUS STDCALL create_thread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN struct eprocess* TargetProcess, /* FIXME */ OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, IN PINITIAL_TEB InitialTeb, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, /* FIXME */ IN PVOID StartContext OPTIONAL) /* FIXME */ { struct eprocess * process; struct ethread * thread, *first_thread, *cur_thread; struct task_struct *new_tsk = NULL; unsigned clone_flags = 0; PTEB teb_base; long cpid; HANDLE hthread; NTSTATUS status = STATUS_SUCCESS; ktrace("\n"); if (!(cur_thread = get_current_ethread())) { return STATUS_INVALID_PARAMETER; } /* current still be regarded */ if (ProcessHandle && ProcessHandle != NtCurrentProcess()) { status = ref_object_by_handle(ProcessHandle, PROCESS_ALL_ACCESS, process_object_type, KernelMode, (PVOID *)&process, NULL); if (!NT_SUCCESS(status)) return status; } else { if (TargetProcess) process = (struct eprocess *)TargetProcess; else process = cur_thread->threads_process; ref_object(process); } if (!process->fork_in_progress) { /* second and after */ if (!ProcessHandle || ProcessHandle == NtCurrentProcess()) first_thread = cur_thread; else first_thread = get_first_thread(process); if (!first_thread) { status = STATUS_INVALID_PARAMETER; goto cleanup_process; } clone_flags = SIGCHLD | CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_PARENT | CLONE_THREAD; cpid = do_fork_from_task(first_thread->et_task, CREATE_THREAD, clone_flags, first_thread->tcb.trap_frame->esp, (struct pt_regs *)first_thread->tcb.trap_frame, 0, NULL, NULL); if (cpid < 0) { status = STATUS_INVALID_PARAMETER; goto cleanup_process; } new_tsk = find_task_by_vpid(cpid); memset(&new_tsk->thread.tls_array, 0, sizeof(new_tsk->thread.tls_array)); set_tls_array(&new_tsk->thread, first_thread->et_task->thread.gs >> 3, (unsigned long)InitialTeb->StackBase + 0x800, 0xfffff); /* allocate a Win32 thread object */ status = create_object(KernelMode, thread_object_type, ObjectAttributes, KernelMode, NULL, sizeof(struct ethread), 0, 0, (PVOID *)&thread); if (!NT_SUCCESS(status)) goto cleanup_tsk; ethread_init(thread, process, new_tsk); deref_object(thread); } else {