📄 ktmgr.cpp
字号:
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
if((0 == lpManager->dwNextWakeupTick) ||
(lpManager->dwNextWakeupTick > dwTmpCounter))
lpManager->dwNextWakeupTick = dwTmpCounter; //Update dwNextWakeupTick value.
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_SLEEPING;
dwTmpCounter = MAX_DWORD_VALUE - dwTmpCounter; //Calculates the priority of the
//current kernel thread in the sleeping
//queue.
lpManager->lpSleepingQueue->InsertIntoQueue((__COMMON_OBJECT*)lpManager->lpSleepingQueue,
(__COMMON_OBJECT*)lpKernelThread,
dwTmpCounter);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
//lpContext = &lpKernelThread->KernelThreadContext;
lpManager->ScheduleFromProc(NULL);
return TRUE;
}
//CancelSleep Routine.
static BOOL CancelSleep(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpKernelThread)
{
return FALSE;
}
//SetCurrentIRQL.
static DWORD SetCurrentIRQL(__COMMON_OBJECT* lpThis,DWORD dwNewIRQL)
{
return 0L;
}
//GetCurrentIRQL.
static DWORD GetCurrentIRQL(__COMMON_OBJECT* lpThis)
{
return 0L;
}
//SetLastError.
static DWORD SetLastError(/*__COMMON_OBJECT* lpKernelThread,*/DWORD dwNewError)
{
DWORD dwOldError = 0L;
dwOldError = KernelThreadManager.lpCurrentKernelThread->dwLastError;
KernelThreadManager.lpCurrentKernelThread->dwLastError = dwNewError;
return dwOldError;
}
//GetLastError.
static DWORD GetLastError(/*__COMMON_OBJECT* lpKernelThread*/)
{
return KernelThreadManager.lpCurrentKernelThread->dwLastError;
}
//GetThreadID.
static DWORD GetThreadID(__COMMON_OBJECT* lpKernelThread)
{
if(NULL == lpKernelThread)
return 0L;
return ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwThreadID;
}
//GetThreadStatus.
static DWORD GetThreadStatus(__COMMON_OBJECT* lpKernelThread)
{
if(NULL == lpKernelThread)
return 0L;
return ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwThreadStatus;
}
//SetThreadStatus.
static DWORD SetThreadStatus(__COMMON_OBJECT* lpKernelThread,DWORD dwStatus)
{
return 0L;
}
//MsgQueueFull.
static BOOL MsgQueueFull(__COMMON_OBJECT* lpThread)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
if(NULL == lpThread) //Parameter check.
return FALSE;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
return MAX_KTHREAD_MSG_NUM == lpKernelThread->ucCurrentMsgNum ? TRUE : FALSE;
}
//MsgQueueEmpty.
static BOOL MsgQueueEmpty(__COMMON_OBJECT* lpThread)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
if(NULL == lpThread) //Parameter check.
return FALSE;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
return 0 == lpKernelThread->ucCurrentMsgNum ? TRUE : FALSE;
}
//SendMessage.
static BOOL MgrSendMessage(__COMMON_OBJECT* lpThread,__KERNEL_THREAD_MESSAGE* lpMsg)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__KERNEL_THREAD_OBJECT* lpNewThread = NULL;
BOOL bResult = FALSE;
DWORD dwFlags = 0L;
if((NULL == lpThread) || (NULL == lpMsg)) //Parameters check.
return bResult;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(MsgQueueFull(lpThread)) //Message queue is full.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return bResult;
}
//Message queue not full,put the message to the queue.
lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueTrial].wCommand
= lpMsg->wCommand;
lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueTrial].wParam
= lpMsg->wParam;
lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueTrial].dwParam
= lpMsg->dwParam;
lpKernelThread->ucMsgQueueTrial ++;
if(MAX_KTHREAD_MSG_NUM == lpKernelThread->ucMsgQueueTrial)
lpKernelThread->ucMsgQueueTrial = 0; //so the message queue is a circle
lpKernelThread->ucCurrentMsgNum ++; //by this para, one can check if the queue is full?
lpNewThread = (__KERNEL_THREAD_OBJECT*)lpKernelThread->lpMsgWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpKernelThread->lpMsgWaitingQueue,
NULL);
if(lpNewThread) //Should wakeup the target kernel thread.
{
lpNewThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.AddReadyKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpNewThread); //Add to ready queue.
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
//
//If in kernel thread context,then re-schedule kernel thread.
//
if(IN_KERNELTHREAD()) //---- !!!!!!!! PROBLEM CAUSED !!!!!!!! ----
{
KernelThreadManager.ScheduleFromProc(NULL);
}
bResult = TRUE;
return bResult;
}
//GetMessage.
static BOOL MgrGetMessage(__COMMON_OBJECT* lpThread,__KERNEL_THREAD_MESSAGE* lpMsg)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
if((NULL == lpThread) || (NULL == lpMsg)) //Parameters check.
return FALSE;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(MsgQueueEmpty(lpThread)) //Current message queue is empty,should waiting.
{
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
lpKernelThread->lpMsgWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpKernelThread->lpMsgWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.ScheduleFromProc(NULL); //Re-schedule.
//lpKernelThread->lpMsgEvent->WaitForThisObject(
// (__COMMON_OBJECT*)(lpKernelThread->lpMsgEvent)); //Block the current thread.
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
lpMsg->wCommand = lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueHeader].wCommand;
lpMsg->wParam = lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueHeader].wParam;
lpMsg->dwParam = lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueHeader].dwParam;
lpKernelThread->ucMsgQueueHeader ++;
if(MAX_KTHREAD_MSG_NUM == lpKernelThread->ucMsgQueueHeader)
lpKernelThread->ucMsgQueueHeader = 0x0000;
lpKernelThread->ucCurrentMsgNum --;
//if(0 == lpKernelThread->ucCurrentMsgNum) //The message queue is empty.
// lpKernelThread->lpMsgEvent->ResetEvent((__COMMON_OBJECT*)(lpKernelThread->lpMsgEvent));
//LEAVE_CRITICAL_SECTION(); //Enable the interrupt.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return TRUE;
}
//
//The following routine is used to lock a kernel thread,especially the current kernel thread.
//When a kernel thread is locked,it can not be interrupted,even a kernel thread with high priority
//ready to run.The different between lock kernel thread and lock interrupt is,when interrupt is
//locked,the system will never be interrupted by hardware,and the schedule will never occur,because
//timer interrupt also be locked,but when lock a kernel thread,only disables the schedule of the
//system,interrupt is not locked,so,hardware interrupt can also be processed by system.
//CAUTION: When lock a kernel thread,you must unlock it by calling UnlockKernelThread routine to
//unlock the kernel thread,otherwise,others kernel thread(s) will never be scheduled.
//
static BOOL LockKernelThread(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpThread)
{
__KERNEL_THREAD_MANAGER* lpManager = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis) //Parameter check.
return FALSE;
lpManager = (__KERNEL_THREAD_MANAGER*)lpThis;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
lpKernelThread = (NULL == lpThread) ? lpManager->lpCurrentKernelThread :
(__KERNEL_THREAD_OBJECT*)lpThread; //If lpThread is NULL,then lock the current kernel thread.
if(KERNEL_THREAD_STATUS_RUNNING != lpKernelThread->dwThreadStatus)
{
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
return FALSE;
}
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED; //Once mark the status of
//the target thread to
//BLOCKED,it will never be
//switched out.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
return TRUE;
}
//
//The following routine unlockes a kernel thread who is locked by LockKernelThread routine.
//
static VOID UnlockKernelThread(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpThread)
{
__KERNEL_THREAD_MANAGER* lpManager = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis) //Parameter check.
return;
lpManager = (__KERNEL_THREAD_MANAGER*)lpThis;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
lpKernelThread = (NULL == lpThread) ? lpManager->lpCurrentKernelThread :
(__KERNEL_THREAD_OBJECT*)lpThread;
if(KERNEL_THREAD_STATUS_BLOCKED != lpKernelThread->dwThreadStatus) //If not be locked.
{
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
return;
}
/**************************************************************
***************************************************************
***************************************************************
**************************************************************/
//
//The definition of Kernel Thread Manager.
//
__KERNEL_THREAD_MANAGER KernelThreadManager = {
0L, //dwCurrentIRQL.
NULL, //CurrentKernelThread.
NULL, //lpRunningQueue.
//NULL, //lpReadyQueue.
NULL, //lpSuspendedQueue.
NULL, //lpSleepingQueue.
NULL, //lpTerminalQueue.
{0}, //Ready queue array.
//0L, //dwClockTickCounter.
0L, //dwNextWakeupTick.
NULL, //lpCreateHook.
NULL, //lpEndScheduleHook.
NULL, //lpBeginScheduleHook.
NULL, //lpTerminalHook.
SetThreadHook, //SetThreadHook.
CallThreadHook, //CallThreadHook.
GetScheduleKernelThread, //GetScheduleKernelThread.
AddReadyKernelThread, //AddReadyKernelThread.
KernelThreadMgrInit, //Initialize routine.
CreateKernelThread, //CreateKernelThread routine.
DestroyKernelThread, //DestroyKernelThread routine.
SuspendKernelThread, //SuspendKernelThread routine.
ResumeKernelThread, //ResumeKernelThread routine.
ScheduleFromProc, //ScheduleFromProc routine.
ScheduleFromInt, //ScheduleFromInt routine.
SetThreadPriority, //SetThreadPriority routine.
GetThreadPriority, //GetThreadPriority routine.
TerminalKernelThread, //TerminalKernelThread routine.
Sleep, //Sleep routine.
CancelSleep, //CancelSleep routine.
SetCurrentIRQL, //SetCurrentIRQL routine.
GetCurrentIRQL, //GetCurrentIRQL routine.
GetLastError, //GetLastError routine.
SetLastError, //SetLastError routine.
GetThreadID, //GetThreadID routine.
GetThreadStatus, //GetThreadStatus routine.
SetThreadStatus, //SetThreadStatus routine.
MgrSendMessage, //SendMessage routine.
MgrGetMessage, //GetMessage routine.
MsgQueueFull, //MsgQueueFull routine.
MsgQueueEmpty, //MsgQueueEmpty routine.
LockKernelThread, //LockKernelThread routine.
UnlockKernelThread //UnlockKernelThread routine.
};
//
/**************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
***************************************************************************************/
//
//Dispatch a message to an message(event) handler.
//
DWORD DispatchMessage(__KERNEL_THREAD_MESSAGE* lpMsg,__KERNEL_THREAD_MESSAGE_HANDLER lpHandler)
{
return lpHandler(lpMsg->wCommand,lpMsg->wParam,lpMsg->dwParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -