// XmlConfigParse.cpp: implementation of the CXmlConfigParse class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XmlConfigParse.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define FILE_OMIT_FLAG  2

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CXmlConfigParse::CXmlConfigParse()
{
	m_xmlConfig.Close();
	m_mapProductInfo.RemoveAll();
	m_mapProductEnable.RemoveAll();
	m_aProductList.RemoveAll();
	m_pCurProduct = NULL;
	m_bOK = FALSE;
	m_strBaseConfig = _T("");
	m_mapPrdCfg.RemoveAll();
}

CXmlConfigParse::CXmlConfigParse(LPCTSTR lpcstrFileName)
{
	if(!Init(lpcstrFileName))
	{
		return;	
	}
	m_pCurProduct = NULL;
}

CXmlConfigParse::~CXmlConfigParse()
{
	m_bOK = FALSE;
	m_pCurProduct = NULL;
	int nCount = m_aProductList.GetSize();
	PPRODUCT_INFO_T pProd;
	for(int i = 0; i< nCount; i++)
	{
		m_mapProductInfo.Lookup(m_aProductList[i],pProd);

		if(pProd != NULL)
		{
			pProd->Clear();
			delete pProd;
		}
	}
	m_mapProductInfo.RemoveAll();
	m_mapProductEnable.RemoveAll();
	m_aProductList.RemoveAll();	
	m_mapPrdCfg.RemoveAll();
}


BOOL CXmlConfigParse::Init(LPCTSTR lpszFileName,int nFlag /*= 0*/)
{
	if(!lpszFileName)
	{
		AfxMessageBox( _T("The file name must not be empty!") );
		return FALSE;
	}
	m_strBaseConfig = lpszFileName;
    if(nFlag == 0)
	{
		CString strBasePath= lpszFileName;
		int nFind = strBasePath.ReverseFind(_T('\\'));
		strBasePath = strBasePath.Left(nFind);

		m_bOK = LoadAllProductInfo(strBasePath);
	}
	else
	{
// 		m_aProductList.RemoveAll();
// 		m_mapProductInfo.RemoveAll();
// 		m_mapProductEnable.RemoveAll();
// 		m_mapPrdCfg.RemoveAll();
		
		m_bOK = _LoadProductInfo(lpszFileName,TRUE);	
	}


	return m_bOK;
	
}
/**
 * Get the number of products
 *
 * @return Returns dwCount,the number of products
 */ 
DWORD CXmlConfigParse::GetProductCount()
{	
	return m_aProductList.GetSize();
}
/**
 * Get product names
 *
 * @param arrProductNameList: store the names; 
 */   
/*void CXmlConfigParse::GetProductNameList(CStringArray &arrProductNameList)
{
	LPXNode lpChild;
	lpChild = m_xmlConfig.GetChild(_T("ProductList") );
	XNodes childs;
	childs = lpChild->GetChilds(_T("Product") );
	int  nCount = childs.size();
	CString strAttValue;
	for( int i = 0; i < nCount; i++)
	{
		strAttValue= childs[i]->GetAttrValue(_T("name"));
		ASSERT(!strAttValue.IsEmpty());
		arrProductNameList.Add(strAttValue);
	}
	childs.clear();

}*/
/**
 * Get product names
 *
 * @param pProductNameList: store the names; 
 * @param dwSize: original pProductNameList spaces size; 
 * @param dwRealSize: real used size; 
 */ 
void CXmlConfigParse::GetProductNameList(LPTSTR pProductNameList,DWORD dwSize,DWORD &dwRealSize)
{
	int  nCount = m_aProductList.GetSize();
	CString strName;
	dwRealSize = 0;
	memset(pProductNameList,0,dwSize*sizeof(_TCHAR));
	for( int i = 0; i < nCount; i++)
	{
		strName= m_aProductList.GetAt(i);
		ASSERT(!strName.IsEmpty());
		dwRealSize+=strName.GetLength();
		if(dwRealSize >= dwSize)
		{
			break;
		}
		_tcscat(pProductNameList,(LPCTSTR)strName);
		pProductNameList[dwRealSize]=_T(';');
		dwRealSize++; //+';'
		//arrProductNameList.Add(strAttValue);
	}
	pProductNameList[dwRealSize] = _T('\0');
}

