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.

774 lines
25 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. Channel.cpp
  5. Abstract:
  6. This is implementation of IChannel object
  7. Revision History:
  8. Steve Shih created 07/15/99
  9. Davide Massarenti rewrote 12/05/2000
  10. ********************************************************************/
  11. #include "stdafx.h"
  12. ////////////////////////////////////////////////////////////////////////////////
  13. CSAFChannelRecord::CSAFChannelRecord()
  14. {
  15. }
  16. HRESULT CSAFChannelRecord::GetField( /*[in]*/ SAFREG_Field field, /*[out]*/ BSTR *pVal )
  17. {
  18. LPCWSTR szText;
  19. WCHAR rgLCID[64];
  20. switch(field)
  21. {
  22. case SAFREG_SKU : szText = m_ths.GetSKU (); break;
  23. case SAFREG_Language : szText = rgLCID; _ltow( m_ths.GetLanguage(), rgLCID, 10 ); break;
  24. case SAFREG_VendorID : szText = m_bstrVendorID; break;
  25. case SAFREG_ProductID : szText = m_bstrProductID; break;
  26. case SAFREG_VendorName : szText = m_bstrVendorName; break;
  27. case SAFREG_ProductName : szText = m_bstrProductName; break;
  28. case SAFREG_ProductDescription: szText = m_bstrDescription; break;
  29. case SAFREG_VendorIcon : szText = m_bstrIcon; break;
  30. case SAFREG_SupportUrl : szText = m_bstrURL; break;
  31. break;
  32. case SAFREG_PublicKey : szText = m_bstrPublicKey; break;
  33. case SAFREG_UserAccount : szText = m_bstrUserAccount; break;
  34. case SAFREG_Security : szText = m_bstrSecurity; break;
  35. case SAFREG_Notification : szText = m_bstrNotification; break;
  36. default: return E_INVALIDARG;
  37. }
  38. return MPC::GetBSTR( szText, pVal );
  39. }
  40. HRESULT CSAFChannelRecord::SetField( /*[in]*/ SAFREG_Field field, /*[in]*/ BSTR newVal )
  41. {
  42. CComBSTR* pbstr = NULL;
  43. SANITIZEWSTR( newVal );
  44. switch(field)
  45. {
  46. case SAFREG_SKU : m_ths.m_strSKU = newVal ; break;
  47. case SAFREG_Language : m_ths.m_lLCID = _wtol( newVal ) ; break;
  48. case SAFREG_VendorID : pbstr = (CComBSTR*)&m_bstrVendorID ; break;
  49. case SAFREG_ProductID : pbstr = (CComBSTR*)&m_bstrProductID ; break;
  50. case SAFREG_VendorName : pbstr = (CComBSTR*)&m_bstrVendorName ; break;
  51. case SAFREG_ProductName : pbstr = (CComBSTR*)&m_bstrProductName ; break;
  52. case SAFREG_ProductDescription: pbstr = (CComBSTR*)&m_bstrDescription ; break;
  53. case SAFREG_VendorIcon : pbstr = (CComBSTR*)&m_bstrIcon ; break;
  54. case SAFREG_SupportUrl : pbstr = (CComBSTR*)&m_bstrURL ; break;
  55. case SAFREG_PublicKey : pbstr = (CComBSTR*)&m_bstrPublicKey ; break;
  56. case SAFREG_UserAccount : pbstr = (CComBSTR*)&m_bstrUserAccount ; break;
  57. case SAFREG_Security : pbstr = (CComBSTR*)&m_bstrSecurity ; break;
  58. case SAFREG_Notification : pbstr = (CComBSTR*)&m_bstrNotification; break;
  59. default: return E_INVALIDARG;
  60. }
  61. return pbstr ? MPC::PutBSTR( *pbstr, newVal ) : S_OK;
  62. }
  63. ////////////////////////////////////////////////////////////////////////////////
  64. CSAFChannel::CSAFChannel()
  65. {
  66. __HCP_FUNC_ENTRY( "CSAFChannel::CSAFChannel" );
  67. // CSAFChannelRecord m_data;
  68. // CComPtr<IPCHSecurityDescriptor> m_Security;
  69. // List m_lstIncidentItems;
  70. }
  71. void CSAFChannel::FinalRelease()
  72. {
  73. __HCP_FUNC_ENTRY( "CSAFChannel::FinalRelease" );
  74. Passivate();
  75. }
  76. void CSAFChannel::Passivate()
  77. {
  78. __HCP_FUNC_ENTRY( "CSAFChannel::Passivate" );
  79. m_Security.Release();
  80. MPC::ReleaseAll( m_lstIncidentItems );
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. HRESULT CSAFChannel::OpenIncidentStore( /*[out]*/ CIncidentStore*& pIStore )
  84. {
  85. __HCP_FUNC_ENTRY( "CSAFChannel::OpenIncidentStore" );
  86. HRESULT hr;
  87. __MPC_EXIT_IF_ALLOC_FAILS(hr, pIStore, new CIncidentStore());
  88. __MPC_EXIT_IF_METHOD_FAILS(hr, pIStore->Load());
  89. hr = S_OK;
  90. __HCP_FUNC_CLEANUP;
  91. __HCP_FUNC_EXIT(hr);
  92. }
  93. HRESULT CSAFChannel::CloseIncidentStore( /*[out]*/ CIncidentStore*& pIStore )
  94. {
  95. __HCP_FUNC_ENTRY( "CSAFChannel::CloseIncidentStore" );
  96. HRESULT hr;
  97. if(pIStore)
  98. {
  99. (void)pIStore->Save();
  100. delete pIStore; pIStore = NULL;
  101. }
  102. hr = S_OK;
  103. __HCP_FUNC_EXIT(hr);
  104. }
  105. /////////////////////////////////////////////////////////////////////////////
  106. HRESULT CSAFChannel::Init( /*[in]*/ const CSAFChannelRecord& cr )
  107. {
  108. __HCP_FUNC_ENTRY( "CSAFChannel::Init" );
  109. HRESULT hr;
  110. CIncidentStore* pIStore = NULL;
  111. m_data = cr;
  112. __MPC_EXIT_IF_METHOD_FAILS(hr, OpenIncidentStore( pIStore ));
  113. __MPC_EXIT_IF_METHOD_FAILS(hr, pIStore->OpenChannel( this ));
  114. hr = S_OK;
  115. __HCP_FUNC_CLEANUP;
  116. (void)CloseIncidentStore( pIStore );
  117. __HCP_FUNC_EXIT(hr);
  118. }
  119. HRESULT CSAFChannel::Import( /*[in]*/ const CSAFIncidentRecord& increc ,
  120. /*[out]*/ CSAFIncidentItem* *ppItem )
  121. {
  122. __HCP_FUNC_ENTRY( "CSAFChannel::Import" );
  123. HRESULT hr;
  124. CComObject<CSAFIncidentItem>* pItem = NULL;
  125. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateChild( this, &pItem ));
  126. __MPC_EXIT_IF_METHOD_FAILS(hr, pItem->Import( increc ));
  127. if(ppItem)
  128. {
  129. (*ppItem = pItem)->AddRef();
  130. }
  131. m_lstIncidentItems.push_back( pItem ); pItem = NULL;
  132. hr = S_OK;
  133. __HCP_FUNC_CLEANUP;
  134. MPC::Release( pItem );
  135. __HCP_FUNC_EXIT(hr);
  136. }
  137. HRESULT CSAFChannel::Create( /*[in]*/ BSTR bstrDesc ,
  138. /*[in]*/ BSTR bstrURL ,
  139. /*[in]*/ BSTR bstrProgress ,
  140. /*[in]*/ BSTR bstrXMLDataFile ,
  141. /*[in]*/ BSTR bstrXMLBlob ,
  142. /*[out]*/ CSAFIncidentItem* *pVal )
  143. {
  144. __HCP_FUNC_ENTRY( "CSAFChannel::Create" );
  145. HRESULT hr;
  146. CIncidentStore* pIStore = NULL;
  147. CComBSTR bstrOwner;
  148. __MPC_PARAMCHECK_BEGIN(hr)
  149. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  150. __MPC_PARAMCHECK_END();
  151. __MPC_EXIT_IF_METHOD_FAILS(hr, OpenIncidentStore( pIStore ));
  152. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetCallerPrincipal( /*fImpersonate*/true, bstrOwner ));
  153. __MPC_EXIT_IF_METHOD_FAILS(hr, pIStore->AddRec( this, bstrOwner, bstrDesc, bstrURL, bstrProgress, bstrXMLDataFile, bstrXMLBlob, pVal ));
  154. // Fire an event to the Notification Object (onIncidentAdded)
  155. __MPC_EXIT_IF_METHOD_FAILS(hr, Fire_NotificationEvent( EVENT_INCIDENTADDED, GetSizeIncidentList(), this, *pVal, 0 ));
  156. hr = S_OK;
  157. __HCP_FUNC_CLEANUP;
  158. (void)CloseIncidentStore( pIStore );
  159. __HCP_FUNC_EXIT(hr);
  160. }
  161. CSAFChannel::IterConst CSAFChannel::Find( /*[in]*/ BSTR bstrURL )
  162. {
  163. IterConst it;
  164. //
  165. // Release all the items.
  166. //
  167. for(it = m_lstIncidentItems.begin(); it != m_lstIncidentItems.end(); it++)
  168. {
  169. if((*it)->GetURL() == bstrURL) break;
  170. }
  171. return it;
  172. }
  173. CSAFChannel::IterConst CSAFChannel::Find( /*[in]*/ DWORD dwIndex )
  174. {
  175. IterConst it;
  176. //
  177. // Release all the items.
  178. //
  179. for(it = m_lstIncidentItems.begin(); it != m_lstIncidentItems.end(); it++)
  180. {
  181. if((*it)->GetRecIndex() == dwIndex) break;
  182. }
  183. return it;
  184. }
  185. /////////////////////////////////////////////////////////////////////////////
  186. // Custom interfaces
  187. STDMETHODIMP CSAFChannel::get_VendorID( /*[out, retval]*/ BSTR *pVal )
  188. {
  189. MPC::SmartLock<_ThreadModel> lock( this );
  190. return m_data.GetField( CSAFChannelRecord::SAFREG_VendorID, pVal );
  191. }
  192. STDMETHODIMP CSAFChannel::get_ProductID( /*[out, retval]*/ BSTR *pVal )
  193. {
  194. MPC::SmartLock<_ThreadModel> lock( this );
  195. return m_data.GetField( CSAFChannelRecord::SAFREG_ProductID, pVal );
  196. }
  197. STDMETHODIMP CSAFChannel::get_VendorName( /*[out, retval]*/ BSTR *pVal )
  198. {
  199. MPC::SmartLock<_ThreadModel> lock( this );
  200. return m_data.GetField( CSAFChannelRecord::SAFREG_VendorName, pVal );
  201. }
  202. STDMETHODIMP CSAFChannel::get_ProductName( /*[out, retval]*/ BSTR *pVal )
  203. {
  204. MPC::SmartLock<_ThreadModel> lock( this );
  205. return m_data.GetField( CSAFChannelRecord::SAFREG_ProductName, pVal );
  206. }
  207. STDMETHODIMP CSAFChannel::get_Description( /*[out, retval]*/ BSTR *pVal )
  208. {
  209. MPC::SmartLock<_ThreadModel> lock( this );
  210. return m_data.GetField( CSAFChannelRecord::SAFREG_ProductDescription, pVal );
  211. }
  212. STDMETHODIMP CSAFChannel::get_VendorDirectory( /*[out, retval]*/ BSTR *pVal )
  213. {
  214. __HCP_FUNC_ENTRY( "CSAFChannel::get_VendorDirectory" );
  215. HRESULT hr;
  216. MPC::SmartLock<_ThreadModel> lock( this );
  217. MPC::wstring strRoot;
  218. Taxonomy::LockingHandle handle;
  219. Taxonomy::InstalledInstanceIter it;
  220. bool fFound;
  221. __MPC_PARAMCHECK_BEGIN(hr)
  222. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  223. __MPC_PARAMCHECK_END();
  224. if(m_data.m_bstrVendorID.Length() == 0)
  225. {
  226. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  227. }
  228. __MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::InstalledInstanceStore::s_GLOBAL->GrabControl( handle ));
  229. __MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::InstalledInstanceStore::s_GLOBAL->SKU_Find ( m_data.m_ths, fFound, it ));
  230. if(!fFound)
  231. {
  232. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  233. }
  234. strRoot = it->m_inst.m_strSystem;
  235. strRoot += HC_HELPSET_SUB_VENDORS L"\\"; MPC::SubstituteEnvVariables( strRoot );
  236. strRoot += m_data.m_bstrVendorID;
  237. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( strRoot.c_str(), pVal ));
  238. hr = S_OK;
  239. __HCP_FUNC_CLEANUP;
  240. __HCP_FUNC_EXIT(hr);
  241. }
  242. /////////////////////////////////////////////////////////////////////////////
  243. STDMETHODIMP CSAFChannel::get_Security( /*[out, retval]*/ IPCHSecurityDescriptor* *pVal )
  244. {
  245. __HCP_FUNC_ENTRY( "CSAFChannel::get_Security" );
  246. HRESULT hr;
  247. __MPC_PARAMCHECK_BEGIN(hr)
  248. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  249. __MPC_PARAMCHECK_END();
  250. if(m_data.m_bstrSecurity.Length())
  251. {
  252. if(m_Security == NULL)
  253. {
  254. CPCHSecurityDescriptorDirect sdd;
  255. __MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertFromString( m_data.m_bstrSecurity ));
  256. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurity::s_GLOBAL->CreateObject_SecurityDescriptor( &m_Security ));
  257. __MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertSDToCOM( m_Security ));
  258. }
  259. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Security.CopyTo( pVal ));
  260. }
  261. hr = S_OK;
  262. __HCP_FUNC_CLEANUP;
  263. __HCP_FUNC_EXIT(hr);
  264. }
  265. STDMETHODIMP CSAFChannel::put_Security( /*[in]*/ IPCHSecurityDescriptor* newVal )
  266. {
  267. __HCP_FUNC_ENTRY( "CSAFChannel::put_Security" );
  268. HRESULT hr;
  269. m_data.m_bstrSecurity.Empty ();
  270. m_Security .Release();
  271. if(newVal)
  272. {
  273. CPCHSecurityDescriptorDirect sdd;
  274. __MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertSDFromCOM( newVal ));
  275. __MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertToString( &m_data.m_bstrSecurity ));
  276. }
  277. //
  278. // Update the SAF store...
  279. //
  280. __MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg::s_GLOBAL->UpdateField( m_data, CSAFChannelRecord::SAFREG_Security ));
  281. hr = S_OK;
  282. __HCP_FUNC_CLEANUP;
  283. __HCP_FUNC_EXIT(hr);
  284. }
  285. /////////////////////////////////////////////////////////////////////////////
  286. STDMETHODIMP CSAFChannel::get_Notification( /*[out, retval]*/ BSTR *pVal )
  287. {
  288. MPC::SmartLock<_ThreadModel> lock( this );
  289. return m_data.GetField( CSAFChannelRecord::SAFREG_Notification, pVal );
  290. }
  291. STDMETHODIMP CSAFChannel::put_Notification( /*[in]*/ BSTR newVal )
  292. {
  293. __HCP_FUNC_ENTRY( "CSAFChannel::get_Notification" );
  294. HRESULT hr;
  295. CLSID clsID;
  296. MPC::SmartLock<_ThreadModel> lock( this );
  297. // Lets see if the CLSID is valid, if not return error
  298. if(FAILED(hr = ::CLSIDFromString( newVal, &clsID )))
  299. {
  300. DebugLog(L"Not a valid GUID!\r\n");
  301. __MPC_FUNC_LEAVE;
  302. }
  303. // Set the CSAFChannel object member
  304. m_data.m_bstrNotification = newVal;
  305. // Place the Notification GUID into the XML SAFReg
  306. __MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg::s_GLOBAL->UpdateField( m_data, CSAFChannelRecord::SAFREG_Notification ));
  307. hr = S_OK;
  308. __HCP_FUNC_CLEANUP;
  309. __HCP_FUNC_EXIT(hr);
  310. }
  311. /////////////////////////////////////////////////////////////////////////////
  312. STDMETHODIMP CSAFChannel::Incidents( /*[in]*/ IncidentCollectionOptionEnum opt ,
  313. /*[out, retval]*/ IPCHCollection* *ppC )
  314. {
  315. __HCP_FUNC_ENTRY( "CSAFChannel::get_Incidents" );
  316. HRESULT hr;
  317. IterConst it;
  318. CComPtr<CPCHCollection> pColl;
  319. MPC::SmartLock<_ThreadModel> lock( this );
  320. __MPC_PARAMCHECK_BEGIN(hr)
  321. __MPC_PARAMCHECK_POINTER_AND_SET(ppC,NULL);
  322. __MPC_PARAMCHECK_END();
  323. // Check the value of "opt" if other than 0,1,2 flag an error
  324. switch(opt)
  325. {
  326. case pchAllIncidents : break;
  327. case pchOpenIncidents : break;
  328. case pchClosedIncidents: break;
  329. default : __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);// Not a valid Option. Set the error.
  330. }
  331. //
  332. // Create the Enumerator and fill it with items.
  333. //
  334. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pColl ));
  335. for(it = m_lstIncidentItems.begin(); it != m_lstIncidentItems.end(); it++)
  336. {
  337. CSAFIncidentItem* item = *it;
  338. if(item->MatchEnumOption( opt ))
  339. {
  340. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->AddItem( item ));
  341. }
  342. }
  343. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl.QueryInterface( ppC ));
  344. hr = S_OK;
  345. __HCP_FUNC_CLEANUP;
  346. __HCP_FUNC_EXIT(hr);
  347. }
  348. // The following method needs to be in the IncidentItem ideally.
  349. // First take it out from here.
  350. STDMETHODIMP CSAFChannel::RecordIncident( /*[in]*/ BSTR bstrDisplay ,
  351. /*[in]*/ BSTR bstrURL ,
  352. /*[in]*/ VARIANT vProgress ,
  353. /*[in]*/ VARIANT vXMLDataFile ,
  354. /*[in]*/ VARIANT vXMLBlob ,
  355. /*[out]*/ ISAFIncidentItem* *pVal )
  356. {
  357. __HCP_FUNC_ENTRY( "CSAFChannel::RecordIncident" );
  358. HRESULT hr;
  359. CComPtr<CSAFIncidentItem> pItem;
  360. MPC::SmartLock<_ThreadModel> lock( this );
  361. BSTR bstrProgress = (vProgress.vt == VT_BSTR ? vProgress .bstrVal : NULL);
  362. BSTR bstrXMLDataFile = (vXMLDataFile.vt == VT_BSTR ? vXMLDataFile.bstrVal : NULL);
  363. BSTR bstrXMLBlob = (vXMLBlob.vt == VT_BSTR ? vXMLBlob .bstrVal : NULL);
  364. __MPC_EXIT_IF_METHOD_FAILS(hr, Create( bstrDisplay, bstrURL, bstrProgress, bstrXMLDataFile, bstrXMLBlob, &pItem ));
  365. __MPC_EXIT_IF_METHOD_FAILS(hr, pItem.QueryInterface( pVal ));
  366. hr = S_OK;
  367. __HCP_FUNC_CLEANUP;
  368. __HCP_FUNC_EXIT(hr);
  369. }
  370. HRESULT CSAFChannel::RemoveIncidentFromList( /*[in]*/ CSAFIncidentItem* pVal )
  371. {
  372. __HCP_FUNC_ENTRY( "CSAFChannel::RemoveIncidentFromList" );
  373. HRESULT hr;
  374. IterConst it;
  375. MPC::SmartLock<_ThreadModel> lock( this );
  376. // Fire an event to the Notification Object (onIncidentAdded)
  377. __MPC_EXIT_IF_METHOD_FAILS(hr, Fire_NotificationEvent( EVENT_INCIDENTREMOVED, GetSizeIncidentList(), this, pVal, 0 ));
  378. it = Find( pVal->GetRecIndex() );
  379. if(it != m_lstIncidentItems.end())
  380. {
  381. (*it)->Release();
  382. m_lstIncidentItems.erase( it );
  383. }
  384. hr = S_OK;
  385. __HCP_FUNC_CLEANUP;
  386. __HCP_FUNC_EXIT(hr);
  387. }
  388. ////////////////////////////////////////////////////////////////////////////////
  389. /*
  390. Function CSAFChannel::Fire_Notification
  391. Description
  392. This function is used to fire a notification event on the registered notification object.
  393. If there is no notification object, this will do nothing.
  394. Parameters:
  395. Depending on the type of Event you want to fire, different parameters must be filled out.
  396. The following table shows which are the valid parameters for the call. If a parameter
  397. is not valid, it MUST be set to NULL.
  398. iEventType - EVENT_INCIDENTADDED
  399. Valid parameters:
  400. - iCountIncidentInChannel
  401. - pC
  402. - pI
  403. - EVENT_INCIDENTREMOVED
  404. Valid parameters:
  405. - iCountIncidentInChannel
  406. - pC
  407. - pI
  408. - EVENT_INCIDENTUPDATED
  409. Valid parameters:
  410. - iCountIncidentInChannel
  411. - pC
  412. - pI
  413. - EVENT_CHANNELUPDATED
  414. Valid parameters:
  415. - iCountIncidentInChannel
  416. - pC
  417. - dwCode
  418. */
  419. HRESULT CSAFChannel::Fire_NotificationEvent( int iEventType ,
  420. int iCountIncidentInChannel ,
  421. ISAFChannel* pC ,
  422. ISAFIncidentItem* pI ,
  423. DWORD dwCode )
  424. {
  425. __HCP_FUNC_ENTRY( "CSAFChannel::Fire_NotificationEvent" );
  426. HRESULT hr;
  427. PWTS_SESSION_INFO pSessionInfo = NULL;
  428. DWORD dwSessions = 0;
  429. DWORD dwValidSessions = 0;
  430. DWORD dwRetSize = 0;
  431. WINSTATIONINFORMATIONW WSInfo;
  432. CComBSTR bstrCaller;
  433. PSID pSID = NULL;
  434. LPCWSTR szDomain = NULL;
  435. LPCWSTR szLogin = NULL;
  436. CLSID clsID;
  437. ULONG ulRet;
  438. // Check to see if we have a registered Notification Object
  439. if(!m_data.m_bstrNotification || FAILED(::CLSIDFromString( m_data.m_bstrNotification, &clsID )))
  440. {
  441. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  442. }
  443. //
  444. // First lets get the callers Domain and Name by impersonating the caller and grabbing them
  445. //
  446. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetCallerPrincipal( true, bstrCaller ));
  447. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::ConvertPrincipalToSID( bstrCaller, pSID ));
  448. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::ConvertSIDToPrincipal( pSID, &szLogin, &szDomain ));
  449. // Enumerate all sessions on this machine
  450. // -------------------------------------------
  451. // Use WTSEnumerateSessions
  452. // Then find active ones
  453. // Then make the calls to ISAFChannelNotifyIncident
  454. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WTSEnumerateSessions( WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwSessions ))
  455. // Find the active ones and mark them only if they are the correct user
  456. for(DWORD i = 0; i < dwSessions; i++)
  457. {
  458. if(pSessionInfo[i].State == WTSActive) // Got an active session
  459. {
  460. CComPtr<IPCHSlaveProcess> sp;
  461. CComPtr<IUnknown> unk;
  462. CComPtr<ISAFChannelNotifyIncident> chNot;
  463. // Now mark it if the Username and Domain match that of the user
  464. // we are calling for.
  465. memset( &WSInfo, 0, sizeof(WSInfo) );
  466. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WinStationQueryInformationW( SERVERNAME_CURRENT ,
  467. pSessionInfo[i].SessionId ,
  468. WinStationInformation ,
  469. &WSInfo ,
  470. sizeof(WSInfo) ,
  471. &dwRetSize ));
  472. // Now we can fish the userid and domain out of the WSInfo.Domain and WSInfo.UserName
  473. // Now we are ready to compare the domain and username
  474. if((wcscmp( WSInfo.Domain , szDomain ) == 0) &&
  475. (wcscmp( WSInfo.UserName, szLogin ) == 0) )
  476. {
  477. WINSTATIONUSERTOKEN WsUserToken;
  478. // We found the correct sessions, make the calls to ISAFChannelNotifyIncident
  479. WsUserToken.ProcessId = LongToHandle( GetCurrentProcessId() );
  480. WsUserToken.ThreadId = LongToHandle( GetCurrentThreadId () );
  481. // Grab token from SessionID
  482. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WinStationQueryInformationW( WTS_CURRENT_SERVER_HANDLE ,
  483. pSessionInfo[i].SessionId ,
  484. WinStationUserToken ,
  485. &WsUserToken ,
  486. sizeof(WsUserToken) ,
  487. &ulRet ));
  488. // Create the notification object in the session (using the hToken
  489. {
  490. CPCHUserProcess::UserEntry ue;
  491. __MPC_EXIT_IF_METHOD_FAILS(hr, ue.InitializeForImpersonation( WsUserToken.UserToken ));
  492. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHUserProcess::s_GLOBAL->Connect( ue, &sp ));
  493. }
  494. //
  495. // Discard all the failures from the remote objects.
  496. //
  497. ////////////////////////////////////////////////////////////////////////////////
  498. // Use the Slave Process to Create the object which CLSID clsID.
  499. if(FAILED(hr = sp->CreateInstance( clsID, NULL, &unk )))
  500. {
  501. continue;
  502. }
  503. // Grab a pointer to the correct interface
  504. if(FAILED(hr = unk.QueryInterface( &chNot )))
  505. {
  506. continue;
  507. }
  508. // Depending on the type of notification, call the correct event callback
  509. switch(iEventType)
  510. {
  511. case EVENT_INCIDENTADDED : hr = chNot->onIncidentAdded ( pC, pI , iCountIncidentInChannel ); break;
  512. case EVENT_INCIDENTREMOVED: hr = chNot->onIncidentRemoved( pC, pI , iCountIncidentInChannel ); break;
  513. case EVENT_INCIDENTUPDATED: hr = chNot->onIncidentUpdated( pC, pI , iCountIncidentInChannel ); break;
  514. case EVENT_CHANNELUPDATED : hr = chNot->onChannelUpdated ( pC, dwCode, iCountIncidentInChannel ); break;
  515. }
  516. if(FAILED(hr))
  517. {
  518. continue;
  519. }
  520. }
  521. }
  522. }
  523. hr = S_OK;
  524. __HCP_FUNC_CLEANUP;
  525. MPC::SecurityDescriptor::ReleaseMemory( (void *&)pSID );
  526. MPC::SecurityDescriptor::ReleaseMemory( (void *&)szLogin );
  527. MPC::SecurityDescriptor::ReleaseMemory( (void *&)szDomain );
  528. __HCP_FUNC_EXIT(hr);
  529. }