Example #1
0
void setmoduleunloaded(void* handle) {
	CLinkNode<byte>* p = s_plugins.first();
	while (p) {
		if (p->data() == (byte*)handle) {
			s_plugins.del(p);
			return;
		}
		p = p->next();
	}
}
Example #2
0
//-----------------------------------------------------------------------------
// Name: FreeApiInfo
// Object: Free memory and events associated to pAPIInfo
// Parameters :
//          in : API_INFO* pAPIInfo : pointer to APIInfo to free
// Return : 
//-----------------------------------------------------------------------------
BOOL FreeApiInfo(API_INFO* pAPIInfo)
{
    FreeOptionalParametersMemory(pAPIInfo);

    // free allocated memory for string
    if (pAPIInfo->szAPIName)
    {
        HeapFree(ApiOverrideHeap, 0, pAPIInfo->szAPIName);
        pAPIInfo->szAPIName=NULL;
    }

    if (pAPIInfo->szModuleName)
    {
        HeapFree(ApiOverrideHeap, 0, pAPIInfo->szModuleName);
        pAPIInfo->szModuleName=NULL;
    }

    if (pAPIInfo->evtEndOfHook)
    {
        CloseHandle(pAPIInfo->evtEndOfHook);
        pAPIInfo->evtEndOfHook=NULL;
    }

    if (pAPIInfo->PostApiCallChain)
    {
        CLinkList* pTmp;
        // delete Call Chain
        // assign to null before destroying content (better for multi threading)
        pTmp=pAPIInfo->PostApiCallChain;
        pAPIInfo->PostApiCallChain=NULL;
        pTmp->Lock();
        delete pTmp;
    }

    if (pAPIInfo->PreApiCallChain)
    {
        CLinkList* pTmp;
        // delete Call Chain
        // assign to null before destroying content (better for multi threading)
        pTmp=pAPIInfo->PreApiCallChain;
        pAPIInfo->PreApiCallChain=NULL;
        pTmp->Lock();
        delete pTmp;
    }


    return TRUE;
}
Example #3
0
int ismoduleloaded(void* handle) {
	CLinkNode<byte>* p = s_plugins.first();
	while (p) {
		if (p->data() == (byte*)handle)
			return 1;
		p = p->next();
	}
	return 0;
}
Example #4
0
//------------------------------------------------------------------------------
int main( int argn, char *argv[] )
{
	if ( argn != 3 )
	{
		return usage();
	}

	Cstr buffer;
	if ( !buffer.fileToBuffer( argv[1] ) )
	{
		printf( "Could not load [%s]\n", argv[1] );
		return usage();
	}

	CLinkList<ReadHex::Chunk> chunklist;
	ReadHex::parse( chunklist, buffer.c_str(), buffer.size() );

	ReadHex::Chunk *chunk = chunklist.getFirst();

	buffer.format( "unsigned int g_origin = 0x%04X;\n\n"
				   "unsigned int g_size = 0x%04X;\n\n"
				   "const PROGMEM int g_data[]=\n{", chunk->addressBase, chunk->size/2 );

	for( unsigned int i=0; i<chunk->size; i += 2  )
	{
		if ( !(i%16) )
		{
			buffer.append( "\n\t" );
		}
		buffer.appendFormat( "0x%02X%02X, ", chunk->data[i+1], chunk->data[i] );
	}
			
	buffer.append( "\n};\n" );

	buffer.bufferToFile( argv[2] );

	printf( "[%s] -> [%s] complete\n", argv[1], argv[2] );

	return 0;
}
Example #5
0
int main() {
  
  //check to see if we're in interactive mode
  int tty = isatty(fileno(stdin));

  //prompt user
  if(tty) {
    cout << "Linked List (C++) -- Interactive Mode" << endl;
    cout << "Enter a list, one integer per line" << endl;
    cout << "Exit with ^D" << endl;
    cout << ">>>";
  }

  //setup list
  CLinkList *list = new CLinkList();

  //read user input
  while(!cin.eof()) {
    long in;
    cin >> in;
    list->addElement((atom_t) in);
    if(tty) { cout << ">>>"; }
  }
  
  cout << endl << endl;

  //display list
  CListIterator iter = list->getIterator();
  cout << "{ ";
  while(iter.hasMore()) {
    long temp = (long) iter.getElement();
    cout << temp << " ";
    ++iter;
  }
  cout << "}" << endl;

}
//The return value is the amount of treasure on board.
int CvSelectionGroupAI::AI_getYieldsLoaded(short* piYields)
{
	if (piYields != NULL)
	{
		for (int i = 0; i < NUM_YIELD_TYPES; ++i)
		{
			piYields[i] = 0;
		}
	}
	int iAmount = 0;

	CLinkList<IDInfo> unitList;
	buildCargoUnitList(unitList);

	CLLNode<IDInfo>* pUnitNode = unitList.head();
	while (pUnitNode != NULL)
	{
		CvUnit* pLoopUnit = ::getUnit(pUnitNode->m_data);
		pUnitNode = unitList.next(pUnitNode);

		if (pLoopUnit->getYieldStored() > 0)
		{
			if (pLoopUnit->getUnitInfo().isTreasure())
			{
				iAmount += pLoopUnit->getYieldStored();
			}
			else if (pLoopUnit->getYield() != NO_YIELD)
			{
				if (piYields != NULL)
				{
					piYields[pLoopUnit->getYield()] += pLoopUnit->getYieldStored();
				}
			}
		}
	}
	return iAmount;
}
Example #7
0
bool CClientFXDB::ReadFXGroups( bool bText, ILTStream* pFxFile, CLinkList<FX_GROUP *> &collGroupFx )
{
	// Read in the number of FX groups in this file
	uint32 dwNumGroups;

	if( bText )
	{
		ReadTextFile( pFxFile, "%s %lu", &dwNumGroups );
	}
	else
	{
		pFxFile->Read(&dwNumGroups, sizeof(uint32));
	}

	//allocate a working buffer that keys can read properties into
	static const uint32		knMaxKeyProps = 512;
	FX_PROP*				pPropBuffer = debug_newa(FX_PROP, knMaxKeyProps);

	if(!pPropBuffer)
		return false;

	for( uint32 i = 0; i < dwNumGroups; i ++ )
	{
		// Create a new group.
		FX_GROUP *pFxGroup = debug_new( FX_GROUP );

		if( !ReadFXGroup( bText, pFxFile, pFxGroup, pPropBuffer, knMaxKeyProps ))
		{
			debug_deletea(pPropBuffer);
			return false;
		}

		collGroupFx.AddTail(pFxGroup);
	}

	//free our working buffer
	debug_deletea(pPropBuffer);

	return true;
}
Example #8
0
//------------------------------------------------------------------------------
inline bool parse( CLinkList<Chunk>& chunklist, const char* data, const int size )
{
    if ( !data )
    {
        return false;
    }

    chunklist.clear();
    Chunk* chunk = 0;

    int pos = 0;
    char buf[5];

    while( pos < size )
    {
        for( ; data[pos] != ':' && pos < size; pos++ );
        if ( pos >= size )
        {
            printf( "':' unfound\n" );
            break;
        }
        pos++;

        if ( (size - pos) < 10 )
        {
            printf( "size - pos = %d\n", size - pos );
            break;
        }

        buf[0] = data[pos++];
        buf[1] = data[pos++];
        buf[2] = 0;
        int byteCount = strtol( buf, 0, 16 );

        buf[0] = data[pos++];
        buf[1] = data[pos++];
        buf[2] = data[pos++];
        buf[3] = data[pos++];
        buf[4] = 0;
        int offsetAddress = strtol( buf, 0, 16 );

        buf[0] = data[pos++];
        buf[1] = data[pos++];
        buf[2] = 0;
        int recordType = strtol( buf, 0, 16 );


        switch( recordType )
        {
        case 0:
        {
            if ( !chunk )
            {
                chunk = chunklist.add();
                chunk->addressBase = offsetAddress;
                memset( chunk->data, 0, sizeof(chunk->data) );
                chunk->size = 0;
            }

            buf[2] = 0;

            for( int i=0; i<byteCount; i++ )
            {
                if ( !(buf[0] = data[pos++]) || !(buf[1] = data[pos++]) )
                {
                    goto parse_fail;
                }

                unsigned int offset = (offsetAddress + i) - chunk->addressBase;
                if ( offset >= chunk->size )
                {
                    chunk->size = offset + 1;
                }
                chunk->data[offset] = (char)strtol( buf, 0, 16 );

//					printf( "[%d/%d/%d %02X]", i, byteCount, offset, (unsigned char)chunk->data[offset] );
            }

//				printf( "\n" );

            break;
        }

        case 1:
        {
            return true; // reached EOF, only legal exit point
        }

        case 2:
        case 3:
        case 4:
        case 5:
        {
            printf( "unhandled record type [%d]\n", recordType );
            break;
        }

        default:
        {
            printf( "unrecognized record type [%d]\n", recordType );
            goto parse_fail;
        }
        }
    }

parse_fail:
    chunklist.clear();
    return false;
}
Example #9
0
void setmoduleloaded(void* handle) {
	if (!handle || ismoduleloaded(handle))
		return;

	s_plugins.add((byte*)handle,0);
}
Example #10
0
void CKeyControl::TrackKey(CLinkListNode<KEY> *pNode, CPoint ptAnchor, CPoint ptOffset)
{
	CPoint ptLast = ptAnchor;
	CPoint ptCur;

	int xOff = ptOffset.x - ptAnchor.x;
	int yOff = ptOffset.y - ptAnchor.y;

	pNode->m_Data.m_bSelected = TRUE;

	// Make a list of all the keys that are selected

	CLinkList<CLinkListNode<KEY> *> collSelKeys;

	CLinkListNode<KEY> *pKeyNode = m_collKeys.GetHead();

	while (pKeyNode)
	{
		if (pKeyNode->m_Data.m_bSelected) collSelKeys.AddTail(pKeyNode);
		
		pKeyNode = pKeyNode->m_pNext;
	}

	while (GetAsyncKeyState(VK_LBUTTON) & 0x8000)
	{
		GetCursorPos(&ptCur);
		ScreenToClient(&ptCur);

		ptCur.x -= xOff;
		ptCur.y -= yOff;

		if (ptCur != ptLast)
		{
			float tmKeyBase = (float)ptCur.x / (float)m_cx;
			float valBase   = (float)(m_cy - ptCur.y) / (float)m_cy;

			if (valBase < 0.0f) valBase = 0.0f;
			if (valBase > 1.0f) valBase = 1.0f;

			CLinkListNode<CLinkListNode<KEY> *> *pSelNode = collSelKeys.GetHead();

			while (pSelNode)
			{
				CLinkListNode<KEY> *pCurNode = pSelNode->m_Data;

				float tmKey = tmKeyBase - pNode->m_Data.m_tmAnchor;
				float val   = valBase - pNode->m_Data.m_valAnchor;

				float tmActual = tmKey + pCurNode->m_Data.m_tmAnchor;
				
				if (pCurNode->m_pPrev)
				{
					float tmPrevActual = pCurNode->m_pPrev->m_Data.m_tmAnchor + pCurNode->m_pPrev->m_Data.m_tmKey;

					if (tmPrevActual > tmActual)
					{
						tmKey = tmPrevActual - pCurNode->m_Data.m_tmAnchor;
					}
				}
				else
				{
					tmKey = 0.0f;
				}

				if (pCurNode->m_pNext)
				{
					float tmNextActual = pCurNode->m_pNext->m_Data.m_tmAnchor + pCurNode->m_pNext->m_Data.m_tmKey;

					if (tmNextActual < tmActual)
					{
						tmKey = tmNextActual - pCurNode->m_Data.m_tmAnchor;
					}
				}
				else
				{
					tmKey = 1.0f - pCurNode->m_Data.m_tmAnchor;
				}

				if (val + pCurNode->m_Data.m_valAnchor < 0.0f) val = -pCurNode->m_Data.m_valAnchor;
				if (val + pCurNode->m_Data.m_valAnchor > 1.0f) val = 1.0f - pCurNode->m_Data.m_valAnchor;

				pCurNode->m_Data.m_tmKey = tmKey;
				pCurNode->m_Data.m_val = val;

				pSelNode = pSelNode->m_pNext;
			}

			ptLast = ptCur;
		}
		
		Redraw(pNode);
	}

	// And update the new positions

	pNode = m_collKeys.GetHead();

	while (pNode)
	{
		pNode->m_Data.m_tmAnchor  += pNode->m_Data.m_tmKey;
		pNode->m_Data.m_valAnchor += pNode->m_Data.m_val;
		pNode->m_Data.m_tmKey = 0.0f;
		pNode->m_Data.m_val   = 0.0f;
		pNode->m_Data.m_bSelected = FALSE;
		
		pNode = pNode->m_pNext;
	}

	// And one final redraw to remove the selected stuff
	
	Redraw(NULL);
}
Example #11
0
//-----------------------------------------------------------------------------
// Name: FreeOptionalParametersMemory
// Object: Free memory of optional parameters info from index FromIndex
// Parameters :
//     in  : API_INFO *pAPIInfo
//           BYTE FromIndex : index from which delete memory, !=0 only to remove
//                            some too much allocated memory (see number parameter 
//                            correction from APIOverrideKernel)
//           BYTE ToIndex : index to delete memory, must be < MAX_PARAM
//                          should be pAPIInfo->MonitoringParamCount
// Return : 
//-----------------------------------------------------------------------------
void FreeOptionalParametersMemory(API_INFO *pAPIInfo,BYTE FromIndex,BYTE ToIndex)
{
    CLinkListItem* pItem;
    PMONITORING_PARAMETER_OPTIONS pParamOption;
    BYTE Cnt;
    CLinkList* pList;

    // remove all breaking or logging options
    // let it to avoid crash : when a flag is specified, it require memory that has been freed !!!
    memset(&pAPIInfo->LogBreakWay,0,sizeof(API_LOG_BREAK_WAY));

    if (ToIndex>=MAX_PARAM)
        ToIndex=MAX_PARAM-1;

    // we have to free optional parameter allocated memory
    for(Cnt=FromIndex;Cnt<=ToIndex;Cnt++)
    {
        pAPIInfo->ParamList[Cnt].dwSizeOfData=0;
        pAPIInfo->ParamList[Cnt].dwSizeOfPointedData=0;
        pAPIInfo->ParamList[Cnt].dwType=0;


        if (pAPIInfo->ParamList[Cnt].pConditionalLogContent!=NULL)
        {
            // store list pointer
            pList=pAPIInfo->ParamList[Cnt].pConditionalLogContent;
            // set pAPIInfo list pointer to NULL
            pAPIInfo->ParamList[Cnt].pConditionalLogContent=NULL;

            // free memory
            pList->Lock();
            for(pItem=pList->Head;pItem;pItem=pItem->NextItem)
            {
                pParamOption=(MONITORING_PARAMETER_OPTIONS*)pItem->ItemData;
                if (pParamOption->pbPointedValue!=0)
                    HeapFree(ApiOverrideHeap,0,pParamOption->pbPointedValue);
            }
            pList->RemoveAllItems(TRUE);
            delete pList;
        }

        if (pAPIInfo->ParamList[Cnt].pConditionalBreakContent!=NULL)
        {
            // store list pointer
            pList=pAPIInfo->ParamList[Cnt].pConditionalBreakContent;
            // set pAPIInfo list pointer to NULL
            pAPIInfo->ParamList[Cnt].pConditionalBreakContent=NULL;

            // free memory
            pList->Lock();
            for(pItem=pList->Head;pItem;pItem=pItem->NextItem)
            {
                pParamOption=(MONITORING_PARAMETER_OPTIONS*)pItem->ItemData;
                if (pParamOption->pbPointedValue!=0)
                    HeapFree(ApiOverrideHeap,0,pParamOption->pbPointedValue);
            }
            pList->RemoveAllItems(TRUE);
            delete pList;
        }
    }
}
void CvPlotGroup::recalculatePlots()
{
	PROFILE_FUNC();

	CLLNode<XYCoords>* pPlotNode;
	CvPlot* pPlot;
	CLinkList<XYCoords> oldPlotGroup;
	XYCoords xy;
	PlayerTypes eOwner;
	int iCount;

	eOwner = getOwnerINLINE();

	pPlotNode = headPlotsNode();

	if (pPlotNode != NULL)
	{
		pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

		iCount = 0;

		gDLL->getFAStarIFace()->SetData(&GC.getPlotGroupFinder(), &iCount);
		gDLL->getFAStarIFace()->GeneratePath(&GC.getPlotGroupFinder(), pPlot->getX_INLINE(), pPlot->getY_INLINE(), -1, -1, false, eOwner);

		if (iCount == getLengthPlots())
		{
			return;
		}
	}

	oldPlotGroup.clear();

	pPlotNode = headPlotsNode();

	while (pPlotNode != NULL)
	{
		pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

		FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value");

		xy.iX = pPlot->getX_INLINE();
		xy.iY = pPlot->getY_INLINE();

		oldPlotGroup.insertAtEnd(xy);

		pPlot->setPlotGroup(eOwner, NULL);

		pPlotNode = deletePlotsNode(pPlotNode); // will delete this PlotGroup...
	}

	pPlotNode = oldPlotGroup.head();

	while (pPlotNode != NULL)
	{
		pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

		FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value");

		pPlot->updatePlotGroup(eOwner, true);

		pPlotNode = oldPlotGroup.deleteNode(pPlotNode);
	}
}
Example #13
0
//-----------------------------------------------------------------------------
// Name: MakeStats
// Object: compute statistics and add them to listview
// Parameters :
//     in  : 
//     out :
//     return : 
//-----------------------------------------------------------------------------
void CLogsStatsUI::MakeStats()
{
    CLinkListItem* pItemLogList;
    CLinkListItem* pItemStatList;
    CLinkList* pStatList;
    LOG_LIST_ENTRY* pLogEntry;
    STATSTRUCT* pStat;
    STATSTRUCT Stat;
    BOOL bFoundInStatList;
    TCHAR** ppc=new TCHAR*[4];
    TCHAR pszCallCount[12];
    TCHAR pszAverageDuration[12];
    DWORD AverageDuration;
    HCURSOR hOldCursor;

    // create a list of STATSTRUCT
    pStatList=new CLinkList(sizeof(STATSTRUCT));

    // store original cursor
    hOldCursor=GetCursor();

    // set cusor to wait cursor
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    // for each item in pLogList
    pLogList->Lock(TRUE);
    for (pItemLogList=pLogList->Head;pItemLogList;pItemLogList=pItemLogList->NextItem)
    {
        pLogEntry=(LOG_LIST_ENTRY*)pItemLogList->ItemData;
        // if pLogEntry is an user message, go to next entry
        if (pLogEntry->Type!=ENTRY_LOG)
            continue;

        bFoundInStatList=FALSE;

        // a function is defined by it's api name and module name
        // so try to find an item in pStatList with same api name and module name
        pStatList->Lock();
        for (pItemStatList=pStatList->Head;pItemStatList;pItemStatList=pItemStatList->NextItem)
        {
            pStat=(STATSTRUCT*)pItemStatList->ItemData;
            // compare api and module name
            if (_tcsicmp(pStat->ApiName,pLogEntry->pLog->pszApiName)==0)
            {
                if(_tcsicmp(pStat->ModuleName,pLogEntry->pLog->pszModuleName)==0)
                {
                    // the func is already in stat list, so update it's stat values

                    // update count
                    pStat->Count++;

                    // update DurationSum (trying to avoid buffer overflow)
                    if (0xFFFFFFFF-pLogEntry->pLog->pHookInfos->dwCallDuration<=pStat->DurationSum)
                        pStat->DurationSum=0xFFFFFFFF;
                    else
                        pStat->DurationSum+=pLogEntry->pLog->pHookInfos->dwCallDuration;

                    // we have found item
                    bFoundInStatList=TRUE;
                    break;
                }
            }
        }
        pStatList->Unlock();

        // if item was not in state list, add it to stat list
        if (!bFoundInStatList)
        {
            _tcscpy(Stat.ApiName,pLogEntry->pLog->pszApiName);
            _tcscpy(Stat.ModuleName,pLogEntry->pLog->pszModuleName);
            Stat.Count=1;
            Stat.DurationSum=pLogEntry->pLog->pHookInfos->dwCallDuration;

            pStatList->AddItem(&Stat);
        }
    }
    pLogList->Unlock();

    // for each item of pStatList
    pStatList->Lock();
    for (pItemStatList=pStatList->Head;pItemStatList;pItemStatList=pItemStatList->NextItem)
    {
        // add item to list view
        pStat=(STATSTRUCT*)pItemStatList->ItemData;

        // api name
        ppc[0]=pStat->ApiName;

        // module name
        ppc[1]=pStat->ModuleName;

        // call count
        _stprintf(pszCallCount,_T("%u"),pStat->Count);
        ppc[2]=pszCallCount;

        // average duration
        AverageDuration=pStat->DurationSum/pStat->Count;
        if (pStat->DurationSum==0xFFFFFFFF)
            _stprintf(pszAverageDuration,_T(">%u"),AverageDuration);
        else
            _stprintf(pszAverageDuration,_T("%u"),AverageDuration);
    
        ppc[3]=pszAverageDuration;

        this->pListview->AddItemAndSubItems(4,ppc,FALSE);
    }
    pStatList->Unlock();

    // free allocated memory
    delete[] ppc;

    delete pStatList;

    // restore original cursor
    SetCursor(hOldCursor);
}
Example #14
0
//-----------------------------------------------------------------------------
// Name: ParseCOMMonitoringFileLine
// Object: COM monitoring file line parser
// Parameters :
//     in  : 
//     out : 
//     return : 
//-----------------------------------------------------------------------------
BOOL CComShowMethodsAddress::ParseCOMMonitoringFileLine(TCHAR* pszFileName,TCHAR* Line,DWORD dwLineNumber,LPVOID UserParam)
{
    CMethodInfo* pMethodInfo;
    TCHAR* pszFunctionDefinition;
    TCHAR* psz;
    HOOK_DEFINITION_INFOS HookDefinitionInfos;
    BOOL bAlreadyExisting;

    SHOWMETHODSADDRESS_PARSE_COM_MONITORING_FILE_LINE_PARAM* pParam;

    pParam=(SHOWMETHODSADDRESS_PARSE_COM_MONITORING_FILE_LINE_PARAM*)UserParam;


    CTrimString::TrimString(Line);

    // if empty or commented line (WARNING we keep monitoring disabled lines !!!)
    if ((*Line==0)||(*Line==';'))
        // continue parsing
        return TRUE;

    if (*Line=='!')
    {
        Line++;
        CTrimString::TrimString(Line);
    }

    // line is like 
    // vtbl hooking info|function definition|optional parameters


    // find first splitter (between vtbl hooking info definition and function definition)
    pszFunctionDefinition=_tcschr(Line,FIELDS_SEPARATOR);

    if (pszFunctionDefinition)
    {
        // ends line --> line contain only vtbl hooking info
        *pszFunctionDefinition=0;
        // point to function definition
        pszFunctionDefinition++;
    }

    // get vtbl hooking info definition
    if(!GetHookDefinitionInfo(Line,pParam->pIid,&HookDefinitionInfos))
    {
        return ReportParsingError(pszFileName,dwLineNumber);
    }

    // if we need a full iid spying, the matching IID file needs to be loaded
    if (HookDefinitionInfos.VTBLInfoType==VTBL_INFO_TYPE_OBJECT_FULL_IID)
    {
        CLinkList* mpLinkListOfBaseInterfacesID;
        if (pParam->pLinkListOfBaseInterfacesID)
            mpLinkListOfBaseInterfacesID=pParam->pLinkListOfBaseInterfacesID;
        else
            mpLinkListOfBaseInterfacesID=new CLinkList(sizeof(IID));

        CLinkListItem* pItem=mpLinkListOfBaseInterfacesID->AddItem(&HookDefinitionInfos.InterfaceID);
        pParam->pComShowMethodsAddress->ParseInterfaceDefinitionFile(pParam->pHookedClass,
                                                                     pParam->pIid,
                                                                     pParam->pInterfaceAssociatedToIID,
                                                                     pParam->pHookedObject,
                                                                     &HookDefinitionInfos.InterfaceID,
                                                                     mpLinkListOfBaseInterfacesID
                                                                    );
        mpLinkListOfBaseInterfacesID->RemoveItem(pItem);
        if (!pParam->pLinkListOfBaseInterfacesID)
            delete mpLinkListOfBaseInterfacesID;

        // continue parsing
        return TRUE;
    }

    if (!pszFunctionDefinition)
    {
        return ReportParsingError(pszFileName,dwLineNumber);
    }

    // get function name (avoid HookComInfos.ParseFunctionDescription to avoid to load APIOverride dll)
    // search end of function name
    psz=_tcschr(pszFunctionDefinition, '(');
    if (psz)
        *psz=0;
    // remove return type in function name if any or WINAPI, __cdecl keywords 
    // search last space in function name
    psz=_tcsrchr(pszFunctionDefinition,' ');
    // keep only data after last space
    if (psz)
    {
        psz++;// point to char after space
        pszFunctionDefinition=psz;
    }


    // get method info (this will auto add pMethodInfo object to matching interface)
    if (!pParam->pHookedClass->GetMethodInfoForHook(pParam->pHookedObject,
                                                    pParam->pInterfaceAssociatedToIID,
                                                    pParam->pLinkListOfBaseInterfacesID,
                                                    &HookDefinitionInfos,
                                                    pszFunctionDefinition,
                                                    pszFileName,
                                                    dwLineNumber,
                                                    HOOK_TYPE_MONITORING,
                                                    TRUE,// act like auto hooking
                                                    &pMethodInfo,
                                                    &bAlreadyExisting))
    {
        // continue parsing
        return TRUE;
    }

    // copy api name into pMethodInfo
    pMethodInfo->SetName(pszFunctionDefinition);

    // continue parsing
    return TRUE;
}