PPRODUCT_INFO_T CXmlConfigParse::GetProdInfo(LPCTSTR lpszProductName)
{
	ASSERT(lpszProductName != NULL);
    BOOL bOk = m_mapProductInfo.Lookup(lpszProductName,m_pCurProduct);
	if(!bOk)
	{
		m_pCurProduct = NULL;
	}
	return m_pCurProduct;
}

/**
 * Release this
 */ 
void CXmlConfigParse::Release()
{
	m_bOK = FALSE;
	m_pCurProduct = NULL;
	int nCount = m_aProductList.GetSize();
	PPRODUCT_INFO_T pProd;
	for(int i = 0; i< nCount; i++)
	{
		m_mapProductInfo.Lookup(m_aProductList[i],pProd);

		ASSERT(pProd != NULL);
		if(pProd->pFileInfoArr )
			delete [] pProd->pFileInfoArr;
		if(pProd->paNvBackupItem)
			delete [] pProd->paNvBackupItem;
		delete pProd;
	}
	m_mapProductInfo.RemoveAll();
	m_mapProductEnable.RemoveAll();
	m_aProductList.RemoveAll();	
	m_mapPrdCfg.RemoveAll();
	delete this;
}

BOOL CXmlConfigParse::Success()
{
	return m_bOK;
}



BOOL CXmlConfigParse::LoadAllProductInfo(LPCTSTR lpszConfigBase)
{
	CString strWildPath = lpszConfigBase;
	strWildPath += _T("\\*.xml");
	CFileFind finder;
	BOOL bFound;
	bFound = finder.FindFile(strWildPath);
	CStringArray aFilePath;
	CObArray aTime;
	CString strPath;
	CString strName;
	CString strBaseConfg = m_strBaseConfig;
	int nFind = strBaseConfg.ReverseFind(_T('\\'));
    strBaseConfg = strBaseConfg.Right(strBaseConfg.GetLength() - nFind -1);
//	CTime *pCurTime;
	CTime lmCurTime;
	int i=0;
	while(bFound)
	{
		bFound = finder.FindNextFile();
	    strName = finder.GetFileName();
		if(strName.CompareNoCase(_T("BMAConfigSchema.xml")) == 0 ||
			strName.CompareNoCase(strBaseConfg)== 0)
		{
			continue;
		}
		else if(strName.Right(4).CompareNoCase(_T(".xml")) == 0)
		{
			strPath = finder.GetFilePath();
			finder.GetLastWriteTime(lmCurTime);
			
			int nCount = aFilePath.GetSize();
			if(nCount == 0)
			{
				aFilePath.Add(strPath);
				//pCurTime= new CTime(lmCurTime);
				aTime.Add((CObject *)&lmCurTime);
			}
			else
			{
				for(i=0; i<nCount;i++)
				{
					if(lmCurTime>= *(CTime*)aTime[i])
					{
						aTime.InsertAt(i,(CObject *)&lmCurTime);
						aFilePath.InsertAt(i,strPath);
						break;
					}
				}
				if(i>=nCount)
				{
					aTime.Add((CObject *)&lmCurTime);
					aFilePath.Add(strPath);
				}

			}
			
		}
	}

	m_aProductList.RemoveAll();
	m_mapProductInfo.RemoveAll();
	m_mapProductEnable.RemoveAll();
	m_mapPrdCfg.RemoveAll();
	aFilePath.Add(m_strBaseConfig);

    int nFileCount = aFilePath.GetSize();
	
	if(nFileCount == 0)
		return FALSE;
	
    BOOL bOk = TRUE;
	for(i=0;i<nFileCount;i++)
	{
		bOk = _LoadProductInfo(aFilePath.GetAt(i));
		if(!bOk)
			return FALSE;
	}

	return TRUE;
}

