static DWORD PspThreadCutterThread(PVOID StartContext) { HANDLE ProcessHandle, ThreadHandle; PTHREAD_CONTROL_BLOCK *pt_prev_thread, *pt_cur_thread; while(1) { /* check thread cutting list */ if(!PspPopCuttingItem(&m_ThreadCuttingList, &ThreadHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); ProcessHandle = PsGetThreadPtr(ThreadHandle)->parent_process_handle; /* if requsted thread's parent process handle is same with system process handle, then do nothing!! protect system thread */ if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } /* invalid thread */ if(PsGetProcessPtr(ProcessHandle)->thread_count == 0) { goto $exit; } /* check whether there is only one thread exist in the parent process */ else if(PsGetProcessPtr(ProcessHandle)->thread_count == 1) { PsGetProcessPtr(ProcessHandle)->pt_head_thread = NULL; } /* more than 2 threads exist */ else { pt_prev_thread = pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != PsGetThreadPtr(ThreadHandle)) { /* there is no requested thread in the parent process */ if((*pt_cur_thread)->pt_next_thread == NULL) { goto $exit; } pt_prev_thread = pt_cur_thread; pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } /* change next thread pointer */ (*pt_prev_thread)->pt_next_thread = (*pt_cur_thread)->pt_next_thread; } PsGetProcessPtr(ProcessHandle)->thread_count--; /* except user mode program's stack */ if(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address >= (int *)0x00200000) MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address)); /* dealloc stack */ MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle))); /* dealloc thread */ $exit: EXIT_CRITICAL_SECTION(); } return 0; }
static DWORD PspProcessCutterThread(PVOID StartContext) { HANDLE ProcessHandle; PPROCESS_CONTROL_BLOCK *pt_prev_process, *pt_cur_process; PTHREAD_CONTROL_BLOCK *pt_cur_thread; while(1) { /* check process cutting list */ if(!PspPopCuttingItem(&m_ProcessCuttingList, &ProcessHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); /* if requsted process handle is same with system process handle, then do nothing!! protect system process */ if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } /* find requested process position in the process list */ pt_prev_process = pt_cur_process = &(m_ProcMgrBlk.pt_head_process); while(*pt_cur_process != PsGetProcessPtr(ProcessHandle)) { /* there is no requested process in the list */ if((*pt_cur_process)->pt_next_process == NULL) { goto $exit; } pt_prev_process = pt_cur_process; pt_cur_process = &((*pt_cur_process)->pt_next_process); } /* change next process pointer */ (*pt_prev_process)->pt_next_process = (*pt_cur_process)->pt_next_process; m_ProcMgrBlk.process_count--; /* dealloc all threads belonged to the requested process */ pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != NULL) { MmFreeNonCachedMemory((PVOID)((*pt_cur_thread)->pt_stack_base_address)); MmFreeNonCachedMemory((PVOID)(*pt_cur_thread)); pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } /* dealloc the requested process memory */ MmFreeNonCachedMemory((PVOID)ProcessHandle); $exit: EXIT_CRITICAL_SECTION(); } return 0; }
static BOOL PspAddNewThread(HANDLE ProcessHandle, HANDLE ThreadHandle) { PTHREAD_CONTROL_BLOCK *pt_next_thread; ENTER_CRITICAL_SECTION(); pt_next_thread = &PsGetProcessPtr(ProcessHandle)->pt_head_thread; while(*pt_next_thread) pt_next_thread = &(*pt_next_thread)->pt_next_thread; *pt_next_thread = PsGetThreadPtr(ThreadHandle); PsGetProcessPtr(ProcessHandle)->thread_count++; EXIT_CRITICAL_SECTION(); return TRUE; }
static HANDLE PspFindNextThreadScheduled(void) { PTHREAD_CONTROL_BLOCK pt_thread; PPROCESS_CONTROL_BLOCK pt_process; if(m_ProcMgrBlk.process_count == 0 || m_ProcMgrBlk.pt_current_thread == NULL || m_ProcMgrBlk.pt_head_process == NULL) { return NULL; } /* if there are no threads to be scheduled, this fuction never returns */ pt_thread = m_ProcMgrBlk.pt_current_thread; $find_thread: if(pt_thread->pt_next_thread != NULL) { pt_thread = pt_thread->pt_next_thread; } else { while(1) { pt_process = PsGetProcessPtr(pt_thread->parent_process_handle)->pt_next_process; $find_process: if(pt_process == NULL) pt_process = m_ProcMgrBlk.pt_head_process; if(pt_process->pt_head_thread == NULL) { pt_process = pt_process->pt_next_process; goto $find_process; } else { pt_thread = pt_process->pt_head_thread; break; } } /* while(1) */ } if(pt_thread->thread_status != THREAD_STATUS_READY && pt_thread->thread_status != THREAD_STATUS_RUNNING) goto $find_thread; m_ProcMgrBlk.pt_current_thread = pt_thread; /* replace the current thread handle */ return (HANDLE)pt_thread; }
//다음 실행 가능한 쓰레드를 찾기 위한 함수 static HANDLE PspFindNextThreadScheduled(void) { PTHREAD_CONTROL_BLOCK pt_thread; PPROCESS_CONTROL_BLOCK pt_process; if(m_ProcMgrBlk.process_count == 0 || m_ProcMgrBlk.pt_current_thread == NULL || m_ProcMgrBlk.pt_head_process == NULL) { return NULL; } pt_thread = m_ProcMgrBlk.pt_current_thread; $find_thread: if(pt_thread->pt_next_thread != NULL) { pt_thread = pt_thread->pt_next_thread; } else { while(1) { pt_process = PsGetProcessPtr(pt_thread->parent_process_handle)->pt_next_process; $find_process: if(pt_process == NULL) pt_process = m_ProcMgrBlk.pt_head_process; if(pt_process->pt_head_thread == NULL) { pt_process = pt_process->pt_next_process; goto $find_process; } else { pt_thread = pt_process->pt_head_thread; break; } } } if(pt_thread->thread_status != THREAD_STATUS_READY && pt_thread->thread_status != THREAD_STATUS_RUNNING) goto $find_thread; m_ProcMgrBlk.pt_current_thread = pt_thread; return (HANDLE)pt_thread; }
//종료된 쓰레드의 삭제 static DWORD PspThreadCutterThread(PVOID StartContext) { HANDLE ProcessHandle, ThreadHandle; PTHREAD_CONTROL_BLOCK *pt_prev_thread, *pt_cur_thread; while(1) { if(!PspPopCuttingItem(&m_ThreadCuttingList, &ThreadHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); ProcessHandle = PsGetThreadPtr(ThreadHandle)->parent_process_handle; if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } if(PsGetProcessPtr(ProcessHandle)->thread_count == 0) { goto $exit; } else if(PsGetProcessPtr(ProcessHandle)->thread_count == 1) { PsGetProcessPtr(ProcessHandle)->pt_head_thread = NULL; } else { pt_prev_thread = pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != PsGetThreadPtr(ThreadHandle)) { if((*pt_cur_thread)->pt_next_thread == NULL) { goto $exit; } pt_prev_thread = pt_cur_thread; pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } (*pt_prev_thread)->pt_next_thread = (*pt_cur_thread)->pt_next_thread; } PsGetProcessPtr(ProcessHandle)->thread_count--; if(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address >= (int *)0x00200000) MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address)); MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle))); $exit: EXIT_CRITICAL_SECTION(); } }
static DWORD PspGetNextThreadID(HANDLE ProcessHandle) { DWORD thread_id; ENTER_CRITICAL_SECTION(); thread_id = PsGetProcessPtr(ProcessHandle)->next_thread_id++; EXIT_CRITICAL_SECTION(); return thread_id; }
//종료된 프로세스의 삭제 static DWORD PspProcessCutterThread(PVOID StartContext) { HANDLE ProcessHandle; PPROCESS_CONTROL_BLOCK *pt_prev_process, *pt_cur_process; PTHREAD_CONTROL_BLOCK *pt_cur_thread; while(1) { if(!PspPopCuttingItem(&m_ProcessCuttingList, &ProcessHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } pt_prev_process = pt_cur_process = &(m_ProcMgrBlk.pt_head_process); while(*pt_cur_process != PsGetProcessPtr(ProcessHandle)) { if((*pt_cur_process)->pt_next_process == NULL) { goto $exit; } pt_prev_process = pt_cur_process; pt_cur_process = &((*pt_cur_process)->pt_next_process); } (*pt_prev_process)->pt_next_process = (*pt_cur_process)->pt_next_process; m_ProcMgrBlk.process_count--; pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != NULL) { MmFreeNonCachedMemory((PVOID)((*pt_cur_thread)->pt_stack_base_address)); MmFreeNonCachedMemory((PVOID)(*pt_cur_thread)); pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } MmFreeNonCachedMemory((PVOID)ProcessHandle); $exit: EXIT_CRITICAL_SECTION(); } return 0; }
static BOOL PspAddNewProcess(HANDLE ProcessHandle) { PPROCESS_CONTROL_BLOCK *pt_next_process; ENTER_CRITICAL_SECTION(); pt_next_process = &m_ProcMgrBlk.pt_head_process; while(*pt_next_process) pt_next_process = &(*pt_next_process)->pt_next_process; *pt_next_process = PsGetProcessPtr(ProcessHandle); m_ProcMgrBlk.process_count++; EXIT_CRITICAL_SECTION(); return TRUE; }