Beispiel #1
0
//DeviceRead for WINHD driver.
static DWORD DeviceRead(__COMMON_OBJECT* lpDrv,
						__COMMON_OBJECT* lpDev,
						__DRCB* lpDrcb)
{
	__PARTITION_EXTENSION* pPe = NULL;
	__DEVICE_OBJECT* pDevice = (__DEVICE_OBJECT*)lpDev;
	DWORD dwResult = 0;
	DWORD dwStart  = 0;
	DWORD dwFlags;

	if((NULL == lpDev) || (NULL == lpDrcb))  //Invalid parameters.
	{
		goto __TERMINAL;
	}
	pPe = (__PARTITION_EXTENSION*)pDevice->lpDevExtension;
	if(NULL == pPe)  //Should not occur,or else the OS kernel may have fatal error.
	{
		goto __TERMINAL;
	}
	//Check the validity of DRCB object transferred.
	if(DRCB_REQUEST_MODE_READ != lpDrcb->dwRequestMode) //Invalid operation action.
	{
		goto __TERMINAL;
	}
 	if((NULL == lpDrcb->lpOutputBuffer) || (0 == lpDrcb->dwOutputLen))
	{
		goto __TERMINAL;
	}
	if(0 != lpDrcb->dwOutputLen % pDevice->dwBlockSize)  //Only block size request is
		                                                 //legally.
	{
		goto __TERMINAL;
	}
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	//Check if current position is in device end.
	if(pPe->dwCurrPos == pPe->dwSectorNum)
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		goto __TERMINAL;
	}
	dwResult = lpDrcb->dwOutputLen / pDevice->dwBlockSize;
	//Check if exceed the device boundry after read.
	if(pPe->dwCurrPos + dwResult >= pPe->dwSectorNum)  //Exceed end boundry.
	{
		dwResult = pPe->dwSectorNum - pPe->dwCurrPos;  //Only partial data of the
		                                               //requested can be read.
	}
	dwStart = pPe->dwCurrPos + pPe->dwStartSector;     //Read start this position,in sector number.
	pPe->dwCurrPos += dwResult;  //Adjust current pointer.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	//Now issue read command to read data from device.
	if(!ReadSector(0,dwStart,dwResult,(BYTE*)lpDrcb->lpOutputBuffer))  //Can not read data.
	{
 		dwResult = 0;
		goto __TERMINAL;
	}
	dwResult *= pDevice->dwBlockSize;  //dwResult now is the byte number just read.
__TERMINAL:
	return dwResult;
}
Beispiel #2
0
//static
DWORD kWaitForEventObject(__COMMON_OBJECT* lpThis)
{
    __EVENT*                      lpEvent             = (__EVENT*)lpThis;
    __KERNEL_THREAD_OBJECT*       lpKernelThread      = NULL;
    //__KERNEL_THREAD_CONTEXT*      lpContext           = NULL;
    DWORD                         dwFlags             = 0;

    if(NULL == lpEvent)
    {
        return OBJECT_WAIT_FAILED;
    }

    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    if(EVENT_STATUS_FREE == lpEvent->dwEventStatus)
    {
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
        return OBJECT_WAIT_RESOURCE;
    }
    else
    {
        lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
        lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
        lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_WAITING;
        lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
        lpEvent->lpWaitingQueue->InsertIntoQueue(
            (__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
            (__COMMON_OBJECT*)lpKernelThread,
            0);
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);    //Leave critical section here is safety.
        KernelThreadManager.ScheduleFromProc(NULL);
    }
    return OBJECT_WAIT_RESOURCE;
}
Beispiel #3
0
static DWORD WaitForEventObject(struct __COMMON_OBJECT* lpThis)
{
	struct __EVENT*                      lpEvent             = NULL;
	struct __KERNEL_THREAD_OBJECT*       lpKernelThread      = NULL;
	__KERNEL_THREAD_CONTEXT*      lpContext           = NULL;
	DWORD                         dwFlags             = 0L;

	if(NULL == lpThis)
		return OBJECT_WAIT_FAILED;

	lpEvent = (struct __EVENT*)lpThis;

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);

	if(EVENT_STATUS_FREE == lpEvent->dwEventStatus)
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return OBJECT_WAIT_RESOURCE;
	}
	else
	{
		lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
		lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
		lpEvent->lpWaitingQueue->InsertIntoQueue(
			(struct __COMMON_OBJECT*)lpEvent->lpWaitingQueue,
			(struct __COMMON_OBJECT*)lpKernelThread,
			0L);

		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);    //Leave critical section here is safety.

		//lpContext = &lpKernelThread->KernelThreadContext;
		KernelThreadManager.ScheduleFromProc(NULL);
	}
	return OBJECT_WAIT_RESOURCE;
}
Beispiel #4
0
//The implementation of RegisterFileSystem.
static BOOL AddFileSystem(__COMMON_OBJECT* lpThis,
						  __COMMON_OBJECT* lpDevObj,
						  DWORD            dwAttribute,
						  CHAR*            pVolumeLbl)
{
	BOOL                       bResult      = FALSE;
	__IO_MANAGER*              pMgr         = (__IO_MANAGER*)lpThis;
	__DEVICE_OBJECT*           pFileSystem  = (__DEVICE_OBJECT*)lpDevObj;
	BYTE                       FsIdentifier = 'C';  //First file system identifier.
	DWORD                      dwFlags;
	int                        i,j,k;

	if((NULL == pMgr) || (NULL == pFileSystem))  //Invalid parameters.
	{
		goto __TERMINAL;
	}
	//Seek the empty slot of file system array,if there is.
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	for(i = 0;i < FILE_SYSTEM_NUM;i ++)
	{
		if(0 == pMgr->FsArray[i].FileSystemIdentifier)  //Empty slot.
		{
			break;
		}
	}
	if(FILE_SYSTEM_NUM == i)  //No slot is free.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		goto __TERMINAL;
	}
	//Calculate the file system identifier,if the maximal file system identifier
	//in current array is x,then use x + 1 as new file system's identifier.
	for(j = 0;j < FILE_SYSTEM_NUM;j ++)
	{
		if(pMgr->FsArray[j].FileSystemIdentifier >= FsIdentifier)
		{
			FsIdentifier += 1;  //Use next one.
		}
	}
	pMgr->FsArray[i].FileSystemIdentifier = FsIdentifier;
	pMgr->FsArray[i].pFileSystemObject    = (__COMMON_OBJECT*)pFileSystem;
	pMgr->FsArray[i].dwAttribute          = dwAttribute;
	//Set volume lable.
	k = 0;
	for(j = 0;j < VOLUME_LBL_LEN - 1;j ++)
	{
		if(' ' == pVolumeLbl[j])  //Skip space.
		{
			continue;
		}
		pMgr->FsArray[i].VolumeLbl[k] = pVolumeLbl[j];
		k += 1;
	}
	pMgr->FsArray[i].VolumeLbl[k] = 0;   //Set terminator.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	bResult = TRUE;