BOOL CXmlConfigParse::_Init(LPCTSTR lpszConfigName)
{
	_ASSERTE(lpszConfigName != NULL);

	// Open file
	CString strText;
	CString strNotes;
	CFile file;
	if ( !file.Open( lpszConfigName, CFile::modeRead ) )
	{
		AfxMessageBox( _T("Unable to open xml config file") );
		return FALSE;
	}
	int nFileLen = (int)file.GetLength();
	
	// Allocate buffer for binary file data
	char* pBuffer = new char[nFileLen + 1];
	memset(pBuffer,0,nFileLen + 1);
	nFileLen = file.Read( pBuffer, nFileLen );
	file.Close();
	pBuffer[nFileLen] = '\0';
	

	_TCHAR *pBufferU = NULL;
	if(pBuffer[0] != (UCHAR)0xFF || pBuffer[1] != (UCHAR)0xFE)//not unicode 
	{
		pBufferU = new _TCHAR[nFileLen+1];
		memset(pBufferU,0,sizeof(_TCHAR)*(nFileLen + 1));
		MultiByteToWideChar(CP_ACP,0,pBuffer,nFileLen+1,pBufferU,nFileLen+1);
		strText.Empty();
		strText = pBufferU;
	}
	else
	{
		strText = (LPTSTR)pBuffer;
	}
	
	delete [] pBuffer;
	pBuffer = NULL;
	if(pBufferU != NULL)
	{
		delete [] pBufferU;
		pBufferU = NULL;
	}
	
	CString strXmlRet;
	strXmlRet = m_xmlConfig.Load(strText);
	strText.Empty();

	if(strXmlRet.IsEmpty())
	{
		return FALSE;
	}
	return TRUE;
}

