📄 resmance.cpp
字号:
/***************************************************************************
* Name : resman.cpp
* Title : WinCE resource manager
* Author(s) : Imagination Technologies
* Created : 19th June 2003
*
* Copyright : 2003 by Imagination Technologies. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8,
* : HomePark Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Description : Handles the WinCE specific side of resource management
*
* Platform : WinCE
*
* Modifications:-
* $Log: resmanCE.cpp $
*
****************************************************************************/
#include "precomp.h"
extern "C"
{
#include "drvescape.h"
}
/*****************************************************************************
FUNCTION : AmendProcessesInList
PURPOSE : Add or delete items for the process monitor handle list
PARAMETERS : RESMAN_MON_THREAD_PARAMS *pMonParams
HANDLE hProcess Handle to add/delete
IMG_BOOL bAdd True - add, False - delete
RETURNS : True - successfully added or deleted handle
*****************************************************************************/
IMG_BOOL AmendProcessesInList(PRESMAN_MON_THREAD_PARAMS pMonParams, HANDLE hProcess, IMG_BOOL bAdd)
{
IMG_UINT32 ProcessInxInList = (IMG_UINT32) -1;
IMG_UINT32 ScanIndex;
/* Attempt to find process handle in list, remember to skip first element */
for(ScanIndex = 1; ScanIndex < MAXIMUM_WAIT_OBJECTS && pMonParams->hProcesses[ScanIndex]; ScanIndex++)
{
if(pMonParams->hProcesses[ScanIndex] == hProcess)
{
ProcessInxInList = ScanIndex;
break;
}
}
if(bAdd)
{
/******************************************************** Add handle */
if(ProcessInxInList != (IMG_UINT32) -1) return(IMG_FALSE); /* Handle already in list */
if(ScanIndex == MAXIMUM_WAIT_OBJECTS) return(IMG_FALSE); /* List Full */
/* Add to list, bump count */
pMonParams->hProcesses[ScanIndex] = hProcess;
pMonParams->ui32ProcessCnt++;
}
else
{
/***************************************************** Delete handle */
if(ProcessInxInList == (IMG_UINT32) -1) return(IMG_FALSE); /* Handle not in list */
/* Remove item from list, ripple up list, ensure last item zero-ed */
for(; ProcessInxInList < (MAXIMUM_WAIT_OBJECTS-1); ProcessInxInList++)
{
pMonParams->hProcesses[ProcessInxInList] = pMonParams->hProcesses[ProcessInxInList+1];
}
pMonParams->hProcesses[ProcessInxInList] = 0;
pMonParams->ui32ProcessCnt--;
}
return(IMG_TRUE);
}
/*****************************************************************************
FUNCTION : MonitorProcesses
PURPOSE : Monitor processoes
PARAMETERS : RESMAN_MON_THREAD_PARAMS *
RETURNS :
*****************************************************************************/
static ULONG MonitorThreadProc(PVOID pvParameter)
{
PRESMAN_MON_THREAD_PARAMS pMonParams = (PRESMAN_MON_THREAD_PARAMS) pvParameter;
DWORD dwWaitRtn;
IMG_BOOL bTerminateRequested = IMG_FALSE;
while(!bTerminateRequested)
{
/* Wait for some thing to happen */
dwWaitRtn = WaitForMultipleObjects(pMonParams->ui32ProcessCnt,
pMonParams->hProcesses,
FALSE, INFINITE);
if(dwWaitRtn == WAIT_OBJECT_0)
{
/********************************************* Recieved command */
/* WARNING this process loop is replicated in ResManSendCmd below */
switch(pMonParams->eCommand)
{
case PMC_TERMINATE_THREAD:
{
pMonParams->bCmdSuccessful = IMG_TRUE;
bTerminateRequested = IMG_TRUE;
break;
}
case PMC_REGISTER_PROCESS:
{
pMonParams->bCmdSuccessful = AmendProcessesInList(pMonParams, pMonParams->hCmdParam, IMG_TRUE);
break;
}
case PMC_UNREGISTER_PROCESS:
{
pMonParams->bCmdSuccessful = AmendProcessesInList(pMonParams, pMonParams->hCmdParam, IMG_FALSE);
break;
}
default:
{
pMonParams->bCmdSuccessful = IMG_FALSE;
break;
}
}
/* Signal command completion */
if(pMonParams->eCommand != PMC_CMDRESET)
{
SetEvent(pMonParams->hCommandCompletion);
}
}
else
{
/******************************************** Process terminated */
HANDLE hTerminatedProcess = pMonParams->hProcesses[dwWaitRtn];
/* Remove handle for list */
AmendProcessesInList(pMonParams, hTerminatedProcess, IMG_FALSE);
/* Send driver escape to signal termination, this will ensure
that the services are not re-entered by another thread */
DRVESC_RESMAN_THREAD_TERMINATED_PARAMS sResManThreadTerminated;
sResManThreadTerminated.hProcess = hTerminatedProcess;
ExtEscape(GetWindowDC(NULL), DRVESC_RESMAN_THREAD_TERMINATED, 0, NULL,
sizeof(sResManThreadTerminated), (LPSTR)&sResManThreadTerminated);
}
}
return(0);
}
/*****************************************************************************
FUNCTION : ResManSendCommand
PURPOSE : Send a command to the resman thread
PARAMETERS :
RETURNS :
*****************************************************************************/
IMG_BOOL MBX::ResManSendCommand(PMC eCommand, HANDLE hCmdParam)
{
if(m_sMonitorThread.hThread == NULL) return(IMG_FALSE);
/* Send command */
m_sMonitorThread.eCommand = eCommand;
m_sMonitorThread.hCmdParam = hCmdParam;
m_sMonitorThread.bCmdSuccessful = IMG_FALSE;
SetEvent(m_sMonitorThread.hProcesses[0]);
/* Wait for ACK */
if(WaitForSingleObject(m_sMonitorThread.hCommandCompletion, 1000) == WAIT_TIMEOUT)
{
/* Wait timeout will happen if the monitor thread is attempting to call the
driver, via a driver escape, and we are waiting in the driver. Handle as
a special case */
ResetEvent(m_sMonitorThread.hProcesses[0]);
m_sMonitorThread.eCommand = PMC_CMDRESET;
switch(eCommand)
{
case PMC_REGISTER_PROCESS:
{
m_sMonitorThread.bCmdSuccessful = AmendProcessesInList(&m_sMonitorThread, hCmdParam, IMG_TRUE);
m_sMonitorThread.bCmdSuccessful = IMG_TRUE;
break;
}
case PMC_UNREGISTER_PROCESS:
{
m_sMonitorThread.bCmdSuccessful = AmendProcessesInList(&m_sMonitorThread, hCmdParam, IMG_FALSE);
m_sMonitorThread.bCmdSuccessful = IMG_TRUE;
break;
}
}
}
return(m_sMonitorThread.bCmdSuccessful);
}
/*****************************************************************************/
/****************************** External functions ***************************/
/*****************************************************************************/
/*****************************************************************************
FUNCTION : StartResManThread
PURPOSE : Start the resource manager monitoring thread
PARAMETERS :
RETURNS :
*****************************************************************************/
DWORD MBX::ResManStartThread()
{
memset(&m_sMonitorThread, 0, sizeof(m_sMonitorThread));
/* Create Command event */
if((m_sMonitorThread.hProcesses[0] = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
{
return(ERROR_INVALID_PARAMETER);
}
m_sMonitorThread.ui32ProcessCnt++;
/* Create Command completion event */
if((m_sMonitorThread.hCommandCompletion = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
{
CloseHandle(m_sMonitorThread.hProcesses[0]);
return(ERROR_INVALID_PARAMETER);
}
/* Create and start thread */
if((m_sMonitorThread.hThread = CreateThread(NULL, 0, MonitorThreadProc, &m_sMonitorThread, 0, NULL)) == NULL)
{
CloseHandle(m_sMonitorThread.hProcesses[0]);
return(ERROR_INVALID_PARAMETER);
}
return(ERROR_SUCCESS);
}
/*****************************************************************************
FUNCTION : StopResManThread
PURPOSE : Stop the resource manager monitoring thread
PARAMETERS :
RETURNS :
*****************************************************************************/
DWORD MBX::ResManStopThread()
{
ResManSendCommand(PMC_TERMINATE_THREAD, NULL);
WaitForSingleObject(m_sMonitorThread.hThread, 1000);
for(int i=0; i < MAXIMUM_WAIT_OBJECTS; i++)
{
if(m_sMonitorThread.hProcesses[i])
{
CloseHandle(m_sMonitorThread.hProcesses[i]);
}
}
CloseHandle(m_sMonitorThread.hCommandCompletion);
CloseHandle(m_sMonitorThread.hThread);
return(ERROR_SUCCESS);
}
/*****************************************************************************
FUNCTION : TermintateProcessRequest
PURPOSE : Handle terminate process requests sent for the process monitoring
thread.
PARAMETERS :
RETURNS :
*****************************************************************************/
DWORD MBX::ResManTermintateProcessRequest(DRVESC_RESMAN_THREAD_TERMINATED_PARAMS *psResManThreadTerminated)
{
PVRSRVResManConnect((IMG_UINT32)psResManThreadTerminated->hProcess, IMG_FALSE);
CloseHandle(psResManThreadTerminated->hProcess);
return(ERROR_SUCCESS);
}
/*****************************************************************************
FUNCTION : ResManConnectProcess
PURPOSE : Handle terminate process requests sent for the process monitoring
thread.
PARAMETERS :
RETURNS :
*****************************************************************************/
DWORD MBX::ResManConnectProcess()
{
HANDLE hProcess = GetOwnerProcess();
if(ResManSendCommand(PMC_REGISTER_PROCESS, hProcess))
{
PVRSRVResManConnect((IMG_UINT32)hProcess, IMG_TRUE);
}
return(ERROR_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -