BOOL COCSInventoryState::WriteToFile(LPCTSTR lpstrFilename, LPCTSTR lpstrSection)
{
	CMarkup	myXml;
	TiXmlElement *pNode, *pTemp;

	// Load current state file
	if (myXml.LoadFile( lpstrFilename))
	{
		// File already exists, so remove existing section from XML 
		myXml.ResetPos();
		pNode = myXml.FindFirstElem( lpstrSection);
		while (pNode)
		{
			pTemp = pNode;
			pNode = myXml.FindNextElem( lpstrSection, pTemp);
			myXml.DeleteElem( pTemp);
		}
	}
	// Add new section
	myXml.ResetPos();
	if (!FormatXML( &myXml, lpstrSection))
		return FALSE;
	// Save state file
	if (!myXml.SaveFile( lpstrFilename))
		return FALSE;
	return TRUE;
}
BOOL COCSInventoryState::ReadFromFile(LPCTSTR lpstrFilename, LPCTSTR lpstrSection)
{
	CMarkup	myXml;

	// Fill Device hardware properties from string
	if (!myXml.LoadFile( lpstrFilename))
		return FALSE;
	if (!ParseFromXML( &myXml, lpstrSection))
		return FALSE;
	return TRUE;
}
int COptDownloadPackage::downloadInfoFile()
{
	CConfig				*pAgentConfig = getAgentConfig();
	CComProvider		*pProvider = getComServerProvider();
	CServerConfig		*pServerConfig = pProvider->newConfig();
	CConnexionAbstract	*pConnexion = NULL;
	TCHAR				szDummy[_MAX_PATH + 1];

	ASSERT(pAgentConfig);
	ASSERT(pProvider);
	ASSERT(pServerConfig);

	// Create provider connection object using default Provider configuration
	if ((pConnexion = pProvider->newConnexion(pServerConfig)) == NULL)
	{
		m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed creating connection for Communication Provider <%s>"), pAgentConfig->getCommunicationProvider());
		pProvider->deleteConfig(pServerConfig);
		return FALSE;
	}
	// Download metadata info file
	m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Metadata file <info> for package <%s> is located at <%s>"), m_csId, getRemoteMetadataURL());
	if (!pConnexion->getFile(getRemoteMetadataURL(), getLocalMetadataFilename()))
	{
		m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed to download Metadata file <%s> to <%s>"), getRemoteMetadataURL(), getLocalMetadataFilename());
		pProvider->deleteConnexion(pConnexion);
		pProvider->deleteConfig(pServerConfig);
		return FALSE;
	}
	m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Unloading communication provider"));
	// Use provider to delete connexion and server config
	pProvider->deleteConnexion(pConnexion);
	pProvider->deleteConfig(pServerConfig);

	// Open metadata file to add fragment location
	CString csBuffer;
	CMarkup xml;
	if (!xml.LoadFile(getLocalMetadataFilename()))
	{
		m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot read or parse Metadata file <%s>"), getLocalMetadataFilename());
		return FALSE;
	}
	// Add fragment location to meta data
	xml.FindFirstElem(_T("DOWNLOAD"));
	xml.SetAttrib(_T("LOC"), m_csRemotePackLoc);
	// Add package schedule to meta data
	xml.SetAttrib(_T("SCHEDULE"), m_csSchedule);
	// Add post execution command to meta data
	xml.SetAttrib(_T("POSTCMD"), m_csPostCmd);
	// Write meta data file
	if (!xml.SaveFile(getLocalMetadataFilename()))
	{
		m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't update Metadata file <%s>"), getLocalMetadataFilename());
		return FALSE;
	}
	// Compute digest on meta data and add it to Registry
	if (!fileDigest(getLocalMetadataFilename(), csBuffer))
	{
		m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't register package <%s> into Registry"), m_csId);
		DeleteFile(getLocalMetadataFilename());
		return FALSE;
	}
	if (!regAddPackageDigest(m_csId, csBuffer))
	{
		m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't register package <%s> into Registry"), m_csId);
		DeleteFile(getLocalMetadataFilename());
		return FALSE;
	}
	// Now create a timestamp 
	csBuffer.Format(_T("%s\\%s\\%s"), getDownloadFolder(), m_csId, OCS_DOWNLOAD_TIMESTAMP);
	if (!fileExists(csBuffer))
	{
		_ltot(time(NULL), szDummy, 10);
		if (!WriteTextToFile(szDummy, csBuffer))
			m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't create timestamp file <%s>"), csBuffer);
	}
	else
		m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Timestamp file <%s> already exists"), csBuffer);
	m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Retrieve info file...OK (pack %s)"), m_csId);
	return TRUE;
}
BOOL CPackage::load( LPCTSTR lpstrFile)
{
	CString csBuffer;
	CMarkup myXml;
	TCHAR	cPath[_MAX_PATH], 
			cCommand[255];

	try
	{
		// Load "info" file content
		if (!myXml.LoadFile( lpstrFile))
			return FALSE;
		myXml.ResetPos();
		if (!myXml.FindFirstElem( _T( "DOWNLOAD")))
			return FALSE;
		m_csID = myXml.GetAttrib( _T( "ID"));
		csBuffer = myXml.GetAttrib( _T( "PRI"));
		if (csBuffer.IsEmpty())
			return FALSE;
		m_uPriority = _ttoi( csBuffer);
		m_csAction = myXml.GetAttrib( _T( "ACT"));
		m_csName = myXml.GetAttrib( _T( "NAME"));
		m_csDigest = myXml.GetAttrib( _T( "DIGEST"));
		m_csLocation = myXml.GetAttrib( _T( "LOC"));
		m_csProtocol = myXml.GetAttrib( _T( "PROTO"));
		csBuffer = myXml.GetAttrib( _T( "FRAGS"));
		if (csBuffer.IsEmpty())
			return FALSE;
		m_uFrags = _ttoi( csBuffer);
		m_csDigestAlgo = myXml.GetAttrib( _T( "DIGEST_ALGO"));
		m_csDigestAlgo.MakeLower();
		m_csDigestEncode = myXml.GetAttrib( _T( "DIGEST_ENCODE"));
		m_csDigestEncode.MakeLower();

		if (m_csAction == OCS_DOWNLOAD_ACTION_STORE)
		{
			// Store only action, get path where to store data
			if( !ExpandEnvironmentStrings( myXml.GetAttrib( _T( "PATH")), cPath, _MAX_PATH ))
			{
				return FALSE;
			}
			else
			{
				m_csPath = cPath;
				m_csPath.Replace( _T( "/"), _T( "\\"));
				m_csPath.Replace( _T( "INSTALL_PATH"), getInstallFolder());
			}
		}
		else
		{
			// Put into path tmp folder to unzip package
			if (GetTempPath( _MAX_PATH, m_csPath.GetBufferSetLength( _MAX_PATH+1)) == 0)
				return FALSE;
			m_csPath.ReleaseBuffer();
			m_csPath.AppendFormat( _T( "\\%s.OCS"), m_csID);
		}

		if (m_csAction == OCS_DOWNLOAD_ACTION_LAUNCH)
		{
			// In LAUNCH, command is in the NAME atribute
			if( !ExpandEnvironmentStrings( m_csName, cCommand, 255 ))
			{
				return FALSE;
			}
			else
			{
				m_csCommand = cCommand;
				m_csCommand.Replace( _T( "INSTALL_PATH"), getInstallFolder());
			}
		}
		else
		{
			// In Store or Execute mode, command is in the COMMAND attribute
			if( !ExpandEnvironmentStrings( myXml.GetAttrib( _T( "COMMAND")), cCommand, 255 ))
			{
				return FALSE;
			}
			else
			{
				m_csCommand = cCommand;
				m_csCommand.Replace( _T( "INSTALL_PATH"), getInstallFolder());
			}
		}
		m_csGardeFou = myXml.GetAttrib( _T( "GARDEFOU"));
		
		/* User notification */
		csBuffer = myXml.GetAttrib( _T( "NOTIFY_USER"));
		// Ensure non empty value
		if (!csBuffer.IsEmpty())
			m_bNotifyUser = (_ttoi( csBuffer) != 0);
		else
			m_bNotifyUser = FALSE;
		if (m_bNotifyUser)
		{
			csBuffer = myXml.GetAttrib( _T( "NOTIFY_COUNTDOWN"));
			// Ensure non empty value
			if (csBuffer.IsEmpty())
				csBuffer = COMMAND_TIMEOUT_DEFAULT;
			m_uNotifyCountdown = _ttoi( csBuffer);
			m_csNotifyText = myXml.GetAttrib( _T( "NOTIFY_TEXT"));
			if (myXml.GetAttrib( _T( "NOTIFY_CAN_ABORT")))
				m_bNotifyCanAbort = ( _ttoi( myXml.GetAttrib( _T( "NOTIFY_CAN_ABORT"))) != 0);
			else
				m_bNotifyCanAbort = FALSE;
			if (myXml.GetAttrib( _T( "NOTIFY_CAN_DELAY")))
				m_bNotifyCanDelay = ( _ttoi( myXml.GetAttrib( _T( "NOTIFY_CAN_DELAY"))) != 0);
			else
				m_bNotifyCanDelay = FALSE;
		}
		csBuffer = myXml.GetAttrib( _T( "NEED_DONE_ACTION"));
		// Ensure non empty value
		if (!csBuffer.IsEmpty())
			m_bNeedDoneAction = (_ttoi( csBuffer) != 0);
		else
			m_bNeedDoneAction = FALSE;
		if (m_bNeedDoneAction)
		{
			m_csNeedDoneActionText = myXml.GetAttrib( _T( "NEED_DONE_ACTION_TEXT"));
		}
		m_csSchedule = myXml.GetAttrib( _T( "SCHEDULE"));
		m_csPostCmd = myXml.GetAttrib( _T( "POSTCMD"));
	}
	catch( CException *pEx)
	{
		pEx->Delete();
		return FALSE;
	}
	return TRUE;
}