/*------------------------------------------------------------------------ $Workfile: $ $Archive: $ $Revision: $ $Date: $ Description: Copyright ? 2007 Exent Technologies Ltd. ------------------------------------------------------------------------*/ #include "stdafx.h" #pragma hdrstop #define ACONTENTPUSHMGR_CPP #define LOGGER_TYPE_FILE_CODE LOGGER_TYPE_FILE_CONTENT_PUSH_MGR #define XML_VERIFY_MOD L"g1sT7M/oxJ7JSwaN7i1aMtW0B1R6+4IVlpjfQrlLtoxIktn/w8UaLhJrMCC3MghjrrtybJKJkitS 204pwywziIT/pzHtYQDYf6VEYn4sPJxYovioGJz6zDzA+utQgyt7wNyMhe/6KYKHush1tIMcp4gt vqomDy9ZcRik//WvWFU=" #define XML_VERIFY_EXP L"AQAB" #include "UnitInclude.h" AContentPushMgr::AContentPushMgr() { m_bInit = false; m_pContentPushCBObj = NULL; m_ProviderId = NULL; m_dwIntervalForRetryOperationInSec = NULL; m_pIInstalledContentsControler = NULL; m_strProxy.erase(); } /*------------------------------------------------------------------------ AContentPushMgr::Init() Description: Parameters: wstrInfoPath = wstring providerID = PROVIDERID dwIntervalForRetryOperationInSec = DWORD pIInstalledContentsControler = IInstalledContentsControler* pContentPushCBObj = IContentPushMgrCB* Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::Init(wstring wstrInfoPath, PROVIDERID providerID, DWORD dwIntervalForRetryOperationInSec, string strProxy, IInstalledContentsControler* pIInstalledContentsControler, IContentPushMgrCB* pContentPushCBObj) { if (m_bInit) Term(); BOOL bRes = m_TimingNotificationMutex.Create( FALSE, NULL, NULL ); if( !bRes ) { DoLogEx( AERR, AClientSDKErrIDs::CREATE_MUTEX_ERR, "" ); return false; } m_bInit = true; m_pContentPushCBObj = pContentPushCBObj; m_ProviderId = providerID; m_dwIntervalForRetryOperationInSec = dwIntervalForRetryOperationInSec; m_pIInstalledContentsControler = pIInstalledContentsControler; m_strProxy = strProxy; // Check if ContentPushMgr has already run successfully if (IsAlreadyRunSuccessfully()) return true; // Format the AIG's file name WCHAR fileName[MAX_PATH]; swprintf( fileName, AIG_FILE_NAME, m_ProviderId ); m_wstrAIGXmlFileName = wstrInfoPath + fileName; // Initiate timer for doing the main logic (fetching XML, add to download list). // First time, we do it immediately, and then once in "dwIntervalForRetryOperation", DWORD dwFirstTimeIntervalInSec; if (false == GetFirstTimeDelayInterval(dwFirstTimeIntervalInSec)) { dwFirstTimeIntervalInSec = INTERVAL_FOR_FIRST_TIME_IN_SEC; } m_pNotificationsTimer = new Exent::Util::TimerThread(dwFirstTimeIntervalInSec*1000, true); m_pNotificationsTimer->Register(this); m_pNotificationsTimer->ReStart(); return true; } /*------------------------------------------------------------------------ AContentPushMgr::~AContentPushMgr() Description: ------------------------------------------------------------------------*/ AContentPushMgr::~AContentPushMgr() { Term(); } /*------------------------------------------------------------------------ AContentPushMgr::Term() Description: ------------------------------------------------------------------------*/ void AContentPushMgr::Term() { if (!IsInit()) return; AMutexLock lock( &m_TimingNotificationMutex ); if( !lock.Wait(CP_MGR_MUTEX_WAIT_TIME_FOR_TERM) ) { DoLogEx( AERR, AClientSDKErrIDs::WAIT_ON_LOCK_ERR,"" ); } // First, cancel the current Http Connection, Then Terminate the timer thread. if (m_pNotificationsTimer) { m_pNotificationsTimer->Pause(); } CancelCurrentHttpConnection(); if (m_pNotificationsTimer!=NULL) { m_pNotificationsTimer->UnRegister(this); m_pNotificationsTimer->Close(); delete m_pNotificationsTimer; m_pNotificationsTimer = NULL; } m_TimingNotificationMutex.Destroy(); m_bInit = false; } /*------------------------------------------------------------------------ AContentPushMgr::IsAlreadyRunSuccessfully() Description: Check if the ContentPush module has already run successfully, by checking the corresponding registry key Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::IsAlreadyRunSuccessfully() { bool bRes = false; bool bRet; ISettingsDB* pSDB = NULL; ISettingsMgr* pSMgr = ISettingsMgrFactory::GetInstance(); if ( pSMgr == NULL ) return false; pSDB = pSMgr->GetInstance( "", m_ProviderId ); if ( pSDB == NULL ) return false; bRes = pSDB->GetSetting(PROVIDER_SETTING_CONTENT_PUSH_ALREADY_RUN_SUCCESSFULLY, bRet); if(!bRes) { return false; } return bRet; } /*------------------------------------------------------------------------ GetFirstTimeDelayInterval() Description: Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::GetFirstTimeDelayInterval(DWORD &dwInterval) { bool bRes = false; ISettingsDB* pSDB = NULL; ISettingsMgr* pSMgr = ISettingsMgrFactory::GetInstance(); if ( pSMgr == NULL ) return false; pSDB = pSMgr->GetInstance( "", m_ProviderId ); if ( pSDB == NULL ) return false; bRes = pSDB->GetSetting(PROVIDER_SETTING_CONTENT_PUSH_FIRST_TIME_DELAY_IN_SEC, dwInterval); if(!bRes) { return false; } return bRes; } /*------------------------------------------------------------------------ AContentPushMgr::CheckContentPushContentsState() Description: Loop over all current provider's installed contents. we check for contents that aren't AIG contents, or AIG's contents that already been downloded. Returns: CONTENTS_STATE_ON_DISK ------------------------------------------------------------------------*/ CONTENTS_STATE_ON_DISK AContentPushMgr::CheckContentPushContentsState() { list ContentsList; list::iterator ContentsListIter; AClientSDKErrIDs::ERROR_ID ErrId = AClientSDKErrIDs::ERR_SUCCESS; CONTENTID ContentId; INSTALLED_CONTENT_INFO ContentInfo; bool bFound = false; // Get a pointer to ICC if(!m_pIInstalledContentsControler) { return GENERAL_ERROR; } // Get the content list. ErrId = m_pIInstalledContentsControler->GetInstalledContentsIdsList(ContentsList); if(ErrId != AClientSDKErrIDs::ERR_SUCCESS) { return GENERAL_ERROR; } // Loop over the contents and find contents off the current provider for (ContentsListIter = ContentsList.begin() ; ContentsListIter != ContentsList.end() ; ++ContentsListIter) { ContentId = *ContentsListIter; ErrId = m_pIInstalledContentsControler->GetInstalledContentInfo(ContentId, m_ProviderId, false, ContentInfo); string content_name = ContentInfo.BasicContentInfo.strExentName; if(ErrId == AClientSDKErrIDs::ERR_SUCCESS && !(ContentInfo.dwStatus & CONTENT_STATUS_ERR_PROVIDER_DOESNOT_EXIST)) { // If the content is not an AIG's content, we stop. if (m_AigContentsMap.find(ContentId) == m_AigContentsMap.end()) { return NOT_AIG_CONTENT_EXIST; } //Update AIG's map, if the content found in it m_AigContentsMap[ContentId] = true; } } // Loop over the AIG's map, and search for contents that have'nt downloaded yet. AIG_MAP::iterator it; for (it=m_AigContentsMap.begin(); it!=m_AigContentsMap.end(); ++it) { if ((*it).second == false) { return NOT_ALL_AIG_CONTENTS_EXIST; } } return ALL_AIG_CONTENTS_EXIST; } /*------------------------------------------------------------------------ AContentPushMgr::TimingNotification() Description: CB function of the timer. 1. If XML dosn't exists - fetch it. 2. Get directions for relevan contents Parameters: dwThreadID = DWORD ------------------------------------------------------------------------*/ void AContentPushMgr::TimingNotification(DWORD dwThreadID) { bool bRet; AMutexLock lock( &m_TimingNotificationMutex ); if( !lock.Wait(CP_MGR_MUTEX_WAIT_TIME) ) { DoLogEx( AERR, AClientSDKErrIDs::WAIT_ON_LOCK_ERR,"" ); return; } m_pNotificationsTimer->Pause(); // Check if AIG's XML already exists if (!IsAIGsXmlFileExistsWithContents()) { string strUrl; bRet = GetUrlForAIGXmlFile(strUrl); if (!bRet) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_CANNOT_RETRIVE_AIG_XML_URL, ""); return; } bRet = FetchXml(strUrl, m_wstrAIGXmlFileName); if (!bRet) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_CANNOT_RETRIVE_AIG_LIST, ""); m_pNotificationsTimer->ReStart(m_dwIntervalForRetryOperationInSec*1000); return; } } bRet = CheckSignature(); if (!bRet) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_XML_SIGNATURE_INVALID, ""); return; } bRet = GetDSUrl(m_strDSUrl); if (!bRet) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_XML_PARSING_ERROR, ""); return; } bRet = UpdateContentsMap(); if (!bRet) { m_pNotificationsTimer->ReStart(m_dwIntervalForRetryOperationInSec*1000); DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_XML_PARSING_ERROR, ""); return; } if (CheckContentPushContentsState() != NOT_ALL_AIG_CONTENTS_EXIST) { m_pNotificationsTimer->Pause(); SetAlreadyRunSuccessfullyFlag(); return; } bRet = GetDirectionsForRelevantContents(); if (!bRet) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_FAILED_TO_GET_DIRECTIONS, ""); m_pNotificationsTimer->ReStart(m_dwIntervalForRetryOperationInSec*1000); return; } m_pNotificationsTimer->ReStart(m_dwIntervalForRetryOperationInSec*1000); } /*------------------------------------------------------------------------ AContentPushMgr::TimerStopped() Description: Parameters: dwThreadID = DWORD ------------------------------------------------------------------------*/ void AContentPushMgr::TimerStopped(DWORD dwThreadID) { } /*------------------------------------------------------------------------ AContentPushMgr::SetAlreadyRunSuccessfullyFlag() Description: Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::SetAlreadyRunSuccessfullyFlag() { bool bRes = false; ISettingsDB* pSDB = NULL; ISettingsMgr* pSMgr = ISettingsMgrFactory::GetInstance(); if ( pSMgr == NULL ) return false; pSDB = pSMgr->GetInstance( "", m_ProviderId ); if ( pSDB == NULL ) return false; bRes = pSDB->SetBaseSetting(PROVIDER_SETTING_CONTENT_PUSH_ALREADY_RUN_SUCCESSFULLY, true); if(!bRes) { return false; } return true; } /*------------------------------------------------------------------------ AContentPushMgr::OnSucceed() Description: CB function for IGetDirections success. Parameters: dwContext = DWORD wstrDirectionsAsString = std::wstring& ------------------------------------------------------------------------*/ void AContentPushMgr::OnSucceed(DWORD dwContext, std::wstring& wstrDirectionsAsString) { string strDirections; bool bRet; ABinConverter::WStringToString(wstrDirectionsAsString, strDirections); bRet = m_pContentPushCBObj->CP_AddGameToDownloadList((CONTENTID)dwContext, m_ProviderId, false, strDirections, (DWORD)-1); // Updating content state as downloaded. if (bRet == true) { m_AigContentsMap[(CONTENTID)dwContext] = true; } // Check if all games have already downloded successfully if (CheckContentPushContentsState() != NOT_ALL_AIG_CONTENTS_EXIST) { m_pNotificationsTimer->Pause(); SetAlreadyRunSuccessfullyFlag(); } } /*------------------------------------------------------------------------ AContentPushMgr::OnFail() Description: CB function for IGetDirections failure. Parameters: dwContext = DWORD err = GETDIRECTIONS_ERRORCODE dwInfo = DWORD pwszLastError = const WCHAR* ------------------------------------------------------------------------*/ void AContentPushMgr::OnFail(DWORD dwContext,GETDIRECTIONS_ERRORCODE err, DWORD dwInfo, const WCHAR* pwszLastError) { // If the content need authentication, or dosn't exist, remove it from CP's map if (err == GETDIRECTIONS_AUTENTICATION_FAILED || err == GETDIRECTIONS_GAME_NOT_AVAILABLE) { AIG_MAP::iterator it ; it = m_AigContentsMap.find((CONTENTID)dwContext); if (it != m_AigContentsMap.end()) { m_AigContentsMap.erase(it); } if (err == GETDIRECTIONS_AUTENTICATION_FAILED) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_NOT_DEMO_CONTENT_EXISTS, ""); } if (err == GETDIRECTIONS_GAME_NOT_AVAILABLE) { DoLogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::CONTENT_PUSH_MGR_CONTENT_ISNT_AVAILBLE, ""); } } } /*------------------------------------------------------------------------ AContentPushMgr::IsAIGsXmlFileExistsWithContents() Description: Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::IsAIGsXmlFileExistsWithContents() { AXMLReader XMLReader; // Load the xml from file. if(!XMLParser::LoadXmlFromFile(m_wstrAIGXmlFileName , XMLReader)) { // File doesn't exists return false; } // parsing.. wstring wstrAttribName(L""); CBasicStringConv cbsOut(""); DWORD dwOut = 0; try { AXMLREADER_LIST itemList; AXMLREADER_LIST::iterator itemListIter; if(!XMLReader.XPathGetNodes(L"//cp:aig",OUT itemList)) { return false; } if(itemList.empty()) { DoLogEx(ADBG, AClientSDKErrIDs::XML_GET_NODE_ERR, "%S", L"//cp:aig"); return false; } for(itemListIter=itemList.begin();itemListIter!=itemList.end();itemListIter++) { AXMLReader readerItem = *itemListIter; wstrAttribName = L"cp:contentid"; if(!readerItem.findAttribute(wstrAttribName, OUT cbsOut, L"")) { // Empty list DoLogEx(AERR, AClientSDKErrIDs::XML_FIND_ATTRIBUTE_ERR, "%S",L"cp:contentid"); return false; } // Not empty list return true; } } catch(_com_error comerr) { DoLogEx( AERR, AClientSDKErrIDs::XML_COM_ERR, "%d %s",comerr.Error, comerr.Description()); return false; } return false; } /*------------------------------------------------------------------------ AContentPushMgr::CancelCurrentHttpConnection() Description: ------------------------------------------------------------------------*/ void AContentPushMgr::CancelCurrentHttpConnection() { m_HttpConnection.Cancel(); if ( m_HttpConnection.IsConnected() ) { m_HttpConnection.Disconnect(); } if (m_pIGetDirections) { m_pIGetDirections->CancelAllRequests(0); } } /*------------------------------------------------------------------------ AContentPushMgr::GetUrlForAIGXmlFile() Description: Parameters: strUrl = string& Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::GetUrlForAIGXmlFile(string& strUrl) { bool bRes = false; ISettingsDB* pSDB = NULL; ISettingsMgr* pSMgr = ISettingsMgrFactory::GetInstance(); if ( pSMgr == NULL ) return false; pSDB = pSMgr->GetInstance( "", m_ProviderId ); if ( pSDB == NULL ) return false; bRes = pSDB->GetSetting(PROVIDER_SETTING_CONTENT_PUSH_AIG_LIST_URL, strUrl); if(!bRes) { return false; } // Concat MUID to the URL std::string::size_type pos = strUrl.find("?"); if (pos == std::string::npos) strUrl += "?"; else strUrl += "&"; strUrl += CONTENT_PUSH_AIG_MUID_TAG + ASystem::GetRandMuidString(); return true; } /*------------------------------------------------------------------------ AContentPushMgr::GetDSUrl() Description: Retrieve the DirectionsSupplier URL from the XML Parameters: strDSUrl = string& Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::GetDSUrl(string& strDSUrl) { AXMLReader XMLReader; CBasicStringConv tmpString(""); string strUrl; // Load the xml from file. if(!XMLParser::LoadXmlFromFile(m_wstrAIGXmlFileName , XMLReader)) { return false; } if(!XMLReader.XPathGetSingleNodeValue(L"//cp:dsurl",tmpString)) { return false; } strUrl = tmpString.AsString(); // Add "track=AIG" to the url for server tracking std::string::size_type pos = strUrl.find("?"); if (pos == std::string::npos) strDSUrl = strUrl + "?"; else strDSUrl = strUrl + "&"; strDSUrl += CONTENT_PUSH_AIG_TRACKING_TAG; return true; } /*------------------------------------------------------------------------ AContentPushMgr::UpdateContentsMap() Description: Parse the XML and update the contents map with AIG's contents Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::UpdateContentsMap() { AXMLReader XMLReader; // Load the xml from file. if(!XMLParser::LoadXmlFromFile(m_wstrAIGXmlFileName , XMLReader)) { return false; } // parsing.. wstring wstrAttribName(L""); CBasicStringConv cbsOut(""); DWORD dwOut = 0; try { AXMLREADER_LIST itemList; AXMLREADER_LIST::iterator itemListIter; if(!XMLReader.XPathGetNodes(L"//cp:aig",OUT itemList)) { return false; } if(itemList.empty()) { DoLogEx(ADBG, AClientSDKErrIDs::XML_GET_NODE_ERR, "%S", L"//cp:aig"); return false; } for(itemListIter=itemList.begin();itemListIter!=itemList.end();itemListIter++) { AXMLReader readerItem = *itemListIter; wstrAttribName = L"cp:contentid"; if(!readerItem.findAttribute(wstrAttribName, OUT cbsOut, L"")) { DoLogEx(AERR, AClientSDKErrIDs::XML_FIND_ATTRIBUTE_ERR, "%S",L"cp:contentid"); return false; } // Insert content to map (value does'nt matter right now) CONTENTID id = cbsOut.AsLong(); m_AigContentsMap[id] = 0; } } catch(_com_error comerr) { DoLogEx( AERR, AClientSDKErrIDs::XML_COM_ERR, "%d %s",comerr.Error, comerr.Description()); return false; } return true; } /*------------------------------------------------------------------------ AContentPushMgr::FetchXml() Description: Parameters: strUrl = string& wstrTargetLocalPath = wstring& Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::FetchXml( string& strUrl, wstring& wstrTargetLocalPath ) { DWORD dwBuffSize = 0; PBYTE pBuff = NULL; DWORD dwBytesWritten = 0; if ( !GetFileFromUrlToBuffer( strUrl, pBuff, dwBuffSize ) ) { /*LogEx( AERR, AClientSDKErrIDs::ContentPushMgrLib::FAILED_TO_DOWNLOAD_UPDATES , "%S", m_HttpConnection.GetError() ); */ return false; } HANDLE hFile = CreateFileW( wstrTargetLocalPath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) { DoLogEx( AERR, AClientSDKErrIDs::CREATE_FILE_ERROR, "%S %d", wstrTargetLocalPath.c_str(), GetLastError() ); return false; } BOOL bRes = WriteFile( hFile, pBuff, dwBuffSize, &dwBytesWritten, NULL ); if( !bRes ) { DoLogEx( AERR, AClientSDKErrIDs::WRITE_FILE_ERROR, "%S %d", wstrTargetLocalPath.c_str(), GetLastError() ); CloseHandle(hFile); return false; } CloseHandle(hFile); return true; } /*------------------------------------------------------------------------ AContentPushMgr::GetFileFromUrlToBuffer() Description: buffer is allocated in function & must deallocated outside if the function returns true Parameters: strUrl = IN const string& pBuffer = OUT PBYTE dwBufferSize = OUT DWORD& Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::GetFileFromUrlToBuffer( IN const string& strUrl, OUT PBYTE& pBuffer, OUT DWORD& dwBufferSize ) { if ( strUrl.empty() ) { return false; } pBuffer = NULL; bool bRet; BYTE dummyBuffer[1]={NULL}; DWORD dwRequiredBufferSize = sizeof(dummyBuffer)/sizeof(BYTE); bRet = m_HttpConnection.GetFromFullUrl( strUrl, dummyBuffer ,dwRequiredBufferSize, m_strProxy); if(!bRet) { return false; } //We should look what is the required buffer size. if( !m_HttpConnection.GetLastResponse( NULL, dwRequiredBufferSize ) ) { return false; } if ( dwRequiredBufferSize <= 0 ) { return false; } // Allocate response buffer. // Adding 1 because of a bug in HttpConnection::GetLastResponse //dwRequiredBufferSize; pBuffer = new BYTE [dwRequiredBufferSize]; if(NULL == pBuffer) { return false; } ZeroMemory(pBuffer, dwRequiredBufferSize); dwRequiredBufferSize++; if( !m_HttpConnection.GetLastResponse( pBuffer, dwRequiredBufferSize ) ) { delete [] pBuffer; pBuffer = NULL; return false; } dwBufferSize = dwRequiredBufferSize; return true; } /*------------------------------------------------------------------------ AContentPushMgr::GetDirectionsForRelevantContents() Description: Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::GetDirectionsForRelevantContents() { bool bRes; m_pIGetDirections = IGetDirectionsFactory::Create(); if(!m_pIGetDirections) { DoLogEx(AERR,AClientSDKErrIDs::FACTORY_CREATE_ERR,""); return false; } // Init get direction object. bRes = m_pIGetDirections->Init(m_strProxy); if(!bRes) { DoLogEx(AERR,AClientSDKErrIDs::INIT_OBJECT_ERR,""); return false; } AIG_MAP::const_iterator it; for (it=m_AigContentsMap.begin(); it!=m_AigContentsMap.end(); ++it) { // Check if the content has already downloaded if ((*it).second == true) { continue; } bRes = m_pIGetDirections->GetDirectionsAsync(m_strDSUrl, (*it).first, 1, ASystem::GetRandMuidString(), L"", L"", DIRECTIONS_TYPE_DOWNLOAD, NULL, this, (DWORD)((*it).first)); if(!bRes) { DoLogEx(AERR,AClientSDKErrIDs::GUI::GetRgmx::GET_DIRECTIONS_ASYNC_ERR,"%d %d %s %S", (*it).first, 1, m_strDSUrl.c_str(), L""); return false; } } return true; } /*------------------------------------------------------------------------ AContentPushMgr::IsAigContent() Description: Parameters: contentId = CONTENTID Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::IsAigContent(CONTENTID contentId) { AIG_MAP::iterator it; it = m_AigContentsMap.find(contentId); if (it != m_AigContentsMap.end()) return true; else return false; } /*------------------------------------------------------------------------ AContentPushMgr::CheckSignature() Description: Check the AIGXML signature Returns: True if successful ------------------------------------------------------------------------*/ bool AContentPushMgr::CheckSignature() { IXmlRSASignatureValidator* pValidator = NULL; XML_SIGNATURE_ERR Err = XML_SIGNATURE_OK; bool bRes = true; // Creat the validator. pValidator = IXMLEncryptionLibFactory::CreateRSAValidator(); if(!pValidator) { return false; } try { bRes = pValidator->LoadFromFile(m_wstrAIGXmlFileName); if(!bRes) { bRes = false; throw(""); } // Set the sign key. Err = pValidator->SetSigningPublicKey(XML_VERIFY_MOD, XML_VERIFY_EXP); if(Err != XML_SIGNATURE_OK) { bRes = false; throw(""); } // Validate the signature. Err = pValidator->Validate(); if(Err != XML_SIGNATURE_OK) { bRes = false; throw(""); } // Clean the validator object. if(pValidator) { if(pValidator->IsLoaded()) { pValidator->Unload(); } IXMLEncryptionLibFactory::Release(pValidator); pValidator = NULL; } } catch(...) { bRes = false; } return bRes; }