// This method generates an XML file describing the crash
BOOL CErrorReportExporter::CreateCrashDescriptionXML(CErrorReportInfo& eri)
{
	BOOL bStatus = FALSE;
	ERIFileItem fi;
	CString sFileName = eri.GetErrorReportDirName() + _T("\\crashrpt.xml");
	CString sErrorMsg;
	strconv_t strconv;
	TiXmlDocument doc;
	FILE* f = NULL; 
	CString sNum;
	CString sCrashRptVer;
	CString sOSIs64Bit;
	CString sExceptionType;

	fi.m_bMakeCopy = false;
	fi.m_sDesc = _T("±ÀÀ£³ÌÐòÊôÐÔ¼¯");
	fi.m_sDestFile = _T("crashrpt.xml");
	fi.m_sSrcFile = sFileName;
	fi.m_sErrorStatus = sErrorMsg;  
	// Add this file to the list
	eri.AddFileItem(&fi);

	TiXmlNode* root = root = new TiXmlElement("CrashRpt");
	doc.LinkEndChild(root);  
	sCrashRptVer.Format(_T("%d"), CRASHRPT_VER);
	TiXmlHandle(root).ToElement()->SetAttribute("version", strconv.t2utf8(sCrashRptVer));

	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "" );
	doc.InsertBeforeChild(root, *decl);
	
	AddElemToXML(_T("CrashGUID"), eri.GetCrashGUID(), root);
	AddElemToXML(_T("AppName"), eri.GetAppName(), root);
	AddElemToXML(_T("AppVersion"), eri.GetAppVersion(), root);  
	AddElemToXML(_T("ImageName"), eri.GetImageName(), root);
	AddElemToXML(_T("OperatingSystem"), eri.GetOSName(), root);


	sOSIs64Bit.Format(_T("%d"), eri.IsOS64Bit());
	AddElemToXML(_T("OSIs64Bit"), sOSIs64Bit, root);

	AddElemToXML(_T("GeoLocation"), eri.GetGeoLocation(), root);
	AddElemToXML(_T("SystemTimeUTC"), eri.GetSystemTimeUTC(), root);
		
	if(eri.GetExceptionAddress()!=0)
	{
		sNum.Format(_T("0x%I64x"), eri.GetExceptionAddress());
		AddElemToXML(_T("ExceptionAddress"), sNum, root);

		AddElemToXML(_T("ExceptionModule"), eri.GetExceptionModule(), root);

		sNum.Format(_T("0x%I64x"), eri.GetExceptionModuleBase());
		AddElemToXML(_T("ExceptionModuleBase"), sNum, root);

		AddElemToXML(_T("ExceptionModuleVersion"), eri.GetExceptionModuleVersion(), root);
	}

	sExceptionType.Format(_T("%d"), m_CrashInfo.m_nExceptionType);
	AddElemToXML(_T("ExceptionType"), sExceptionType, root);
	if(m_CrashInfo.m_nExceptionType==CR_SEH_EXCEPTION)
	{
		CString sExceptionCode;
		sExceptionCode.Format(_T("%d"), m_CrashInfo.m_dwExceptionCode);
		AddElemToXML(_T("ExceptionCode"), sExceptionCode, root);
	}
	else if(m_CrashInfo.m_nExceptionType==CR_CPP_SIGFPE)
	{
		CString sFPESubcode;
		sFPESubcode.Format(_T("%d"), m_CrashInfo.m_uFPESubcode);
		AddElemToXML(_T("FPESubcode"), sFPESubcode, root);
	}
	else if(m_CrashInfo.m_nExceptionType==CR_CPP_INVALID_PARAMETER)
	{
		AddElemToXML(_T("InvParamExpression"), m_CrashInfo.m_sInvParamExpr, root);
		AddElemToXML(_T("InvParamFunction"), m_CrashInfo.m_sInvParamFunction, root);
		AddElemToXML(_T("InvParamFile"), m_CrashInfo.m_sInvParamFile, root);

		CString sInvParamLine;
		sInvParamLine.Format(_T("%d"), m_CrashInfo.m_uInvParamLine);
		AddElemToXML(_T("InvParamLine"), sInvParamLine, root);
	}

	CString sGuiResources;
	sGuiResources.Format(_T("%d"), eri.GetGuiResourceCount());
	AddElemToXML(_T("GUIResourceCount"), sGuiResources, root);

	CString sProcessHandleCount;
	sProcessHandleCount.Format(_T("%d"), eri.GetProcessHandleCount());
	AddElemToXML(_T("OpenHandleCount"), sProcessHandleCount, root);

	AddElemToXML(_T("MemoryUsageKbytes"), eri.GetMemUsage(), root);

	if(eri.GetScreenshotInfo().m_bValid)
	{
		TiXmlHandle hScreenshotInfo = new TiXmlElement("ScreenshotInfo");
		root->LinkEndChild(hScreenshotInfo.ToNode());

		TiXmlHandle hVirtualScreen = new TiXmlElement("VirtualScreen");    

		sNum.Format(_T("%d"), eri.GetScreenshotInfo().m_rcVirtualScreen.left);
		hVirtualScreen.ToElement()->SetAttribute("left", strconv.t2utf8(sNum));

		sNum.Format(_T("%d"), eri.GetScreenshotInfo().m_rcVirtualScreen.top);
		hVirtualScreen.ToElement()->SetAttribute("top", strconv.t2utf8(sNum));

		sNum.Format(_T("%d"), eri.GetScreenshotInfo().m_rcVirtualScreen.Width());
		hVirtualScreen.ToElement()->SetAttribute("width", strconv.t2utf8(sNum));

		sNum.Format(_T("%d"), eri.GetScreenshotInfo().m_rcVirtualScreen.Height());
		hVirtualScreen.ToElement()->SetAttribute("height", strconv.t2utf8(sNum));

		hScreenshotInfo.ToNode()->LinkEndChild(hVirtualScreen.ToNode());

		TiXmlHandle hMonitors = new TiXmlElement("Monitors");
		hScreenshotInfo.ToElement()->LinkEndChild(hMonitors.ToNode());                  

		size_t i;
		for(i=0; i<eri.GetScreenshotInfo().m_aMonitors.size(); i++)
		{ 
			MonitorInfo& mi = eri.GetScreenshotInfo().m_aMonitors[i];      
			TiXmlHandle hMonitor = new TiXmlElement("Monitor");

			sNum.Format(_T("%d"), mi.m_rcMonitor.left);
			hMonitor.ToElement()->SetAttribute("left", strconv.t2utf8(sNum));

			sNum.Format(_T("%d"), mi.m_rcMonitor.top);
			hMonitor.ToElement()->SetAttribute("top", strconv.t2utf8(sNum));

			sNum.Format(_T("%d"), mi.m_rcMonitor.Width());
			hMonitor.ToElement()->SetAttribute("width", strconv.t2utf8(sNum));

			sNum.Format(_T("%d"), mi.m_rcMonitor.Height());
			hMonitor.ToElement()->SetAttribute("height", strconv.t2utf8(sNum));

			hMonitor.ToElement()->SetAttribute("file", strconv.t2utf8(Utility::GetFileName(mi.m_sFileName)));

			hMonitors.ToElement()->LinkEndChild(hMonitor.ToNode());                  
		}

		TiXmlHandle hWindows = new TiXmlElement("Windows");
		hScreenshotInfo.ToElement()->LinkEndChild(hWindows.ToNode());                  

		for(i=0; i<eri.GetScreenshotInfo().m_aWindows.size(); i++)
		{ 
			WindowInfo& wi = eri.GetScreenshotInfo().m_aWindows[i];      
			TiXmlHandle hWindow = new TiXmlElement("Window");

			sNum.Format(_T("%d"), wi.m_rcWnd.left);
			hWindow.ToElement()->SetAttribute("left", strconv.t2utf8(sNum));

			sNum.Format(_T("%d"), wi.m_rcWnd.top);
			hWindow.ToElement()->SetAttribute("top", strconv.t2utf8(sNum));

			sNum.Format(_T("%d"), wi.m_rcWnd.Width());
			hWindow.ToElement()->SetAttribute("width", strconv.t2utf8(sNum));

			sNum.Format(_T("%d"), wi.m_rcWnd.Height());
			hWindow.ToElement()->SetAttribute("height", strconv.t2utf8(sNum));

			hWindow.ToElement()->SetAttribute("title", strconv.t2utf8(wi.m_sTitle));

			hWindows.ToElement()->LinkEndChild(hWindow.ToNode());                  
		}
	}

	TiXmlHandle hCustomProps = new TiXmlElement("CustomProps");
	root->LinkEndChild(hCustomProps.ToNode());

	int i;
	for(i=0; i<eri.GetPropCount(); i++)
	{ 
		CString sName;
		CString sVal;
		eri.GetPropByIndex(i, sName, sVal);

		TiXmlHandle hProp = new TiXmlElement("Prop");

		hProp.ToElement()->SetAttribute("name", strconv.t2utf8(sName));
		hProp.ToElement()->SetAttribute("value", strconv.t2utf8(sVal));

		hCustomProps.ToElement()->LinkEndChild(hProp.ToNode());                  
	}

	TiXmlHandle hFileItems = new TiXmlElement("FileList");
	root->LinkEndChild(hFileItems.ToNode());

	for(i=0; i<eri.GetFileItemCount(); i++)
	{    
		ERIFileItem* rfi = eri.GetFileItemByIndex(i);
		TiXmlHandle hFileItem = new TiXmlElement("FileItem");

		hFileItem.ToElement()->SetAttribute("name", strconv.t2utf8(rfi->m_sDestFile));
		hFileItem.ToElement()->SetAttribute("description", strconv.t2utf8(rfi->m_sDesc));
		if(rfi->m_bAllowDelete)
			hFileItem.ToElement()->SetAttribute("optional", "1");
		if(!rfi->m_sErrorStatus.IsEmpty())
			hFileItem.ToElement()->SetAttribute("error", strconv.t2utf8(rfi->m_sErrorStatus));

		hFileItems.ToElement()->LinkEndChild(hFileItem.ToNode());                  
	}

#if _MSC_VER<1400
	f = _tfopen(sFileName, _T("w"));
#else
	_tfopen_s(&f, sFileName, _T("w"));
#endif

	if(f==NULL)
	{
		sErrorMsg = _T("Error opening file for writing");
		goto cleanup;
	}

	doc.useMicrosoftBOM = true;
	bool bSave = doc.SaveFile(f); 
	if(!bSave)
	{
		sErrorMsg = doc.ErrorDesc();
		goto cleanup;
	}

	fclose(f);
	f = NULL;

	bStatus = TRUE;

cleanup:

	if(f)
		fclose(f);

	if(!bStatus)
	{
		eri.GetFileItemByName(fi.m_sDestFile)->m_sErrorStatus = sErrorMsg;
	}

	return bStatus;
}