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.

409 lines
9.2 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 2000-2001
  4. // All rights reserved
  5. //
  6. // conflict.cxx
  7. //
  8. //*************************************************************
  9. #include "appmgext.hxx"
  10. CConflict::CConflict(
  11. CAppInfo* pAppInfo,
  12. CAppInfo* pWinner,
  13. DWORD dwReason,
  14. LONG Precedence ) :
  15. _pAppInfo( pAppInfo ),
  16. _pwszConflictId( NULL ),
  17. _Precedence( Precedence ),
  18. _PrecedenceReason( dwReason ),
  19. _pWinner( pWinner )
  20. {}
  21. CConflict::~CConflict()
  22. {
  23. delete [] _pwszConflictId;
  24. }
  25. HRESULT
  26. CConflict::Write()
  27. {
  28. HRESULT hr;
  29. DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_WRITE_INFO, GetApp()->_pwszDeploymentName, GetApp()->_pwszGPOName));
  30. hr = SetValue(
  31. RSOP_ATTRIBUTE_ID,
  32. _pwszConflictId);
  33. REPORT_ATTRIBUTE_SET_STATUS( RSOP_ATTRIBUTE_ID, hr )
  34. if (FAILED(hr))
  35. {
  36. goto CConflict_Write_cleanup;
  37. }
  38. hr = SetValue(
  39. RSOP_ATTRIBUTE_PRECEDENCE,
  40. _Precedence);
  41. REPORT_ATTRIBUTE_SET_STATUS( RSOP_ATTRIBUTE_PRECEDENCE, hr )
  42. if (FAILED(hr))
  43. {
  44. goto CConflict_Write_cleanup;
  45. }
  46. if ( 1 == _Precedence )
  47. {
  48. _PrecedenceReason = APP_ATTRIBUTE_REASON_VALUE_WINNING;
  49. }
  50. if ( 0 != _PrecedenceReason )
  51. {
  52. hr = SetValue(
  53. APP_ATTRIBUTE_PRECEDENCE_REASON,
  54. (LONG) _PrecedenceReason);
  55. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_PRECEDENCE_REASON, hr )
  56. }
  57. if ( 0 != _Precedence )
  58. {
  59. if ( _Precedence > 1 || AlreadyExists() )
  60. {
  61. GetApp()->_dwApplyCause = APP_ATTRIBUTE_APPLYCAUSE_VALUE_NONE;
  62. hr = ClearValue( APP_ATTRIBUTE_APPLY_CAUSE );
  63. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_APPLY_CAUSE, hr )
  64. }
  65. }
  66. else
  67. {
  68. GetApp()->_dwRemovalCause = APP_ATTRIBUTE_REMOVALCAUSE_NONE;
  69. }
  70. hr = GetApp()->Write( this );
  71. CConflict_Write_cleanup:
  72. return S_OK;
  73. }
  74. HRESULT
  75. CConflict::GetPath( WCHAR* wszPath, DWORD* pchLength )
  76. {
  77. //
  78. // A relative path to an instance of RSOP_ApplicationManagementPolicySetting
  79. // looks like:
  80. //
  81. // RSOP_ApplicationManagementPolicySetting.EntryType=<entrytype>,id="<id-guid>",applicationid="<appid-guid>",precedence=<precedence>
  82. //
  83. DWORD cchRequired;
  84. HRESULT hr = S_OK;
  85. ASSERT( ( GetApp()->GetPublicRsopEntryType() <= APP_ATTRIBUTE_ENTRYTYPE_VALUE_ARPLIST_ITEM ) &&
  86. ( GetApp()->GetPublicRsopEntryType() >= APP_ATTRIBUTE_ENTRYTYPE_VALUE_INSTALLED_PACKAGE ) );
  87. cchRequired = sizeof( RELATIVE_PATH_FORMAT ) / sizeof( WCHAR ) + // Fixed length portion
  88. 1 + // Entry type
  89. MAX_SZGUID_LEN * 2 + // 2 guids
  90. 9; // Precedence = 1
  91. if ( cchRequired <= *pchLength )
  92. {
  93. WCHAR wszDeploymentId[ MAX_SZGUID_LEN ];
  94. WCHAR* wszApplicationId;
  95. LONG lPrecedence;
  96. LONG EntryType;
  97. if ( GetApp()->_bRemovalLogged )
  98. {
  99. EntryType = APP_ATTRIBUTE_ENTRYTYPE_VALUE_REMOVED_PACKAGE;
  100. lPrecedence = 0;
  101. }
  102. else
  103. {
  104. EntryType = GetApp()->GetPublicRsopEntryType();
  105. lPrecedence = 1;
  106. }
  107. GuidToString( GetApp()->_DeploymentId, wszDeploymentId);
  108. //
  109. // Since we are only using precedence 1 applications, the application id
  110. // happens to be the same as the id
  111. //
  112. wszApplicationId = wszDeploymentId;
  113. hr = StringCchPrintf(
  114. wszPath,
  115. *pchLength,
  116. RELATIVE_PATH_FORMAT,
  117. EntryType,
  118. wszDeploymentId,
  119. wszApplicationId,
  120. lPrecedence);
  121. ASSERT(SUCCEEDED(hr));
  122. }
  123. else
  124. {
  125. *pchLength = cchRequired;
  126. hr = S_FALSE;
  127. }
  128. return hr;
  129. }
  130. HRESULT
  131. CConflict::SetConflictId( WCHAR* pwszConflictId )
  132. {
  133. HRESULT hr;
  134. hr = ERROR_SUCCESS;
  135. ASSERT ( ! _pwszConflictId );
  136. _pwszConflictId = StringDuplicate( pwszConflictId );
  137. if ( ! _pwszConflictId )
  138. {
  139. hr = E_OUTOFMEMORY;
  140. }
  141. return hr;
  142. }
  143. CConflictList::~CConflictList()
  144. {
  145. CConflict* pConflict;
  146. Reset();
  147. for ( Reset(); pConflict = (CConflict*) GetCurrentItem(); )
  148. {
  149. MoveNext();
  150. pConflict->Remove();
  151. delete pConflict;
  152. }
  153. }
  154. LONG
  155. CConflictList::AddConflict( CAppInfo* pAppInfo, CAppInfo* pWinner, DWORD dwReason, LONG Precedence )
  156. {
  157. CConflict* pNewConflict;
  158. pNewConflict = new CConflict( pAppInfo, pWinner, dwReason, Precedence );
  159. if ( ! pNewConflict )
  160. {
  161. return ERROR_NOT_ENOUGH_MEMORY;
  162. }
  163. InsertFIFO( pNewConflict );
  164. return ERROR_SUCCESS;
  165. }
  166. CConflictTable::CConflictTable() :
  167. _pLastConflict( NULL )
  168. {}
  169. void
  170. CConflictTable::Reset()
  171. {
  172. _pLastConflict = NULL;
  173. _SupersededApps.Reset();
  174. }
  175. LONG
  176. CConflictTable::AddConflict(
  177. CAppInfo* pAppInfo,
  178. CAppInfo* pWinner,
  179. DWORD dwReason,
  180. LONG Prececence )
  181. {
  182. return _SupersededApps.AddConflict( pAppInfo, pWinner, dwReason );
  183. }
  184. CConflict*
  185. CConflictTable::GetNextConflict( LONG* pCurrentPrecedence )
  186. {
  187. CConflict* pNextConflict;
  188. pNextConflict = NULL;
  189. //
  190. // If we're at the end, leave
  191. //
  192. if ( ! _pLastConflict && ! _SupersededApps.GetCurrentItem() )
  193. {
  194. return NULL;
  195. }
  196. //
  197. // Try to traverse the last conflict to find the next conflict
  198. //
  199. if ( _pLastConflict )
  200. {
  201. //
  202. // The precedence of the next application should be one more
  203. // than the last conflict
  204. //
  205. pNextConflict = _pLastConflict->GetApp()->GetConflictTable()->GetNextConflict( pCurrentPrecedence );
  206. if ( pNextConflict )
  207. {
  208. (*pCurrentPrecedence)++;
  209. }
  210. }
  211. if ( ! pNextConflict )
  212. {
  213. //
  214. // If we did not find a conflict as a result of the previous conflict,
  215. // let's try the next item in our conflict list
  216. //
  217. pNextConflict = (CConflict*) ( _SupersededApps.GetCurrentItem() );
  218. _SupersededApps.MoveNext();
  219. if ( pNextConflict )
  220. {
  221. pNextConflict->GetApp()->GetConflictTable()->Reset();
  222. }
  223. }
  224. _pLastConflict = pNextConflict;
  225. //
  226. // We are finished calculating the precedence and may now
  227. // set the final precedence value
  228. //
  229. if ( pNextConflict )
  230. {
  231. pNextConflict->_Precedence = *pCurrentPrecedence;
  232. }
  233. return pNextConflict;
  234. }
  235. LONG
  236. CConflictTable::GenerateResultantConflictList( CConflictList* pConflictList )
  237. {
  238. CConflict* pConflict;
  239. LONG Status;
  240. LONG Precedence;
  241. Precedence = 2;
  242. Status = ERROR_SUCCESS;
  243. Reset();
  244. while ( pConflict = GetNextConflict( &Precedence ) )
  245. {
  246. Status = pConflictList->AddConflict(
  247. pConflict->GetApp(),
  248. pConflict->_pWinner,
  249. pConflict->_PrecedenceReason,
  250. pConflict->_Precedence);
  251. if ( ERROR_SUCCESS != Status )
  252. break;
  253. Precedence = pConflict->_Precedence;
  254. }
  255. return Status;
  256. }
  257. HRESULT
  258. CConflict::LogFailure()
  259. {
  260. //
  261. // We only log status for settings
  262. // with failures
  263. //
  264. CAppStatus* pAppStatus;
  265. //
  266. // First, see if this setting (app) has a status
  267. //
  268. pAppStatus = (CAppStatus*) GetApp()->_StatusList.GetCurrentItem();
  269. if ( ! pAppStatus )
  270. {
  271. return S_FALSE;
  272. }
  273. //
  274. // Advance the list to the next failure so
  275. // that the next caller will log a different failure
  276. //
  277. GetApp()->_StatusList.MoveNext();
  278. //
  279. // Skip this status if this is not a failure
  280. //
  281. if ( RSOPFailed != pAppStatus->_SettingStatus )
  282. {
  283. return S_OK;
  284. }
  285. HRESULT hr;
  286. IWbemServices* pWbemServices;
  287. //
  288. // Bind to WMI -- this is essentially no op in policy refresh
  289. //
  290. hr = GetApp()->_pManApp->GetRsopContext()->Bind( &pWbemServices );
  291. if ( SUCCEEDED(hr) )
  292. {
  293. POLICYSETTINGSTATUSINFO SettingStatus;
  294. memset( &SettingStatus, 0, sizeof( SettingStatus ) );
  295. SettingStatus.szEventSource = APPMGMT_EVENT_SOURCE;
  296. SettingStatus.szEventLogName = L"Application";
  297. SettingStatus.dwEventID = pAppStatus->_dwEventId;
  298. SettingStatus.dwErrorCode = ERROR_SUCCESS;
  299. SettingStatus.status = pAppStatus->_SettingStatus;
  300. SettingStatus.timeLogged = pAppStatus->_StatusTime;
  301. hr = RsopSetPolicySettingStatus(
  302. 0,
  303. pWbemServices,
  304. GetRecordInterface(),
  305. 1,
  306. &SettingStatus);
  307. }
  308. if ( FAILED(hr) )
  309. {
  310. REPORT_ATTRIBUTE_SET_STATUS( L"Policy Setting Status", hr )
  311. }
  312. return hr;
  313. }