BOOL CXmlConfigParse::_LoadProductInfo(LPCTSTR lpszConfigName,BOOL bChangePrdName/*= FALSE*/)
{
	BOOL bRet = _Init(lpszConfigName);
	if(!bRet)
		return FALSE;

	PPRODUCT_INFO_T pProuctInfo = NULL;
	PPRODUCT_INFO_T pFindProuctInfo = NULL;

	LPXNode lpChild;
	lpChild = m_xmlConfig.GetChild(_T("ProductList") );

	if(lpChild == NULL) //check
		return FALSE;

	XNodes xnProductNodes;
	xnProductNodes = lpChild->GetChilds(_T("Product") );

	int  nCount = xnProductNodes.size();
	CString strCurSchemeName;
	CString strValue;
	int  nValue;
	int nNvBkpItem;
	int i,j,k;
	UINT uEnable;


	for( i = 0; i < nCount; i++)
	{		
		strValue= xnProductNodes[i]->GetAttrValue(_T("name"));
		ASSERT(!strValue.IsEmpty());
		if(strValue.IsEmpty())
		{
			continue;
		}

		if(bChangePrdName)
		{
			strValue.TrimLeft();
			strValue.Insert(0,_T("PAC_"));
		}

		CString strEnable = xnProductNodes[i]->GetAttrValue(_T("enable"));
		nValue = 1;
		_stscanf( strEnable, _T("%d"), &nValue);

		//already exist
        if(m_mapProductInfo.Lookup(strValue,pFindProuctInfo))
		{
			continue;
		}
        uEnable = 1;
		if(m_mapProductEnable.Lookup(strValue,uEnable))
		{
			if(uEnable == 0)
			{
				continue;
			}
			
		}
		else
		{
			m_mapProductEnable.SetAt(strValue,(UINT)nValue);
			if(nValue == 0) //
			{
				continue;
			}
		}

        pProuctInfo = new PRODUCT_INFO_T;

		m_aProductList.Add(strValue);
		m_mapProductInfo.SetAt(strValue,pProuctInfo);
		m_mapPrdCfg.SetAt(strValue,lpszConfigName);
		_tcscpy(pProuctInfo->szProductName,strValue);

		strCurSchemeName=xnProductNodes[i]->GetChildValue(_T("SchemeName"));
			
		strValue = xnProductNodes[i]->GetChildValue(_T("FlashTypeID"));
        _stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwFlashType = nValue;

		strValue = xnProductNodes[i]->GetChildValue(_T("Mode"));
		_stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwMode = nValue;

		strValue = xnProductNodes[i]->GetChildValue(_T("ProductComment"));
		lstrcpyn(pProuctInfo->szComment,strValue,MAX_PATH+1);

        nValue = 0;
		strValue = xnProductNodes[i]->GetChildValue(_T("NvBaseAddrChangeFlag"));
		_stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwNvBaseChangeFlag = nValue;

		nValue = 0;
		strValue = xnProductNodes[i]->GetChildValue(_T("NvNewBasePosition"));
		_stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwNvNewBasePosition= nValue;
		
		nValue = 0;
		strValue = xnProductNodes[i]->GetChildValue(_T("NVOrgFlag"));
		_stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwNVOrgFlag = nValue;

		nValue = 0;
		strValue = xnProductNodes[i]->GetChildValue(_T("NVOrgBasePosition"));
		_stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwNVOrgBasePosition= nValue;
		
		nValue = 0;
		strValue = xnProductNodes[i]->GetChildValue(_T("OmaDMFlag"));
		_stscanf( strValue, _T("%d"), &nValue);
		pProuctInfo->dwOmaDMFlag= nValue;

		
		//for flash type info
		
		LPXNode lpxnFlashInfo;
		lpxnFlashInfo = xnProductNodes[i]->GetChild(_T("FlashInfo"));
		
		if(lpxnFlashInfo != NULL)
		{
	//		nValue = 0;
	//		strValue = lpxnFlashInfo->GetAttrValue(_T("type"));
	//        _stscanf( strValue, _T("%d"), &nValue);
	//		pProuctInfo->dwFlashType = nValue;

			nValue = 0;
			strValue = lpxnFlashInfo->GetAttrValue(_T("use"));
			_stscanf( strValue, _T("%d"), &nValue);
			pProuctInfo->dwUseFlashIdInfo = nValue;	

			if(pProuctInfo->dwUseFlashIdInfo == 1)
			{
				XNodes xnFlashInfoList;
				xnFlashInfoList = lpxnFlashInfo->GetChilds(_T("FlashItem"));
				int nFlashItemCount = xnFlashInfoList.size();
                if(nFlashItemCount > MAX_BLOCK_NUM)
							nFlashItemCount = MAX_BLOCK_NUM;
				pProuctInfo->dwFlashIDCount = (DWORD)nFlashItemCount;

				for(k=0; k<nFlashItemCount;k++)
				{		
					strValue = xnFlashInfoList[k]->GetAttrValue(_T("name"));
					_tcscpy(pProuctInfo->aFlashInfo[k].szName,strValue);
					
					strValue = xnFlashInfoList[k]->GetAttrValue(_T("id"));
					_stscanf( strValue, _T("0x%x"), &(pProuctInfo->aFlashInfo[k].dwID));

					strValue = xnFlashInfoList[k]->GetAttrValue(_T("index"));
					_stscanf( strValue, _T("%d"), &(pProuctInfo->aFlashInfo[k].dwBaseIndex));
				}
				xnFlashInfoList.clear();
			}
		}
		LPXNode lpxnFlashSpec;
		lpxnFlashSpec = xnProductNodes[i]->GetChild(_T("FlashSpec"));
		
		if(lpxnFlashSpec != NULL)
		{
			nValue = 0;
			strValue = lpxnFlashSpec->GetAttrValue(_T("use"));
			_stscanf( strValue, _T("%d"), &nValue);
			pProuctInfo->dwUseFlashIdSpec = nValue;	

			if(pProuctInfo->dwUseFlashIdSpec == 1)
			{
				XNodes xnFlashSpecList;
				xnFlashSpecList = lpxnFlashSpec->GetChilds(_T("FlashSpecItem"));
				int nFlashSpecItemCount = xnFlashSpecList.size();
                if(nFlashSpecItemCount > MAX_BLOCK_NUM)
				{
					nFlashSpecItemCount = MAX_BLOCK_NUM;
				}

				pProuctInfo->dwFlashIDCount = (DWORD)nFlashSpecItemCount;

				for(k=0; k<nFlashSpecItemCount;k++)
				{		
					strValue = xnFlashSpecList[k]->GetAttrValue(_T("name"));
					_tcscpy(pProuctInfo->aFlashInfo[k].szName,strValue);
					
					strValue = xnFlashSpecList[k]->GetAttrValue(_T("id"));
					_stscanf( strValue, _T("0x%x"), &(pProuctInfo->aFlashInfo[k].dwID));

					strValue = xnFlashSpecList[k]->GetAttrValue(_T("index"));
					_stscanf( strValue, _T("%d"), &(pProuctInfo->aFlashInfo[k].dwBaseIndex));
				}
				xnFlashSpecList.clear();
			}
		}
		// for NV backup        
        LPXNode lpNvBackup = NULL;
		lpNvBackup = xnProductNodes[i]->GetChild(_T("NVBackup"));
		if(lpNvBackup != NULL) // if "NVBackup" exist
		{
			nValue = 0;
			strValue = lpNvBackup->GetAttrValue(_T("backup"));
			_stscanf( strValue, _T("%d"), &nValue);
			pProuctInfo->dwNvBackupFlag = nValue;
			
			if(nValue != 0)
			{
				XNodes xnNvBkpList;
				xnNvBkpList = lpNvBackup->GetChilds(_T("NVItem"));
				pProuctInfo->dwNvBackupItemCount = xnNvBkpList.size();
				nNvBkpItem = pProuctInfo->dwNvBackupItemCount;
				if(nNvBkpItem != 0)
				{
					pProuctInfo->paNvBackupItem = new NV_BACKUP_ITEM_T[nNvBkpItem];
					memset(pProuctInfo->paNvBackupItem,0,sizeof(NV_BACKUP_ITEM_T)*nNvBkpItem);
					
					for(j = 0; j<nNvBkpItem;j++)
					{
						PNV_BACKUP_ITEM_T pNBIT = pProuctInfo->paNvBackupItem + j;
							
						strValue = xnNvBkpList[j]->GetAttrValue(_T("name"));
						_tcscpy(pNBIT->szItemName,strValue);
						
						strValue = xnNvBkpList[j]->GetAttrValue(_T("backup"));
						nValue = 0;
						_stscanf(strValue,_T("%d"),&nValue);
						pNBIT->wIsBackup = (WORD)nValue;

						strValue = xnNvBkpList[j]->GetChildAttrValue(_T("BackupFlag"),_T("use"));
						nValue = 0;
						_stscanf(strValue,_T("%d"),&nValue);
						pNBIT->wIsUseFlag = (WORD)nValue;

						strValue = xnNvBkpList[j]->GetChildValue(_T("ID"));
						_stscanf(strValue,_T("0x%x"),&(pNBIT->dwID));
						
						if(pNBIT->wIsUseFlag == 1)
						{
							XNodes xnNvFlagList;
							LPXNode lpxnFlag;
							lpxnFlag = xnNvBkpList[j]->GetChild(_T("BackupFlag"));
							if(lpxnFlag == NULL)
							{
								delete [] pProuctInfo->paNvBackupItem;
								pProuctInfo->paNvBackupItem = NULL;
								delete pProuctInfo;
								pProuctInfo = NULL;
								return FALSE;							
							}
							
							xnNvFlagList = lpxnFlag->GetChilds(_T("NVFlag"));
							int nNvFlagCount = xnNvFlagList.size();
							if(nNvFlagCount > MAX_NV_BACKUP_FALG_NUM)
							{
								nNvFlagCount = MAX_NV_BACKUP_FALG_NUM;
							}

							pNBIT->dwFlagCount = (DWORD)nNvFlagCount;	
							TRACE(_T("%s: NvFlagCount:%d\n"),pProuctInfo->szProductName,nNvFlagCount);
						
							for(k=0; k<nNvFlagCount;k++)
							{		
								strValue = xnNvFlagList[k]->GetAttrValue(_T("name"));
								_tcscpy(pNBIT->nbftArray[k].szFlagName,strValue);
								
								strValue = xnNvFlagList[k]->GetAttrValue(_T("check"));
								_stscanf( strValue, _T("%d"), &(pNBIT->nbftArray[k].dwCheck));
							}
							xnNvFlagList.clear();
						}
					}
				}
				xnNvBkpList.clear();
			}
		}

//////////////////////////////////////////////////////////////////////////     
        LPXNode lpSpecialStrings = NULL;
		lpSpecialStrings = xnProductNodes[i]->GetChild(_T("SpecialStrings"));
		if(lpSpecialStrings != NULL) // if "SpecialStrings" exist
		{
			nValue = 0;
			strValue = lpSpecialStrings->GetAttrValue(_T("enable"));
			_stscanf( strValue, _T("%d"), &nValue);			
			if(nValue != 0)
			{
				XNodes xnSpecialStrList;
				xnSpecialStrList = lpSpecialStrings->GetChilds(_T("SString"));
				int nSSItem =  xnSpecialStrList.size();				
				if(nSSItem != 0)
				{
					pProuctInfo->pSpecialStrings = new SPECIAL_STRING_ARR;
					
					for(j = 0; j<nSSItem;j++)
					{
						SPECIAL_STRING_PTR pSString = new SPECIAL_STRING_T;
							
						strValue = xnSpecialStrList[j]->GetAttrValue(_T("name"));
						_tcscpy(pSString->szName,strValue);
						
						strValue = xnSpecialStrList[j]->GetAttrValue(_T("content"));
						_tcscpy(pSString->szContent,strValue);

						strValue = xnSpecialStrList[j]->GetAttrValue(_T("included"));
						_tcscpy(pSString->szIncluedFileID,strValue);
						
				
						XNodes xnLinkedFileList;						
						xnLinkedFileList = xnSpecialStrList[j]->GetChilds(_T("LinkedFile"));
						int nLFNodeCount = xnLinkedFileList.size();
						
						if(nLFNodeCount>0)
						{
							pSString->pLinkedFileIDs = new LINKED_FILE_ARR;

							for(k=0; k<nLFNodeCount;k++)
							{	
								LINKED_FILE_PTR pLinkedFile = new LINKED_FILE_T;
								strValue = xnLinkedFileList[k]->GetAttrValue(_T("id"));
								_tcscpy(pLinkedFile->szFileID,strValue);
								
								strValue = xnLinkedFileList[k]->GetAttrValue(_T("download"));
								_stscanf( strValue, _T("%d"), &(pLinkedFile->dwDLFlag));

								pSString->pLinkedFileIDs->push_back(pLinkedFile);
							}
						}					
						pProuctInfo->pSpecialStrings->push_back(pSString);
						
						xnLinkedFileList.clear();
					}
				
				}
				xnSpecialStrList.clear();
			}
		}

//////////////////////////////////////////////////////////////////////////
		
		LPXNode lpSchemeListNode = m_xmlConfig.GetChild( _T("SchemeList") );
		XNodes xnSchemeNodeList;
		xnSchemeNodeList = lpSchemeListNode->GetChilds(_T("Scheme"));
		int nSchemeCount = xnSchemeNodeList.size();
		
		for(j = 0; j<nSchemeCount;j++)
		{
			strValue= xnSchemeNodeList[j]->GetAttrValue(_T("name"));
			ASSERT(!strValue.IsEmpty());
			
			if(strValue.Compare(strCurSchemeName)==0)
			{
				XNodes xnFileNodeList;
				xnFileNodeList = xnSchemeNodeList[j]->GetChilds(_T("File"));
				pProuctInfo->dwFileCount = xnFileNodeList.size();
				int nFileCount = (int)(pProuctInfo->dwFileCount);
				if(nFileCount > 0)
				{
					pProuctInfo->pFileInfoArr = new FILE_INFO_T[nFileCount];
					memset(pProuctInfo->pFileInfoArr,0,sizeof(FILE_INFO_T)*nFileCount);
					for(k=0;k<nFileCount;k++)
					{
						PFILE_INFO_T pFIT = pProuctInfo->pFileInfoArr + k;
			
						strValue = xnFileNodeList[k]->GetChildValue(_T("ID"));	
						_tcscpy(pFIT->szID,strValue);
						
						strValue.Empty();
						strValue = xnFileNodeList[k]->GetChildValue(_T("IDAlias"));	
						if(!strValue.IsEmpty())
						{
							_tcscpy(pFIT->szIDAlias,strValue);
						}
						else
						{
							_tcscpy(pFIT->szIDAlias,pFIT->szID);
						}
						

						strValue = xnFileNodeList[k]->GetChildValue(_T("Type"));
						_tcscpy(pFIT->szType,strValue);
						
						strValue = xnFileNodeList[k]->GetChildValue(_T("Flag"));
						pFIT->dwFlag = (DWORD)_ttoi(strValue);
						
						strValue = xnFileNodeList[k]->GetChildValue(_T("CheckFlag"));
						pFIT->dwCheckFlag = (DWORD)_ttoi(strValue);
						
						strValue = xnFileNodeList[k]->GetChildValue(_T("Description"));
						_tcscpy(pFIT->szFileDescript,strValue);

						XNodes nxBlockList;
						nxBlockList = xnFileNodeList[k]->GetChilds(_T("Block"));
						int nBlockCount = nxBlockList.size();

						if(nBlockCount > MAX_BLOCK_NUM)
							nBlockCount = MAX_BLOCK_NUM;
						
						pFIT->dwBlockCount = (DWORD)nBlockCount;

						for(int t=0; t<nBlockCount;t++)
						{		
							strValue = nxBlockList[t]->GetChildValue(_T("Base"));
							_stscanf( strValue, _T("0x%X"), &(pFIT->arrBlock[t].dwBase));
							
							strValue = nxBlockList[t]->GetChildValue(_T("Size"));
							_stscanf( strValue, _T("0x%X"), &(pFIT->arrBlock[t].dwSize));
						}
						nxBlockList.clear();
					}
				}

				xnFileNodeList.clear();
				
				break;
			}
		}
        xnSchemeNodeList.clear();

		if(j >= nSchemeCount)
		{
			TRACE(_T("Product scheme[%s] is not exist!\r\n"),strCurSchemeName);			
			continue;
		}
	}
	xnProductNodes.clear();	

	_Close();

	return TRUE;
}

void  CXmlConfigParse::_Close()
{
	m_xmlConfig.Close();
}

LPTSTR  CXmlConfigParse::GetConfigFile(LPCTSTR lpszProductName)
{
	ASSERT(lpszProductName != NULL);
	static CString strConfigFile = _T("");

    BOOL bOk = m_mapPrdCfg.Lookup(lpszProductName,strConfigFile);
	if(!bOk)
	{
		return NULL;
	}
	return (LPTSTR)(LPCTSTR)strConfigFile;
}