Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

603 lines
18 KiB

  1. /** Copyright (c) 2000 Microsoft Corporation
  2. ******************************************************************************
  3. ** Module Name:
  4. **
  5. ** UpdateHeadlines.cpp
  6. **
  7. ** Abstract:
  8. **
  9. ** Implementation of CUpdateHeadlines
  10. **
  11. ** Author:
  12. **
  13. ** Martha Arellano (t-alopez) 06-Dec-2000
  14. **
  15. **
  16. **
  17. ******************************************************************************
  18. **/
  19. #include "stdafx.h"
  20. //////////////////////////////////////////////////////////////////////
  21. // CONFIG MAP
  22. //////////////////////////////////////////////////////////////////////
  23. /*<?xml version="1.0" ?>
  24. <UPDATEHEADLINES>
  25. <LANGUAGE LCID="1033">
  26. <SKU VERSION="Personal">
  27. <HEADLINE ICON="" TITLE="" LINK="" EXPIRES=""/>
  28. </SKU>
  29. </LANGUAGE>
  30. </UPDATEHEADLINES>
  31. */
  32. CFG_BEGIN_FIELDS_MAP(News::UpdateHeadlines::Headline)
  33. CFG_ATTRIBUTE( L"ICON" , wstring, m_strIcon ),
  34. CFG_ATTRIBUTE( L"TITLE" , wstring, m_strTitle ),
  35. CFG_ATTRIBUTE( L"LINK" , wstring, m_strLink ),
  36. CFG_ATTRIBUTE( L"DESCRIPTION" , wstring, m_strDescription ),
  37. CFG_ATTRIBUTE( L"TIMEOUT" , DATE_CIM, m_dtTimeOut ),
  38. CFG_END_FIELDS_MAP()
  39. CFG_BEGIN_CHILD_MAP(News::UpdateHeadlines::Headline)
  40. CFG_END_CHILD_MAP()
  41. DEFINE_CFG_OBJECT(News::UpdateHeadlines::Headline, L"HEADLINE")
  42. DEFINE_CONFIG_METHODS__NOCHILD(News::UpdateHeadlines::Headline)
  43. ////////////////////
  44. CFG_BEGIN_FIELDS_MAP(News::UpdateHeadlines::SKU)
  45. CFG_ATTRIBUTE( L"VERSION", wstring, m_strSKU ),
  46. CFG_END_FIELDS_MAP()
  47. CFG_BEGIN_CHILD_MAP(News::UpdateHeadlines::SKU)
  48. CFG_CHILD(News::UpdateHeadlines::Headline)
  49. CFG_END_CHILD_MAP()
  50. DEFINE_CFG_OBJECT(News::UpdateHeadlines::SKU, L"SKU")
  51. DEFINE_CONFIG_METHODS_CREATEINSTANCE_SECTION(News::UpdateHeadlines::SKU,tag,defSubType)
  52. if(tag == _cfg_table_tags[0])
  53. {
  54. defSubType = &(*(m_vecHeadlines.insert( m_vecHeadlines.end() )));
  55. return S_OK;
  56. }
  57. DEFINE_CONFIG_METHODS_SAVENODE_SECTION(News::UpdateHeadlines::SKU,xdn)
  58. hr = MPC::Config::SaveList( m_vecHeadlines, xdn );
  59. DEFINE_CONFIG_METHODS_END(News::UpdateHeadlines::SKU)
  60. ////////////////////
  61. CFG_BEGIN_FIELDS_MAP(News::UpdateHeadlines::Language)
  62. CFG_ATTRIBUTE( L"LCID", long, m_lLCID ),
  63. CFG_END_FIELDS_MAP()
  64. CFG_BEGIN_CHILD_MAP(News::UpdateHeadlines::Language)
  65. CFG_CHILD(News::UpdateHeadlines::SKU)
  66. CFG_END_CHILD_MAP()
  67. DEFINE_CFG_OBJECT(News::UpdateHeadlines::Language,L"LANGUAGE")
  68. DEFINE_CONFIG_METHODS_CREATEINSTANCE_SECTION(News::UpdateHeadlines::Language,tag,defSubType)
  69. if(tag == _cfg_table_tags[0])
  70. {
  71. defSubType = &(*(m_lstSKUs.insert( m_lstSKUs.end() )));
  72. return S_OK;
  73. }
  74. DEFINE_CONFIG_METHODS_SAVENODE_SECTION(News::UpdateHeadlines::Language,xdn)
  75. hr = MPC::Config::SaveList( m_lstSKUs, xdn );
  76. DEFINE_CONFIG_METHODS_END(News::UpdateHeadlines::Language)
  77. ////////////////////
  78. CFG_BEGIN_FIELDS_MAP(News::UpdateHeadlines)
  79. CFG_END_FIELDS_MAP()
  80. CFG_BEGIN_CHILD_MAP(News::UpdateHeadlines)
  81. CFG_CHILD(News::UpdateHeadlines::Language)
  82. CFG_END_CHILD_MAP()
  83. DEFINE_CFG_OBJECT(News::UpdateHeadlines,L"UPDATEHEADLINES")
  84. DEFINE_CONFIG_METHODS_CREATEINSTANCE_SECTION(News::UpdateHeadlines,tag,defSubType)
  85. if(tag == _cfg_table_tags[0])
  86. {
  87. defSubType = &(*(m_lstLanguages.insert( m_lstLanguages.end() )));
  88. return S_OK;
  89. }
  90. DEFINE_CONFIG_METHODS_SAVENODE_SECTION(News::UpdateHeadlines,xdn)
  91. hr = MPC::Config::SaveList( m_lstLanguages, xdn );
  92. DEFINE_CONFIG_METHODS_END(News::UpdateHeadlines)
  93. /////////////////////////////////////////////////////////////////////////////
  94. /////////////////////////////////////////////////////////////////////////////
  95. /////////////////////////////////////////////////////////////////////////////
  96. News::UpdateHeadlines::Headline::Headline()
  97. {
  98. // MPC::wstring m_strIcon;
  99. // MPC::wstring m_strTitle;
  100. // MPC::wstring m_strLink;
  101. m_dtTimeOut = 0; // DATE m_dtTimeOut;
  102. }
  103. News::UpdateHeadlines::Headline::Headline( /*[in]*/ const MPC::wstring& strIcon ,
  104. /*[in]*/ const MPC::wstring& strTitle ,
  105. /*[in]*/ const MPC::wstring& strLink ,
  106. /*[in]*/ const MPC::wstring& strDescription ,
  107. /*[in]*/ int nTimeOutDays )
  108. {
  109. m_strIcon = strIcon; // MPC::wstring m_strIcon;
  110. m_strTitle = strTitle; // MPC::wstring m_strTitle;
  111. m_strLink = strLink; // MPC::wstring m_strLink;
  112. m_strDescription = strDescription; // MPC::wstring m_strDescription;
  113. m_dtTimeOut = MPC::GetLocalTime() + nTimeOutDays; // DATE m_dtTimeOut;
  114. }
  115. ////////////////////
  116. News::UpdateHeadlines::SKU::SKU()
  117. {
  118. // MPC::wstring m_strSKU;
  119. // HeadlineVector m_vecHeadlines;
  120. }
  121. News::UpdateHeadlines::SKU::SKU( /*[in]*/ const MPC::wstring& strSKU )
  122. {
  123. m_strSKU = strSKU; // MPC::wstring m_strSKU;
  124. // HeadlineVector m_vecHeadlines;
  125. }
  126. ////////////////////
  127. News::UpdateHeadlines::Language::Language()
  128. {
  129. m_lLCID = 0; // long m_lLCID;
  130. // SKUList m_lstSKUs;
  131. }
  132. News::UpdateHeadlines::Language::Language( long lLCID )
  133. {
  134. m_lLCID = lLCID; // long m_lLCID;
  135. // SKUList m_lstSKUs;
  136. }
  137. /////////////////////////////////////////////////////////////////////////////
  138. News::UpdateHeadlines::UpdateHeadlines()
  139. {
  140. // LanguageList m_lstLanguages;
  141. m_data = NULL; // SKU* m_data;
  142. m_fLoaded = false; // bool m_fLoaded;
  143. m_fDirty = false; // bool m_fDirty;
  144. }
  145. HRESULT News::UpdateHeadlines::Locate( /*[in]*/ long lLCID ,
  146. /*[in]*/ const MPC::wstring& strSKU ,
  147. /*[in]*/ bool fCreate )
  148. {
  149. __HCP_FUNC_ENTRY( "News::UpdateHeadlines::Locate" );
  150. HRESULT hr;
  151. LanguageIter itLanguage;
  152. SKUIter itSKU;
  153. m_data = NULL;
  154. if(m_fLoaded == false)
  155. {
  156. CComPtr<IStream> stream;
  157. MPC::wstring strPath( HC_HCUPDATE_UPDATE ); MPC::SubstituteEnvVariables( strPath );
  158. // we load the file
  159. if(SUCCEEDED(News::LoadXMLFile( strPath.c_str(), stream )))
  160. {
  161. if(SUCCEEDED(MPC::Config::LoadStream( this, stream )))
  162. {
  163. ;
  164. }
  165. }
  166. m_fLoaded = true;
  167. m_fDirty = false;
  168. }
  169. itLanguage = m_lstLanguages.begin();
  170. while(1)
  171. {
  172. if(itLanguage == m_lstLanguages.end())
  173. {
  174. if(fCreate == false)
  175. {
  176. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_INVALID_DATA);
  177. }
  178. itLanguage = m_lstLanguages.insert( itLanguage, Language( lLCID ) );
  179. m_fDirty = true;
  180. }
  181. if(itLanguage->m_lLCID == lLCID)
  182. {
  183. itSKU = itLanguage->m_lstSKUs.begin();
  184. while(1)
  185. {
  186. if(itSKU == itLanguage->m_lstSKUs.end())
  187. {
  188. if(fCreate == false)
  189. {
  190. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_INVALID_DATA);
  191. }
  192. itSKU = itLanguage->m_lstSKUs.insert( itSKU, SKU( strSKU ) );
  193. m_fDirty = true;
  194. }
  195. //
  196. // Check if its bstrMySKUVersion
  197. if(!MPC::StrICmp( itSKU->m_strSKU, strSKU ))
  198. {
  199. m_data = &(*itSKU);
  200. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  201. }
  202. itSKU++;
  203. }
  204. }
  205. itLanguage++;
  206. }
  207. hr = S_OK;
  208. __HCP_FUNC_CLEANUP;
  209. __HCP_FUNC_EXIT(hr);
  210. }
  211. //
  212. // Routine Description:
  213. //
  214. // Loads the UpdateHeadlines.xml file and looks for the specified LCID and SKUVersion
  215. //
  216. // if the file doesn't exist, or there isn't the LCID and SKU,
  217. // those elements are added to the file
  218. //
  219. // the iterators will point to the specified LCID and SKU
  220. //
  221. // Arguments:
  222. //
  223. // nMyLCID the CLanguage to look for
  224. //
  225. // strMySKUVersion the CSKU to look for
  226. //
  227. //
  228. HRESULT News::UpdateHeadlines::Load( /*[in]*/ long lLCID ,
  229. /*[in]*/ const MPC::wstring& strSKU )
  230. {
  231. __HCP_FUNC_ENTRY( "News::UpdateHeadlines::Load" );
  232. HRESULT hr;
  233. __MPC_EXIT_IF_METHOD_FAILS(hr, Locate( lLCID, strSKU, /*fCreate*/true ));
  234. hr = S_OK;
  235. __HCP_FUNC_CLEANUP;
  236. __HCP_FUNC_EXIT(hr);
  237. }
  238. //
  239. // Routine Description:
  240. //
  241. // This saves the UpdateHeadlines file in the path of HC_HCUPDATE_UPDATE
  242. //
  243. // Arguments:
  244. //
  245. // None
  246. //
  247. //
  248. HRESULT News::UpdateHeadlines::Save()
  249. {
  250. __HCP_FUNC_ENTRY( "News::UpdateHeadlines::Save" );
  251. HRESULT hr;
  252. if(m_fDirty)
  253. {
  254. MPC::wstring strPath( HC_HCUPDATE_UPDATE ); MPC::SubstituteEnvVariables( strPath );
  255. // check to see if the dirs exist
  256. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::MakeDir( strPath ));
  257. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::Config::SaveFile( this, strPath.c_str() ));
  258. m_fDirty = false;
  259. }
  260. hr = S_OK;
  261. __HCP_FUNC_CLEANUP;
  262. __HCP_FUNC_EXIT(hr);
  263. }
  264. //
  265. // Routine Description:
  266. //
  267. // Will add a new Headline for the specified LCID and SKU
  268. // If the UpdateHeadlines file doesn't exist, it will be created and saved
  269. //
  270. // - additional validation is made
  271. //
  272. // Arguments:
  273. //
  274. // nMyLCID the Language
  275. // strMySKUVersion the SKU
  276. // strMyIcon the Icon for the Headline
  277. // strMyTitle the Title for the Headline
  278. // strMyLink the Link for the Headline
  279. // nTimeOutDays the number of days, to set the frequency
  280. //
  281. //
  282. //
  283. HRESULT News::UpdateHeadlines::Add ( /*[in]*/ long lLCID ,
  284. /*[in]*/ const MPC::wstring& strSKU ,
  285. /*[in]*/ const MPC::wstring& strIcon ,
  286. /*[in]*/ const MPC::wstring& strTitle ,
  287. /*[in]*/ const MPC::wstring& strLink ,
  288. /*[in]*/ const MPC::wstring& strDescription ,
  289. /*[in]*/ int nTimeOutDays ,
  290. /*[in]*/ DATE dtExpiryDate)
  291. {
  292. __HCP_FUNC_ENTRY( "News::UpdateHeadlines::Add" );
  293. HRESULT hr;
  294. HeadlineIter it;
  295. // Before doing anything make sure that the headlines hasnt expired
  296. // Note: this is the calendar expiration date i.e. if the calendar expiry date is 1/1/01 and
  297. // if the user tries to install this headlines on 1/1/02 then it fails
  298. if (dtExpiryDate && (MPC::GetLocalTime() > dtExpiryDate))
  299. {
  300. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  301. }
  302. // Set the default expiration date if it is 0
  303. if (nTimeOutDays == 0)
  304. {
  305. nTimeOutDays = HCUPDATE_DEFAULT_TIMEOUT;
  306. }
  307. // Load UpdateHeadlines
  308. __MPC_EXIT_IF_METHOD_FAILS(hr, Load( lLCID, strSKU ));
  309. // check that this Headline is unique:
  310. //
  311. for(it = m_data->m_vecHeadlines.begin(); it != m_data->m_vecHeadlines.end(); it++)
  312. {
  313. // if it has the same title
  314. if(MPC::StrICmp( it->m_strTitle, strTitle ) == 0)
  315. {
  316. // modify existing headline
  317. it->m_strIcon = strIcon;
  318. it->m_strLink = strLink;
  319. it->m_strDescription = strDescription;
  320. it->m_dtTimeOut = MPC::GetLocalTime() + nTimeOutDays;
  321. m_fDirty = true;
  322. break;
  323. }
  324. // if it has the same link
  325. if(it->m_strLink == strLink)
  326. {
  327. // modify existing headline
  328. it->m_strIcon = strIcon;
  329. it->m_strTitle = strTitle;
  330. it->m_strDescription = strDescription;
  331. it->m_dtTimeOut = MPC::GetLocalTime() + nTimeOutDays;
  332. m_fDirty = true;
  333. break;
  334. }
  335. }
  336. // if we didn't found and modified a headline
  337. if(it == m_data->m_vecHeadlines.end())
  338. {
  339. m_data->m_vecHeadlines.insert(m_data->m_vecHeadlines.begin(), Headline( strIcon, strTitle, strLink, strDescription, nTimeOutDays ) );
  340. m_fDirty = true;
  341. }
  342. // Save UpdateHeadlines.xml file
  343. __MPC_EXIT_IF_METHOD_FAILS(hr, Save());
  344. hr = S_OK;
  345. __HCP_FUNC_CLEANUP;
  346. __HCP_FUNC_EXIT(hr);
  347. }
  348. //
  349. // Routine Description:
  350. //
  351. // Gets all the UpdateHeadlines for the specified LCID and SKU
  352. // Deletes the expired UpdateHeadlines
  353. // and inserts the rest in the list of Headlines
  354. //
  355. // Arguments:
  356. //
  357. // nMyLCID the Language
  358. // strMySKUVersion the SKU
  359. //
  360. //
  361. HRESULT News::UpdateHeadlines::AddHCUpdateHeadlines( /*[in]*/ long lLCID ,
  362. /*[in]*/ const MPC::wstring& strSKU ,
  363. /*[in]*/ News::Headlines& nhHeadlines )
  364. {
  365. __HCP_FUNC_ENTRY( "News::UpdateHeadlines::Get" );
  366. HRESULT hr;
  367. HeadlineIter itUpdateHeadlines;
  368. Headlines::HeadlineIter itHeadlines;
  369. Headlines::Newsblock* ptrNewsblock;
  370. size_t nLength;
  371. // Load UpdateHeadlines
  372. __MPC_EXIT_IF_METHOD_FAILS( hr, Load( lLCID, strSKU ) );
  373. // Add the first headline from the UpdateHeadlines.xml to the first Newsblock
  374. itUpdateHeadlines = m_data->m_vecHeadlines.begin();
  375. ptrNewsblock = nhHeadlines.get_Newsblock(0);
  376. itHeadlines = ptrNewsblock->m_vecHeadlines.begin();
  377. // Check to see if there are any headlines - if the vector is empty then just add this headline
  378. if ( itHeadlines == ptrNewsblock->m_vecHeadlines.end() )
  379. {
  380. ptrNewsblock->m_vecHeadlines.insert( ptrNewsblock->m_vecHeadlines.end(), News::Headlines::Headline( itUpdateHeadlines->m_strIcon, itUpdateHeadlines->m_strTitle, itUpdateHeadlines->m_strLink, MPC::wstring(), itUpdateHeadlines->m_dtTimeOut, true ));
  381. }
  382. else
  383. {
  384. // There are other headlines in the file
  385. while ( 1 )
  386. {
  387. if ( itHeadlines->m_fUpdateHeadlines == true )
  388. {
  389. // An update headline already exists - replace it
  390. ptrNewsblock->m_vecHeadlines.erase( itHeadlines );
  391. ptrNewsblock->m_vecHeadlines.insert( itHeadlines, News::Headlines::Headline( itUpdateHeadlines->m_strIcon, itUpdateHeadlines->m_strTitle, itUpdateHeadlines->m_strLink, MPC::wstring(), itUpdateHeadlines->m_dtTimeOut, true ));
  392. break;
  393. }
  394. if ( ++itHeadlines == ptrNewsblock->m_vecHeadlines.end() )
  395. {
  396. // No previous update existed - add this to the end of the vector
  397. ptrNewsblock->m_vecHeadlines.insert( ptrNewsblock->m_vecHeadlines.end(), News::Headlines::Headline( itUpdateHeadlines->m_strIcon, itUpdateHeadlines->m_strTitle, itUpdateHeadlines->m_strLink, MPC::wstring(), itUpdateHeadlines->m_dtTimeOut, true ));
  398. break;
  399. }
  400. }
  401. }
  402. // Now add the remaining headlines to the Newsblock whose provider is called "Recent Updates".
  403. if ( ++itUpdateHeadlines != m_data->m_vecHeadlines.end() )
  404. {
  405. nLength = nhHeadlines.get_NumberOfNewsblocks();
  406. // The first headline has been added to the homepage so dont add it again
  407. for ( ptrNewsblock = nhHeadlines.get_Newsblock(nLength - 1); ptrNewsblock; )
  408. {
  409. CComBSTR bstrUpdateBlockName;
  410. // Load the localized name of the update block
  411. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeString( IDS_NEWS_UPDATEBLOCK_NAME, bstrUpdateBlockName ));
  412. if(!MPC::StrICmp( ptrNewsblock->m_strProvider, bstrUpdateBlockName ))
  413. {
  414. // Found the "Recent Updates" newsblock - add the rest of the headlines here
  415. // Before adding delete the current set of headlines
  416. ptrNewsblock->m_vecHeadlines.clear();
  417. for ( ; itUpdateHeadlines != m_data->m_vecHeadlines.end(); ++itUpdateHeadlines )
  418. {
  419. ptrNewsblock->m_vecHeadlines.insert(ptrNewsblock->m_vecHeadlines.end(), News::Headlines::Headline( itUpdateHeadlines->m_strIcon, itUpdateHeadlines->m_strTitle, itUpdateHeadlines->m_strLink, itUpdateHeadlines->m_strDescription, itUpdateHeadlines->m_dtTimeOut, true ));
  420. }
  421. break;
  422. }
  423. ptrNewsblock = nhHeadlines.get_Newsblock(--nLength);
  424. }
  425. }
  426. __MPC_EXIT_IF_METHOD_FAILS(hr, Save());
  427. hr = S_OK;
  428. __HCP_FUNC_CLEANUP;
  429. __HCP_FUNC_EXIT(hr);
  430. }
  431. //
  432. // Routine Description:
  433. //
  434. // Checks to see if there is more than headlines item - returns true if there are
  435. // Also, deletes expired headlines
  436. //
  437. // Arguments:
  438. //
  439. // nMyLCID the Language
  440. // strMySKUVersion the SKU
  441. //
  442. //
  443. HRESULT News::UpdateHeadlines::DoesMoreThanOneHeadlineExist( /*[in]*/ long lLCID,
  444. /*[in]*/ const MPC::wstring& strSKU,
  445. /*[out]*/ bool& fMoreThanOneHeadline,
  446. /*[out]*/ bool& fExactlyOneHeadline)
  447. {
  448. __HCP_FUNC_ENTRY( "News::UpdateHeadlines::DoesNewsItemsExist" );
  449. HRESULT hr;
  450. HeadlineIter it;
  451. DATE dNow = MPC::GetLocalTime();
  452. fMoreThanOneHeadline = false;
  453. fExactlyOneHeadline = false;
  454. // Load UpdateHeadlines
  455. __MPC_EXIT_IF_METHOD_FAILS(hr, Load( lLCID, strSKU ));
  456. for(it = m_data->m_vecHeadlines.begin(); it != m_data->m_vecHeadlines.end(); it++)
  457. {
  458. // if the headline has expired
  459. if(it->m_dtTimeOut < dNow)
  460. {
  461. m_data->m_vecHeadlines.erase( it );
  462. m_fDirty = true;
  463. }
  464. }
  465. if(m_data->m_vecHeadlines.size() > 1)
  466. {
  467. fMoreThanOneHeadline = true;
  468. fExactlyOneHeadline = false;
  469. }
  470. if(m_data->m_vecHeadlines.size() == 1)
  471. {
  472. fMoreThanOneHeadline = false;
  473. fExactlyOneHeadline = true;
  474. }
  475. hr = S_OK;
  476. __HCP_FUNC_CLEANUP;
  477. __HCP_FUNC_EXIT(hr);
  478. }