__TERMINAL:
	return bResult;
}
Beispiel #5
0
//RegisterFileSystem,this routine add one file system controller into system.
static BOOL RegisterFileSystem(__COMMON_OBJECT* lpThis,
							   __COMMON_OBJECT* pFileSystem)
{
	__IO_MANAGER*       pManager = (__IO_MANAGER*)lpThis;
	DWORD               dwFlags;
	int                 i = 0;

	if((NULL == pFileSystem) || (NULL == lpThis)) //Invalid parameters.
	{
		return FALSE;
	}
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	for(i = 0;i < FS_CTRL_NUM;i ++)
	{
		if(NULL == pManager->FsCtrlArray[i]) //Find a empty slot.
		{
			break;
		}
	}
	if(FS_CTRL_NUM == i)  //Can not find a empty slot.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return FALSE;
	}
	//Insert the file system object into this slot.
	pManager->FsCtrlArray[i] = pFileSystem;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return TRUE;
}
Beispiel #6
0
static VOID kVirtualFree(__COMMON_OBJECT* lpThis,LPVOID lpVirtualAddr)
{
	__VIRTUAL_MEMORY_MANAGER*            lpMemMgr   = (__VIRTUAL_MEMORY_MANAGER*)lpThis;
	__VIRTUAL_AREA_DESCRIPTOR*           lpVad      = NULL;
	__PAGE_INDEX_MANAGER*                lpIndexMgr = NULL;
	BOOL                                 bResult    = FALSE;
	DWORD                                dwFlags    = 0;

	if((NULL == lpThis) || (NULL == lpVirtualAddr)) //Invalidate parameters.
		return;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	if(lpMemMgr->dwVirtualAreaNum < SWITCH_VA_NUM)  //Should search in the list.
		lpVad = GetVaByAddr_l(lpThis,lpVirtualAddr);    //Get the virtual area descriptor.
	else
		lpVad = GetVaByAddr_t(lpThis,lpVirtualAddr);
	if(NULL == lpVad)    //This virtual address is not allocated yet.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		goto __TERMINAL;
	}
	//
	//Now,we have got the virtual area descriptor object,so,
	//first delete it from list or tree.
	//
	if(lpMemMgr->dwVirtualAreaNum < SWITCH_VA_NUM)  //Delete from list.
		DelVaFromList(lpThis,lpVad);
	else                                            //Delete from tree.
		DelVaFromTree(lpThis,lpVad);

	//
	//According to different allocating type,to do the different actions.
	//
	switch(lpVad->dwAllocFlags)
	{
	case VIRTUAL_AREA_ALLOCATE_COMMIT:    //The virtual memory area is committed.
		ReleaseCommit(lpThis,lpVad);
		KMemFree((LPVOID)lpVad,KMEM_SIZE_TYPE_ANY,0);  //Release the memory occupied by
		                                                //virtual area descriptor.
		break;
	case VIRTUAL_AREA_ALLOCATE_RESERVE:   //Only reserved.
		KMemFree((LPVOID)lpVad,KMEM_SIZE_TYPE_ANY,0);  //Only release the memory.
		break;
	case VIRTUAL_AREA_ALLOCATE_IO:        //Committed,but without physical memory pages.
		ReleaseIoMap(lpThis,lpVad);
		KMemFree((LPVOID)lpVad,KMEM_SIZE_TYPE_ANY,0);
		break;
	default:
		break;
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	bResult = TRUE;    //Set the completing flags.

__TERMINAL:
	return;
}
Beispiel #7
0
//Several helper routines used by DeviceCtrl.
static DWORD __CtrlSectorRead(__COMMON_OBJECT* lpDrv,
							  __COMMON_OBJECT* lpDev,
							  __DRCB* lpDrcb)
{
	__PARTITION_EXTENSION* pPe     = NULL;
	__DEVICE_OBJECT*       pDevice = (__DEVICE_OBJECT*)lpDev;
	DWORD dwStartSector        = 0;
	DWORD dwSectorNum          = 0;
	int   nDiskNum             = 0;
	DWORD i;
	DWORD dwFlags;

	//Parameter validity checking.
	if((NULL == lpDrcb->lpOutputBuffer) || (0 == lpDrcb->dwOutputLen))
	{
		return 0;
	}
	if((NULL == lpDrcb->lpInputBuffer) || (0 == lpDrcb->dwInputLen))
	{
		return 0;
	}
	//Get start sector and sector number to read.
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	pPe = (__PARTITION_EXTENSION*)pDevice->lpDevExtension;
	dwStartSector = *(DWORD*)(lpDrcb->lpInputBuffer);  //Input buffer stores the start pos.
	if(lpDrcb->dwOutputLen % pDevice->dwBlockSize)     //Always integral block size times is valid.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return 0;
	}
	dwSectorNum = lpDrcb->dwOutputLen / pDevice->dwBlockSize;
	//Check if the reading data exceed the device boundry.
	//if((dwStartSector + dwSectorNum) > (pPe->dwStartSector + pPe->dwSectorNum))
	if((dwStartSector + dwSectorNum) > pPe->dwSectorNum)
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return 0;
	}
	dwStartSector += pPe->dwStartSector;
	nDiskNum       = pPe->nDiskNum;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	//Now issue the reading command.
	for(i = 0;i < dwSectorNum;i ++)
	{
		if(!ReadSector(nDiskNum,dwStartSector + i,1,((BYTE*)lpDrcb->lpOutputBuffer) + 512*i))
		{
			return FALSE;
		}
	}
	//return ReadSector(nDiskNum,dwStartSector,dwSectorNum,(BYTE*)lpDrcb->lpOutputBuffer);
	return TRUE;
}
Beispiel #8
0
static DWORD __CtrlSectorWrite(__COMMON_OBJECT* lpDrv,
							   __COMMON_OBJECT* lpDev,
							   __DRCB* lpDrcb)
{	
	__PARTITION_EXTENSION* pPe     = NULL;
	__DEVICE_OBJECT*       pDevice = (__DEVICE_OBJECT*)lpDev;
	__SECTOR_INPUT_INFO*   psii    = NULL;
	DWORD dwStartSector        = 0;
	DWORD dwSectorNum          = 0;
	int   nDiskNum             = 0;
	DWORD i;
	DWORD dwFlags;

	//Parameter validity checking.
	if((NULL == lpDrcb->lpInputBuffer) || (0 == lpDrcb->dwInputLen))
	{
		return 0;
	}
	psii = (__SECTOR_INPUT_INFO*)lpDrcb->lpInputBuffer;

	//Get start sector and sector number to read.
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	pPe = (__PARTITION_EXTENSION*)pDevice->lpDevExtension;
	if(psii->dwBufferLen % pDevice->dwBlockSize)   //Always integral block size times is valid.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return 0;
	}
	dwSectorNum = psii->dwBufferLen / pDevice->dwBlockSize;
	//Check if the reading data exceed the device boundry.
	if((psii->dwStartSector + dwSectorNum) > (pPe->dwStartSector + pPe->dwSectorNum))
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return 0;
	}
	dwStartSector = psii->dwStartSector + pPe->dwStartSector;
	nDiskNum = pPe->nDiskNum;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	//Now issue the reading command.
	for(i = 0;i < dwSectorNum;i ++)
	{
		if(!WriteSector(nDiskNum,dwStartSector + i,1,((BYTE*)psii->lpBuffer) + 512*i))
		{
			return FALSE;
		}
	}
	return TRUE;
}
Beispiel #9
0
VOID MutexUninitialize(struct __COMMON_OBJECT* lpThis)
{
	struct __PRIORITY_QUEUE*       lpWaitingQueue  = NULL;
	struct __KERNEL_THREAD_OBJECT* lpKernelThread  = NULL;
	DWORD                   dwFlags;

	if(NULL == lpThis) //parameter check.
	{
		BUG();
		return;
	}

	lpWaitingQueue = ((__MUTEX*)lpThis)->lpWaitingQueue;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpKernelThread = (struct __KERNEL_THREAD_OBJECT*)lpWaitingQueue->GetHeaderElement(
		(struct __COMMON_OBJECT*)lpWaitingQueue,
		NULL);
	while(lpKernelThread)
	{
		lpKernelThread->dwThreadStatus   = KERNEL_THREAD_STATUS_READY;
		lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
		lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_DELETED;
		KernelThreadManager.AddReadyKernelThread(
			(struct __COMMON_OBJECT*)&KernelThreadManager,
			lpKernelThread);
		lpKernelThread = (struct __KERNEL_THREAD_OBJECT*)lpWaitingQueue->GetHeaderElement(
			(struct __COMMON_OBJECT*)lpWaitingQueue,
			NULL);
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	ObjectManager.DestroyObject(&ObjectManager,
		(struct __COMMON_OBJECT*)lpWaitingQueue);
	return;
}
Beispiel #10
0
//OpenDevice operations,it will be called indirectly by CreateFile.
static __COMMON_OBJECT* ComDeviceOpen(__COMMON_OBJECT* lpDrv,__COMMON_OBJECT* lpDev,
                                                                                      __DRCB* lpDrcb)
{
         __COMMON_OBJECT*      pRet       = NULL;
         __COM_CONTROL_BLOCK*  pCtrlBlock = NULL; 
         DWORD                 dwFlags;
 
         if(NULL == lpDev)
         {
                   goto __TERMINAL;
         }
         //Get interface control block from device extension.
         pCtrlBlock = (__COM_CONTROL_BLOCK*)((__DEVICE_OBJECT*)lpDev)->lpDevExtension;
         if(NULL == pCtrlBlock)
         {
                   goto __TERMINAL;
         }
         //The COM device can noly be opened once.
         __ENTER_CRITICAL_SECTION(NULL,dwFlags);
         if(0 == pCtrlBlock->nOpenCount)  //Not opened yet.
         {
                   pCtrlBlock->nOpenCount ++;
                   pRet = lpDev;
         }
         else  //Opened yet.
         {
                   pRet = NULL;
         }
         __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
 
__TERMINAL:
         return pRet;
}
Beispiel #11
0
//
//The implementation of InsertIntoQueue.
//This routine allocate a queue element object,initialize it,and 
//put the element object into queue.
//
static BOOL    InsertIntoQueue(__COMMON_OBJECT* lpThis,LPVOID lpObject)
{
	__COMMON_QUEUE*            lpCommQueue = (__COMMON_QUEUE*)lpThis;
	__COMMON_QUEUE_ELEMENT*    lpQueueEle  = NULL;
	DWORD                      dwFlags     = 0L;

	if(NULL == lpThis)    //Invalidate parameter.
		return FALSE;
	if(CommQueueFull(lpThis)) //The current queue is full.
		return FALSE;

	lpQueueEle = ALLOCATE_QUEUE_ELEMENT();
	if(NULL == lpQueueEle)  //Can not allocate queue element.
		return FALSE;
	lpQueueEle->lpObject = lpObject;
	//
	//The following code puts the queue element into comnon queue,
	//and increase current queue element number.
	//
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpQueueEle->lpNext = lpCommQueue->QueueHdr.lpNext;
	lpQueueEle->lpPrev = &lpCommQueue->QueueHdr;
	lpCommQueue->QueueHdr.lpNext->lpPrev = lpQueueEle;
	lpCommQueue->QueueHdr.lpNext = lpQueueEle;
	lpCommQueue->dwCurrentLen ++;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	return TRUE;
}
Beispiel #12
0
//CloseDevice operations,it will be called indirectly by CloseFile.
static DWORD ComDeviceClose(__COMMON_OBJECT* lpDrv,__COMMON_OBJECT* lpDev,
                                                                 __DRCB* lpDrcb)
{
         __COM_CONTROL_BLOCK*  pCtrlBlock = NULL; 
         DWORD                 dwFlags;
 
         if(NULL == lpDev)
         {
                   goto __TERMINAL;
         }
         //Get interface control block from device extension.
         pCtrlBlock = (__COM_CONTROL_BLOCK*)((__DEVICE_OBJECT*)lpDev)->lpDevExtension;
         if(NULL == pCtrlBlock)
         {
                   goto __TERMINAL;
         }
         __ENTER_CRITICAL_SECTION(NULL,dwFlags);
         if(1 == pCtrlBlock->nOpenCount)
         {
                   pCtrlBlock->nOpenCount --;
         }
         __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
 
__TERMINAL:
         return 0;
}
Beispiel #13
0
//Handler to handle the receive(RXNE) interrupt,DA means Data Available here,the name
//inherites from COM driver implemented on X86 platform.
static VOID DAIntHandler(__USART_CONTROL_BLOCK* pCtrlBlock)
{
    CHAR                bt;
    DWORD               dwFlags;


    //Process data available interrupt.
    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    while(IsDataAvailable(pCtrlBlock->dwUsartBase))  //Data available.
    {
        bt = GetUsartByte(pCtrlBlock->dwUsartBase);  //Read the byte.
        pCtrlBlock->Buffer[pCtrlBlock->nBuffTail] = bt;
        pCtrlBlock->nBuffTail ++;
        if(COM_BUFF_LENGTH == pCtrlBlock->nBuffTail)  //Reach end of buffer.
        {
            pCtrlBlock->nBuffTail = 0;
        }
        if(pCtrlBlock->nBuffHeader == pCtrlBlock->nBuffTail)  //Buffer full.
        {
            break;
        }
    }
    while(IsDataAvailable(pCtrlBlock->dwUsartBase))  //Drain out all data from COM interface,since the buffer is full.
    {
        GetUsartByte(pCtrlBlock->dwUsartBase);
    }
    //Wake up all threads waiting for COM data.
    while(pCtrlBlock->pReadingList)
    {
        pCtrlBlock->pReadingList->OnCompletion((__COMMON_OBJECT*)pCtrlBlock->pReadingList);
        pCtrlBlock->pReadingList = pCtrlBlock->pReadingList->lpNext;
    }
    pCtrlBlock->pReadingListTail = NULL;
    __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
}
Beispiel #14
0
//
//SetThreadHook routine,this routine sets appropriate hook routine
//according to dwHookType, and returns the old one.
//
__THREAD_HOOK_ROUTINE SetThreadHook(DWORD dwHookType,
									__THREAD_HOOK_ROUTINE lpRoutine)
{
	__THREAD_HOOK_ROUTINE lpOldRoutine = NULL;
	DWORD                 dwFlags;

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	switch(dwHookType)
	{
	case THREAD_HOOK_TYPE_CREATE:
		lpOldRoutine = KernelThreadManager.lpCreateHook;
		KernelThreadManager.lpCreateHook = lpRoutine;
		break;
	case THREAD_HOOK_TYPE_ENDSCHEDULE:
		lpOldRoutine = KernelThreadManager.lpEndScheduleHook;
		KernelThreadManager.lpEndScheduleHook = lpRoutine;
		break;
	case THREAD_HOOK_TYPE_BEGINSCHEDULE:
		lpOldRoutine = KernelThreadManager.lpBeginScheduleHook;
		KernelThreadManager.lpBeginScheduleHook = lpRoutine;
		break;
	case THREAD_HOOK_TYPE_TERMINAL:
		lpOldRoutine = KernelThreadManager.lpTerminalHook;
		KernelThreadManager.lpTerminalHook = lpRoutine;
		break;
	default:  //Should not reach here.
		BUG();
		break;
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return lpOldRoutine;
}
Beispiel #15
0
//
//CancelTimer implementation.
//This routine is used to cancel timer.
//
static VOID CancelTimer(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpTimer)
{
	__SYSTEM*                  lpSystem       = NULL;
	DWORD                      dwPriority     = 0;
	DWORD                      dwFlags;
	__TIMER_OBJECT*            lpTimerObject  = NULL;

	if((NULL == lpThis) || (NULL == lpTimer))
	{
		return;
	}

	lpSystem = (__SYSTEM*)lpThis;
	//if(((__TIMER_OBJECT*)lpTimer)->dwTimerFlags != TIMER_FLAGS_ALWAYS)
	//	return;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpSystem->lpTimerQueue->DeleteFromQueue((__COMMON_OBJECT*)lpSystem->lpTimerQueue,
		lpTimer);
	lpTimerObject = (__TIMER_OBJECT*)
		lpSystem->lpTimerQueue->GetHeaderElement(
		(__COMMON_OBJECT*)lpSystem->lpTimerQueue,
		&dwPriority);
	if(NULL == lpTimerObject)    //There is not any timer object to be processed.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		goto __DESTROY_TIMER;
	}

	//
	//The following code updates the tick counter that timer object should be processed.
	//
	dwPriority = MAX_DWORD_VALUE - dwPriority;
	if(dwPriority > lpSystem->dwNextTimerTick)
		lpSystem->dwNextTimerTick = dwPriority;
	dwPriority = MAX_DWORD_VALUE - dwPriority;
	lpSystem->lpTimerQueue->InsertIntoQueue(
		(__COMMON_OBJECT*)lpSystem->lpTimerQueue,
		(__COMMON_OBJECT*)lpTimerObject,
		dwPriority);    //Insert into timer object queue.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

__DESTROY_TIMER:  //Destroy the timer object.
	ObjectManager.DestroyObject(&ObjectManager,
		lpTimer);

	return;
}
Beispiel #16
0
static __COMMON_OBJECT* ConnectInterrupt(__COMMON_OBJECT*     lpThis,
							 __INTERRUPT_HANDLER  lpInterruptHandler,
							 LPVOID               lpHandlerParam,
							 UCHAR                ucVector,
							 UCHAR                ucReserved1,
							 UCHAR                ucReserved2,
							 UCHAR                ucInterruptMode,
							 BOOL                 bIfShared,
							 DWORD                dwCPUMask)
{
	__INTERRUPT_OBJECT*      lpInterrupt          = NULL;
	__INTERRUPT_OBJECT*      lpObjectRoot         = NULL;
	__SYSTEM*                lpSystem             = &System;  //Had as a BUG here!!!
	DWORD                    dwFlags              = 0;

	if((NULL == lpThis) || (NULL == lpInterruptHandler))    //Parameters valid check.
	{
		return NULL;
	}

	if(ucVector >= MAX_INTERRUPT_VECTOR)                    //Impossible!!!
	{
		return NULL;
	}

	lpInterrupt = (__INTERRUPT_OBJECT*)
		ObjectManager.CreateObject(&ObjectManager,NULL,OBJECT_TYPE_INTERRUPT);
	if(NULL == lpInterrupt)    //Failed to create interrupt object.
	{
		return FALSE;
	}
	if(!lpInterrupt->Initialize((__COMMON_OBJECT*)lpInterrupt))  //Failed to initialize.
	{
		return FALSE;
	}

	lpInterrupt->lpPrevInterruptObject = NULL;
	lpInterrupt->lpNextInterruptObject = NULL;
	lpInterrupt->InterruptHandler      = lpInterruptHandler;
	lpInterrupt->lpHandlerParam        = lpHandlerParam;
	lpInterrupt->ucVector              = ucVector;

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpObjectRoot = lpSystem->lpInterruptVector[ucVector];
	if(NULL == lpObjectRoot)    //If this is the first interrupt object of the vector.
	{
		System.lpInterruptVector[ucVector]  = lpInterrupt;
	}
	else
	{
		lpInterrupt->lpNextInterruptObject  = lpObjectRoot;
		lpObjectRoot->lpPrevInterruptObject = lpInterrupt;
		System.lpInterruptVector[ucVector]  = lpInterrupt;
	}
	//LEAVE_CRITICAL_SECTION();
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	return (__COMMON_OBJECT*)lpInterrupt;
}
Beispiel #17
0
//
//Implementation of WaitForThisObjectEx routine.
//This routine is a time out waiting routine,caller can give a time value
//to indicate how long want to wait,once exceed the time value,waiting operation
//will return,even in case of the resource is not released.
//If the time value is zero,then this routine will check the current status of
//mutex object,if free,then occupy the object and return RESOURCE,else return
//TIMEOUT,and a re-schedule is triggered.
//
static DWORD WaitForMutexObjectEx(__COMMON_OBJECT* lpThis,DWORD dwMillionSecond)
{
    __MUTEX*                      lpMutex        = (__MUTEX*)lpThis;
    __KERNEL_THREAD_OBJECT*       lpKernelThread = NULL;
    DWORD                         dwFlags;
    DWORD                         dwResult       = OBJECT_WAIT_FAILED;

    if(NULL == lpMutex)
    {
        return OBJECT_WAIT_FAILED;
    }

    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    if(MUTEX_STATUS_FREE == lpMutex->dwMutexStatus)  //Free now.
    {
        lpMutex->dwMutexStatus = MUTEX_STATUS_OCCUPIED;
        lpMutex->dwWaitingNum ++;
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
        //KernelThreadManager.ScheduleFromProc(NULL);  //Re-schedule here.
        return OBJECT_WAIT_RESOURCE;
    }
    else  //The mutex is not free now.
    {
        if(0 == dwMillionSecond)
        {
            __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
            KernelThreadManager.ScheduleFromProc(NULL); //Re-schedule here.
            return OBJECT_WAIT_TIMEOUT;
        }
        lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
        lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
        lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_WAITING;
        //Waiting on mutex's waiting queue.
        lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
        lpMutex->dwWaitingNum ++;  //Added in 2015-04-06.
        lpMutex->lpWaitingQueue->InsertIntoQueue(
            (__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
            (__COMMON_OBJECT*)lpKernelThread,
            0);
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);

        return TimeOutWaiting((__COMMON_OBJECT*)lpMutex,
                              lpMutex->lpWaitingQueue,lpKernelThread,dwMillionSecond,MutexTimeOutCallback);
    }
}
Beispiel #18
0
//
//InsertIntoList routine,this routine inserts a virtual area descriptor object into
//virtual area list.
//
static VOID InsertIntoList(__COMMON_OBJECT* lpThis,__VIRTUAL_AREA_DESCRIPTOR* lpVad)
{
	__VIRTUAL_MEMORY_MANAGER*       lpMemMgr         =	(__VIRTUAL_MEMORY_MANAGER*)lpThis;
	DWORD                           dwFlags          = 0;
	__VIRTUAL_AREA_DESCRIPTOR*      lpFirst          =  NULL;
	__VIRTUAL_AREA_DESCRIPTOR*      lpSecond         =  NULL;

	if((NULL == lpThis) || (NULL == lpVad)) //Invalidate parameters.
		return;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpFirst  = lpMemMgr->lpListHdr;
	if(NULL == lpFirst)    //There is not any element in the list.
	{
		lpMemMgr->lpListHdr        = lpVad;
		lpMemMgr->dwVirtualAreaNum ++;          //Increment the reference counter.
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return;
	}
	lpSecond = lpFirst;
	while(lpFirst)
	{
		if((DWORD)lpFirst->lpStartAddr > (DWORD)lpVad->lpStartAddr)    //Find the proper position.
			break;
		lpSecond = lpFirst;
		lpFirst  = lpFirst->lpNext;
	}
	if(lpSecond == lpFirst)  //Should be the first element in the list.
	{
		lpVad->lpNext       = lpMemMgr->lpListHdr;
		lpMemMgr->lpListHdr = lpVad;
		lpMemMgr->dwVirtualAreaNum ++;
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return;
	}
	else    //Should not be the first element.
	{
		lpVad->lpNext    = lpSecond->lpNext;
		lpSecond->lpNext = lpVad;
	}
	lpMemMgr->dwVirtualAreaNum ++;    //Increment the virtual area's total number.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
}
Beispiel #19
0
//
//The implementation of WaitForKernelThreadObject,because this routine calls ScheduleFromproc,
//so we implement it here(After the implementation of ScheduleFromProc).
//The routine does the following:
// 1. Check the current status of the kernel thread object;
// 2. If the current status is not KERNEL_THREAD_STATUS_TERMINAL,then block the
//    current kernel thread(who want to wait),put it into the object's waiting queue;
// 3. Call ScheduleFromProc to fetch next kernel thread whose status is READY to run.
//
DWORD WaitForKernelThreadObject(__COMMON_OBJECT* lpThis)
{
	__KERNEL_THREAD_OBJECT*           lpKernelThread = NULL;
	__KERNEL_THREAD_OBJECT*           lpCurrent      = NULL;
	__PRIORITY_QUEUE*                 lpWaitingQueue = NULL;
	DWORD                             dwFlags        = 0;
	
	if(NULL == lpThis)    //Parameter check.
	{
		return 0;
	}

	lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThis;

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	if(KERNEL_THREAD_STATUS_TERMINAL == lpKernelThread->dwThreadStatus)  //If the object's
		                                                                 //status is TERMINAL,
																		 //the wait operation
																		 //will secussfully.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return OBJECT_WAIT_RESOURCE;
	}

	//
	//If the waited object's status is not TERMINAL,then the waiting operation will
	//not secussful,the current kernel thread who want to wait will be blocked.
	//
	lpWaitingQueue = lpKernelThread->lpWaitingQueue;
	lpCurrent = KernelThreadManager.lpCurrentKernelThread;
	lpCurrent->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;

	lpWaitingQueue->InsertIntoQueue((__COMMON_OBJECT*)lpWaitingQueue,
		(__COMMON_OBJECT*)lpCurrent,
		0);    //Insert into the current kernel thread into waiting queue.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	KernelThreadManager.ScheduleFromProc(NULL);

	return 0;
}
Beispiel #20
0
//
//The following routine prints out bug's information.
//
VOID __BUG(LPSTR lpszFileName,DWORD dwLineNum)
{
	DWORD   dwFlags;
	
	//Print out fatal error information.
	_hx_printf("\r\nBUG oencountered.\r\nFile name: %s\r\nCode Lines:%d",lpszFileName,dwLineNum);

	//Enter infinite loop.
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	while(TRUE);
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
}
Beispiel #21
0
//
//The implementation of ReleaseMutex.
//
static
DWORD kReleaseMutex(__COMMON_OBJECT* lpThis)
{
    __KERNEL_THREAD_OBJECT*     lpKernelThread   = NULL;
    __MUTEX*                    lpMutex          = NULL;
    DWORD                       dwPreviousStatus = 0;
    DWORD                       dwFlags          = 0;

    if(NULL == lpThis)    //Parameter check.
        return 0;

    lpMutex = (__MUTEX*)lpThis;

    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    if(lpMutex->dwWaitingNum > 0)    //If there are other kernel threads waiting for this object.
    {
        lpMutex->dwWaitingNum --;    //Decrement the counter.
    }
    if(0 == lpMutex->dwWaitingNum)   //There is no kernel thread waiting for the object.
    {
        dwPreviousStatus = lpMutex->dwMutexStatus;
        lpMutex->dwMutexStatus = MUTEX_STATUS_FREE;  //Set to free.
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
        return 0;
    }
    lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpMutex->lpWaitingQueue->GetHeaderElement(
                         (__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
                         0);  //Get one waiting kernel thread to run.
    lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
    lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
    lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_RESOURCE;
    KernelThreadManager.AddReadyKernelThread(
        (__COMMON_OBJECT*)&KernelThreadManager,
        lpKernelThread);  //Put the kernel thread to ready queue.
    __LEAVE_CRITICAL_SECTION(NULL,dwFlags);

    KernelThreadManager.ScheduleFromProc(NULL);  //Re-schedule kernel thread.
    return dwPreviousStatus;
}
Beispiel #22
0
//
//The implementation of CommQueueFull.
//This routine checks the current element number of current queue.
//If it equals the queue number,then returns TRUE,else,
//returns FALSE.
//
static BOOL    CommQueueFull(__COMMON_OBJECT* lpThis)
{
	__COMMON_QUEUE*       lpComQueue = (__COMMON_QUEUE*)lpThis;
	DWORD                 dwFlags    = 0L;
	BOOL                  bResult    = FALSE;
	if(NULL == lpThis)
		return FALSE;

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	bResult = (lpComQueue->dwCurrentLen == lpComQueue->dwQueueLen);
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return bResult;
}
Beispiel #23
0
static void Logk(__DEBUG_MANAGER *pThis, char *tag, char *msg)
{
	__DEBUG_MANAGER			*pDebugManager		= pThis;
	__LOG_MESSAGE			*pMsg				= NULL;
	__KERNEL_THREAD_OBJECT	*lpCurrentThread	= NULL;

	int						Result				= -1;
	int						dwFlags				= 0;

	pMsg = (__LOG_MESSAGE *)KMemAlloc(sizeof(__LOG_MESSAGE),KMEM_SIZE_TYPE_ANY);

	//
	//Set to default now
	//
	pMsg->code = 0;
	pMsg->format = 0;
	pMsg->len = 0;
	pMsg->pid = 0;
	pMsg->time = 0;

	//
	//*****XXX*******
	// FIXME
	//
	__ENTER_CRITICAL_SECTION(NULL, dwFlags);
	lpCurrentThread = KernelThreadManager.lpCurrentKernelThread;
	StrCpy(lpCurrentThread->KernelThreadName,pMsg->name);
	pMsg->tid = lpCurrentThread->dwThreadID;
	__LEAVE_CRITICAL_SECTION(NULL, dwFlags);

	StrCpy(msg, pMsg->msg);
	StrCpy(tag, pMsg->tag);

	//
	//Get the authority to visit the bufferqueue
	//

	Result = pDebugManager->pMutexForKRNLBufferQueue->WaitForThisObject((__COMMON_OBJECT*)DebugManager.pMutexForKRNLBufferQueue);
	if (Result == OBJECT_WAIT_RESOURCE)
	{
		pDebugManager->pKRNLBufferQueue->Enqueue(
			pDebugManager->pKRNLBufferQueue,
			pMsg);
		pDebugManager->pMutexForKRNLBufferQueue->ReleaseMutex((__COMMON_OBJECT*)DebugManager.pMutexForKRNLBufferQueue);
	}

	KMemFree(pMsg, KMEM_SIZE_TYPE_ANY, 0);

	return;
}
Beispiel #24
0
//Implementation of DeviceClose routine.
static DWORD FatDeviceClose(__COMMON_OBJECT* lpDrv,
                            __COMMON_OBJECT* lpDev,
                            __DRCB* lpDrcb)
{
    __DEVICE_OBJECT*        pDeviceObject    = (__DEVICE_OBJECT*)lpDev;
    __FAT32_FS*             pFat32Fs         = NULL;
    __FAT32_FILE*           pFileObject      = NULL;
    DWORD                   _dwFlags;

    if((NULL == pDeviceObject) || (NULL == lpDrcb))
    {
        return 0;
    }
    pFileObject = (__FAT32_FILE*)pDeviceObject->lpDevExtension;
    pFat32Fs    = pFileObject->pFileSystem;
    //Delete the fat32 file object from file system.
    __ENTER_CRITICAL_SECTION(NULL, _dwFlags);
    if((pFileObject->pPrev == NULL) && (pFileObject->pNext == NULL))
    {
        pFat32Fs->pFileList = NULL;
    }
    else
    {
        if(pFileObject->pPrev == NULL)  //This is the first object in file list.
        {
            pFat32Fs->pFileList = pFileObject->pNext;
            pFileObject->pNext->pPrev = NULL;
        }
        else  //Not the fist file in list.
        {
            if(NULL == pFileObject->pNext)  //This is the last one in list.
            {
                pFileObject->pPrev->pNext = NULL;
            }
            else  //Neither is the first nor is the last one in list.
            {
                pFileObject->pPrev->pNext = pFileObject->pNext;
                pFileObject->pNext->pPrev = pFileObject->pPrev;
            }
        }
    }
    __LEAVE_CRITICAL_SECTION(NULL, _dwFlags);
    //Release the file object.
    RELEASE_OBJECT(pFileObject);

    //Destroy file device object.
    IOManager.DestroyDevice((__COMMON_OBJECT*)&IOManager,pDeviceObject);

    return 0;
}
Beispiel #25
0
//
//The implementation of SetQueueLength.
//This routine sets the queue's length to dwNewLen,and returns the old
//value of queue length.
//
static DWORD   SetQueueLength(__COMMON_OBJECT* lpThis,DWORD dwNewLen)
{
	__COMMON_QUEUE*          lpComQueue = (__COMMON_QUEUE*)lpThis;
	DWORD                    dwFlags    = 0L;
	DWORD                    dwOldLen   = 0L;

	if(NULL == lpThis)
		return 0L;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	dwOldLen = lpComQueue->dwQueueLen;
	lpComQueue->dwQueueLen = dwNewLen;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return dwOldLen;
}
Beispiel #26
0
static DWORD WaitForMutexObject(__COMMON_OBJECT* lpThis)
{
    __KERNEL_THREAD_OBJECT*        lpKernelThread   = NULL;
    __MUTEX*                       lpMutex          = (__MUTEX*)lpThis;
    DWORD                          dwFlags          = 0;

    if(NULL == lpMutex)    //Parameter check.
    {
        return 0;
    }

    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    if(MUTEX_STATUS_FREE == lpMutex->dwMutexStatus)    //If the current mutex is free.
    {
        lpMutex->dwMutexStatus = MUTEX_STATUS_OCCUPIED;  //Modify the current status.
        lpMutex->dwWaitingNum  ++;    //Increment the counter.
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
        return OBJECT_WAIT_RESOURCE;  //The current kernel thread successfully occupy
        //the mutex.
    }
    else    //The status of the mutex is occupied.
    {
        lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
        lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
        lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_WAITING;
        lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
        lpMutex->dwWaitingNum          ++;    //Increment the waiting number.
        lpMutex->lpWaitingQueue->InsertIntoQueue(
            (__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
            (__COMMON_OBJECT*)lpKernelThread,
            0);
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);  //Leave critical section here is safety.
        //Reschedule all kernel thread(s).
        KernelThreadManager.ScheduleFromProc(NULL);
    }
    return OBJECT_WAIT_RESOURCE;
}
Beispiel #27
0
//Timer handler routine for all synchronous object.
static DWORD WaitingTimerHandler(LPVOID lpData)
{
	struct __TIMER_HANDLER_PARAM*   lpHandlerParam = (struct __TIMER_HANDLER_PARAM*)lpData;
	DWORD                    dwFlags;

	if(NULL == lpHandlerParam)
	{
		BUG();
		return 0L;
	}

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);  //Acquire kernel thread object's spinlock.
	switch(lpHandlerParam->lpKernelThread->dwWaitingStatus & OBJECT_WAIT_MASK)
	{
		case OBJECT_WAIT_RESOURCE:
		case OBJECT_WAIT_DELETED:
			break;
		case OBJECT_WAIT_WAITING:
			lpHandlerParam->lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
			lpHandlerParam->lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_TIMEOUT;
			//Delete the lpKernelThread from waiting queue.
			lpHandlerParam->lpWaitingQueue->DeleteFromQueue(
				(struct __COMMON_OBJECT*)lpHandlerParam->lpWaitingQueue,
				(struct __COMMON_OBJECT*)lpHandlerParam->lpKernelThread);
			//Add this kernel thread to ready queue.
			lpHandlerParam->lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
			KernelThreadManager.AddReadyKernelThread((struct __COMMON_OBJECT*)&KernelThreadManager,
				lpHandlerParam->lpKernelThread);
			break;
		default:
			__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
			BUG();
			return 0L;
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return 0L;
}
Beispiel #28
0
VOID EventUninitialize(__COMMON_OBJECT* lpThis)
{
    __EVENT*                 lpEvent          = NULL;
    __PRIORITY_QUEUE*        lpPriorityQueue  = NULL;
    __KERNEL_THREAD_OBJECT*  lpKernelThread   = NULL;
    DWORD                    dwFlags;

    if(NULL == lpThis)
    {
        BUG();
        return;
    }

    lpEvent = (__EVENT*)lpThis;

    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    lpPriorityQueue = lpEvent->lpWaitingQueue;
    //if(EVENT_STATUS_FREE != EVENT_STATUS_FREE)
    if (EVENT_STATUS_FREE != lpEvent->dwEventStatus)
    {
        //Should wake up all kernel thread(s) who waiting for this object.
        lpKernelThread = (__KERNEL_THREAD_OBJECT*)
                         lpPriorityQueue->GetHeaderElement(
                             (__COMMON_OBJECT*)lpPriorityQueue,
                             NULL);
        while(lpKernelThread)
        {
            lpKernelThread->dwThreadStatus   = KERNEL_THREAD_STATUS_READY;
            lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
            lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_DELETED;
            KernelThreadManager.AddReadyKernelThread((__COMMON_OBJECT*)&KernelThreadManager,
                    lpKernelThread);
            lpKernelThread = (__KERNEL_THREAD_OBJECT*)
                             lpPriorityQueue->GetHeaderElement(
                                 (__COMMON_OBJECT*)lpPriorityQueue,
                                 NULL);
        }
    }
    __LEAVE_CRITICAL_SECTION(NULL,dwFlags);

    //Clear the kernel object's signature.
    lpEvent->dwObjectSignature = 0;

    ObjectManager.DestroyObject(&ObjectManager,
                                (__COMMON_OBJECT*)lpPriorityQueue);          //*******CAUTION!!!************
    return;
}
Beispiel #29
0
//
//The implementation of SetEvent.
//This routine do the following:
// 1. Saves the previous status into a local variable;
// 2. Sets the current status of the event to EVENT_STATUS_FREE;
// 3. Wakes up all kernel thread(s) in it's waiting queue.
// 4. Returns the previous status.
//
//static
DWORD kSetEvent(__COMMON_OBJECT* lpThis)
{
    DWORD                     dwPreviousStatus     = EVENT_STATUS_OCCUPIED;
    __EVENT*                  lpEvent              = NULL;
    __KERNEL_THREAD_OBJECT*   lpKernelThread       = NULL;
    DWORD                     dwFlags              = 0;

    if(NULL == lpThis)
    {
        return dwPreviousStatus;
    }

    lpEvent = (__EVENT*)lpThis;

    __ENTER_CRITICAL_SECTION(NULL,dwFlags);
    dwPreviousStatus = lpEvent->dwEventStatus;
    lpEvent->dwEventStatus = EVENT_STATUS_FREE;    //Set the current status to free.

    //Wake up all kernel thread(s) waiting for this event.
    lpKernelThread = (__KERNEL_THREAD_OBJECT*)
                     lpEvent->lpWaitingQueue->GetHeaderElement(
                         (__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
                         NULL);
    while(lpKernelThread)                         //Remove all kernel thread(s) from
        //waiting queue.
    {
        lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
        //Set waiting result bit.
        lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
        lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_RESOURCE;
        KernelThreadManager.AddReadyKernelThread(
            (__COMMON_OBJECT*)&KernelThreadManager,
            lpKernelThread);  //Add to ready queue.
        lpKernelThread = (__KERNEL_THREAD_OBJECT*)
                         lpEvent->lpWaitingQueue->GetHeaderElement(
                             (__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
                             NULL);
    }
    __LEAVE_CRITICAL_SECTION(NULL,dwFlags);

    if(IN_KERNELTHREAD())  //Current context is in process.
    {
        KernelThreadManager.ScheduleFromProc(NULL);  //Re-schedule.
    }
    return dwPreviousStatus;
}
Beispiel #30
0
//
//KernelThreadWrapper routine.
//The routine is all kernel thread's entry porint.
//The routine does the following:
// 1. Calles the kernel thread's start routine;
// 2. When the start routine is over,put the kernel thread object into terminal queue;
// 3. Wakeup all kernel thread(s) waiting for this kernel thread object.
// 4. Reschedule all kernel thread(s).
//This routine will never return.
//
VOID KernelThreadWrapper(__COMMON_OBJECT* lpKThread)
{
	__KERNEL_THREAD_OBJECT*        lpKernelThread      = NULL;
	__KERNEL_THREAD_OBJECT*        lpWaitingThread     = NULL;
	__PRIORITY_QUEUE*              lpWaitingQueue      = NULL;
	DWORD                          dwRetValue          = 0;
	DWORD                          dwFlags             = 0;

	lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpKThread;

	//Execute user defined kernel thread function.
	dwRetValue = lpKernelThread->KernelThreadRoutine(lpKernelThread->lpRoutineParam);

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpKernelThread->dwReturnValue    = dwRetValue;      //Set the return value of this thread.
	lpKernelThread->dwThreadStatus   = KERNEL_THREAD_STATUS_TERMINAL;  //Change the status.
	//Insert the current kernel thread object into TERMINAL queue.
	KernelThreadManager.lpTerminalQueue->InsertIntoQueue((__COMMON_OBJECT*)KernelThreadManager.lpTerminalQueue,
		(__COMMON_OBJECT*)lpKernelThread,
		0);
	//
	//The following code wakeup all kernel thread(s) who waiting for this kernel thread 
	//object.
	//
	lpWaitingQueue  = lpKernelThread->lpWaitingQueue;
	lpWaitingThread = (__KERNEL_THREAD_OBJECT*)lpWaitingQueue->GetHeaderElement(
		(__COMMON_OBJECT*)lpWaitingQueue,
		NULL);
	while(lpWaitingThread)
	{
		lpWaitingThread->dwThreadStatus   = KERNEL_THREAD_STATUS_READY;
		lpWaitingThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
		lpWaitingThread->dwWaitingStatus |= OBJECT_WAIT_RESOURCE;
		KernelThreadManager.AddReadyKernelThread(
			(__COMMON_OBJECT*)&KernelThreadManager,
			lpWaitingThread);  //Add to ready queue.
		lpWaitingThread = (__KERNEL_THREAD_OBJECT*)lpWaitingQueue->GetHeaderElement(
			(__COMMON_OBJECT*)lpWaitingQueue,
			NULL);
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	KernelThreadManager.ScheduleFromProc(NULL);  //Re-schedule kernel thread.
	return;        //***** CAUTION! ***** : This instruction will never reach.
}