Source code of Windows XP (NT5)
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.

586 lines
15 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // TaskPollingCallback.cpp
  7. //
  8. // Description:
  9. // CTaskPollingCallback implementation.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) 10-JUL-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "pch.h"
  16. #include <ClusCfgPrivate.h>
  17. #include "TaskPollingCallback.h"
  18. DEFINE_THISCLASS("CTaskPollingCallback")
  19. // ************************************************************************
  20. //
  21. // Constructor / Destructor
  22. //
  23. // ************************************************************************
  24. //////////////////////////////////////////////////////////////////////////////
  25. //++
  26. //
  27. // HRESULT
  28. // CTaskPollingCallback::S_HrCreateInstance(
  29. // IUnknown ** ppunkOut
  30. // )
  31. //
  32. //--
  33. //////////////////////////////////////////////////////////////////////////////
  34. HRESULT
  35. CTaskPollingCallback::S_HrCreateInstance(
  36. IUnknown ** ppunkOut
  37. )
  38. {
  39. TraceFunc( "" );
  40. Assert( ppunkOut != NULL );
  41. HRESULT hr = S_FALSE;
  42. CTaskPollingCallback * pTaskPollingCallback = NULL;
  43. if ( ppunkOut == NULL )
  44. {
  45. hr = THR( E_POINTER );
  46. goto Cleanup;
  47. } // if:
  48. pTaskPollingCallback = new CTaskPollingCallback;
  49. if ( pTaskPollingCallback == NULL )
  50. {
  51. hr = E_OUTOFMEMORY;
  52. goto Cleanup;
  53. } // if:
  54. TraceMoveToMemoryList( pTaskPollingCallback, g_GlobalMemoryList );
  55. hr = THR( pTaskPollingCallback->Init() );
  56. if ( FAILED( hr ) )
  57. {
  58. goto Cleanup;
  59. }
  60. hr = THR( pTaskPollingCallback->TypeSafeQI( IUnknown, ppunkOut ) );
  61. Cleanup:
  62. if ( pTaskPollingCallback != NULL )
  63. {
  64. pTaskPollingCallback->Release();
  65. } // if:
  66. HRETURN( hr );
  67. } //*** CTaskPollingCallback::S_HrCreateInstance
  68. //////////////////////////////////////////////////////////////////////////////
  69. //++
  70. //
  71. // CTaskPollingCallback::CTaskPollingCallback( void )
  72. //
  73. //--
  74. //////////////////////////////////////////////////////////////////////////////
  75. CTaskPollingCallback::CTaskPollingCallback( void )
  76. : m_cRef( 1 )
  77. {
  78. TraceFunc( "" );
  79. InterlockedIncrement( &g_cObjects );
  80. Assert( m_fStop == false );
  81. Assert( m_dwServerGITCookie == NULL );
  82. TraceFuncExit();
  83. } //*** CTaskPollingCallback::CTaskPollingCallback
  84. //////////////////////////////////////////////////////////////////////////////
  85. //++
  86. //
  87. // STDMETHODIMP
  88. // CTaskPollingCallback::Init( void )
  89. //
  90. //--
  91. //////////////////////////////////////////////////////////////////////////////
  92. STDMETHODIMP
  93. CTaskPollingCallback::Init( void )
  94. {
  95. TraceFunc( "" );
  96. HRESULT hr = S_OK;
  97. HRETURN( hr );
  98. } //*** CTaskPollingCallback::Init
  99. //////////////////////////////////////////////////////////////////////////////
  100. //++
  101. //
  102. // CTaskPollingCallback::~CTaskPollingCallback( void )
  103. //
  104. //--
  105. //////////////////////////////////////////////////////////////////////////////
  106. CTaskPollingCallback::~CTaskPollingCallback( void )
  107. {
  108. TraceFunc( "" );
  109. TraceMoveFromMemoryList( this, g_GlobalMemoryList );
  110. InterlockedDecrement( &g_cObjects );
  111. TraceFuncExit();
  112. } //*** CTaskPollingCallback::~CTaskPollingCallback
  113. // ************************************************************************
  114. //
  115. // IUnknown
  116. //
  117. // ************************************************************************
  118. //////////////////////////////////////////////////////////////////////////////
  119. //++
  120. //
  121. // STDMETHODIMP
  122. // CTaskPollingCallback::QueryInterface(
  123. // REFIID riidIn,
  124. // LPVOID * ppvOut
  125. // )
  126. //
  127. //--
  128. //////////////////////////////////////////////////////////////////////////////
  129. STDMETHODIMP
  130. CTaskPollingCallback::QueryInterface(
  131. REFIID riidIn,
  132. LPVOID * ppvOut
  133. )
  134. {
  135. TraceQIFunc( riidIn, ppvOut );
  136. HRESULT hr = E_NOINTERFACE;
  137. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  138. {
  139. *ppvOut = static_cast< ITaskPollingCallback * >( this );
  140. hr = S_OK;
  141. } // if: IUnknown
  142. else if ( IsEqualIID( riidIn, IID_ITaskPollingCallback ) )
  143. {
  144. *ppvOut = TraceInterface( __THISCLASS__, ITaskPollingCallback, this, 0 );
  145. hr = S_OK;
  146. } // else if: ITaskPollingCallback
  147. else if ( IsEqualIID( riidIn, IID_IDoTask ) )
  148. {
  149. *ppvOut = TraceInterface( __THISCLASS__, IDoTask, this, 0 );
  150. hr = S_OK;
  151. } // else if: IDoTask
  152. if ( SUCCEEDED( hr ) )
  153. {
  154. ((IUnknown*) *ppvOut)->AddRef();
  155. } // if: success
  156. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  157. } // QueryInterface
  158. //////////////////////////////////////////////////////////////////////////////
  159. //++
  160. //
  161. // STDMETHODIMP_( ULONG )
  162. // CTaskPollingCallback::AddRef( void )
  163. //
  164. //--
  165. //////////////////////////////////////////////////////////////////////////////
  166. STDMETHODIMP_( ULONG )
  167. CTaskPollingCallback::AddRef( void )
  168. {
  169. TraceFunc( "[IUnknown]" );
  170. InterlockedIncrement( &m_cRef );
  171. RETURN( m_cRef );
  172. } //*** CTaskPollingCallback::AddRef
  173. //////////////////////////////////////////////////////////////////////////////
  174. //++
  175. //
  176. // STDMETHODIMP_( ULONG )
  177. // CTaskPollingCallback::Release( void )
  178. //
  179. //--
  180. //////////////////////////////////////////////////////////////////////////////
  181. STDMETHODIMP_( ULONG )
  182. CTaskPollingCallback::Release( void )
  183. {
  184. TraceFunc( "[IUnknown]" );
  185. InterlockedDecrement( &m_cRef );
  186. if ( m_cRef )
  187. RETURN( m_cRef );
  188. TraceDo( delete this );
  189. RETURN( 0 );
  190. } //*** CTaskPollingCallback::Release
  191. //****************************************************************************
  192. //
  193. // ITaskPollingCallback
  194. //
  195. //****************************************************************************
  196. //////////////////////////////////////////////////////////////////////////////
  197. //++
  198. //
  199. // STDMETHODIMP
  200. // CTaskPollingCallback::BeginTask( void )
  201. //
  202. //--
  203. //////////////////////////////////////////////////////////////////////////////
  204. STDMETHODIMP
  205. CTaskPollingCallback::BeginTask( void )
  206. {
  207. TraceFunc( "[IDoTask]" );
  208. HRESULT hr = S_OK;
  209. BSTR bstrNodeName = NULL;
  210. BSTR bstrLastNodeName = NULL;
  211. BSTR bstrReference = NULL;
  212. BSTR bstrDescription = NULL;
  213. CLSID clsidTaskMajor;
  214. CLSID clsidTaskMinor;
  215. ULONG ulMin;
  216. ULONG ulMax;
  217. ULONG ulCurrent;
  218. HRESULT hrStatus;
  219. FILETIME ft;
  220. IGlobalInterfaceTable * pgit = NULL;
  221. IClusCfgServer * pccs = NULL;
  222. IClusCfgPollingCallback * piccpc = NULL;
  223. IClusCfgPollingCallbackInfo * piccpci = NULL;
  224. IServiceProvider * psp = NULL;
  225. IConnectionPointContainer * pcpc = NULL;
  226. IConnectionPoint * pcp = NULL;
  227. IClusCfgCallback * pcccb = NULL;
  228. //
  229. // Collect the manager we need to complete this task.
  230. //
  231. hr = THR( CoCreateInstance( CLSID_ServiceManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IServiceProvider, &psp ) ) );
  232. if ( FAILED( hr ) )
  233. goto Cleanup;
  234. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager, IConnectionPointContainer, &pcpc ) );
  235. if ( FAILED( hr ) )
  236. goto Cleanup;
  237. hr = THR( pcpc->FindConnectionPoint( IID_IClusCfgCallback, &pcp ) );
  238. if ( FAILED( hr ) )
  239. goto Cleanup;
  240. pcp = TraceInterface( L"CConfigurationConnection!IConnectionPoint", IConnectionPoint, pcp, 1 );
  241. hr = THR( pcp->TypeSafeQI( IClusCfgCallback, &pcccb ) );
  242. if ( FAILED( hr ) )
  243. goto Cleanup;
  244. pcccb = TraceInterface( L"CConfigurationConnection!IClusCfgCallback", IClusCfgCallback, pcccb, 1 );
  245. psp->Release();
  246. psp = NULL;
  247. //
  248. // Create the GIT.
  249. //
  250. hr = THR( CoCreateInstance( CLSID_StdGlobalInterfaceTable,
  251. NULL,
  252. CLSCTX_INPROC_SERVER,
  253. IID_IGlobalInterfaceTable,
  254. reinterpret_cast< void ** >( &pgit )
  255. ) );
  256. if ( FAILED( hr ) )
  257. {
  258. goto Cleanup;
  259. } // if
  260. //
  261. // Get the ClusCfgServer interface from the GIT.
  262. //
  263. hr = THR( pgit->GetInterfaceFromGlobal( m_dwServerGITCookie, IID_IClusCfgServer, reinterpret_cast< void ** >( &pccs ) ) );
  264. if ( FAILED( hr ) )
  265. {
  266. goto Cleanup;
  267. } // if
  268. //
  269. // Get the PollingCallback object from the server.
  270. //
  271. hr = THR( pccs->TypeSafeQI( IClusCfgPollingCallbackInfo, &piccpci ) );
  272. if ( FAILED( hr ) )
  273. {
  274. goto Cleanup;
  275. } // if
  276. hr = THR( piccpci->GetCallback( &piccpc ) );
  277. if ( FAILED( hr ) )
  278. {
  279. goto Cleanup;
  280. } // if
  281. //
  282. // Begin polling for SendStatusReports.
  283. //
  284. while ( !m_fStop )
  285. {
  286. if ( bstrNodeName != NULL )
  287. {
  288. TraceSysFreeString( bstrLastNodeName );
  289. bstrLastNodeName = NULL;
  290. // Give up ownership
  291. bstrLastNodeName = bstrNodeName;
  292. bstrNodeName = NULL;
  293. } // if:
  294. TraceSysFreeString( bstrDescription );
  295. bstrDescription = NULL;
  296. TraceSysFreeString( bstrReference );
  297. bstrReference = NULL;
  298. hr = STHR( piccpc->GetStatusReport(
  299. &bstrNodeName,
  300. &clsidTaskMajor,
  301. &clsidTaskMinor,
  302. &ulMin,
  303. &ulMax,
  304. &ulCurrent,
  305. &hrStatus,
  306. &bstrDescription,
  307. &ft,
  308. &bstrReference
  309. ) );
  310. TraceMemoryAddBSTR( bstrNodeName );
  311. TraceMemoryAddBSTR( bstrDescription );
  312. TraceMemoryAddBSTR( bstrReference );
  313. if ( FAILED( hr ) )
  314. {
  315. HRESULT hr2;
  316. BSTR bstrNotification = NULL;
  317. LogMsg( L"PollingCallback: GetStatusReport() failed. hr = 0x%08x", hr );
  318. hr2 = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_POLLING_CONNECTION_FAILURE, &bstrNotification ) );
  319. hr2 = THR( pcccb->SendStatusReport(
  320. bstrLastNodeName
  321. , TASKID_Major_Establish_Connection
  322. , TASKID_Minor_Polling_Connection_Failure
  323. , 0
  324. , 1
  325. , 0
  326. , hr
  327. , bstrNotification
  328. , NULL
  329. , NULL
  330. ) );
  331. TraceSysFreeString( bstrNotification );
  332. switch ( hr )
  333. {
  334. case S_OK:
  335. case S_FALSE:
  336. break; // ignore
  337. case HRESULT_FROM_WIN32( RPC_E_DISCONNECTED ):
  338. LogMsg( L"PollingCallback: GetStatusReport() failed. hr = RPC_E_DISCONNECTED. Aborting polling.", hr );
  339. goto Cleanup;
  340. case HRESULT_FROM_WIN32( RPC_S_SERVER_UNAVAILABLE ):
  341. LogMsg( L"PollingCallback: GetStatusReport() failed. hr = RPC_S_SERVER_UNAVAILABLE. Aborting polling.", hr );
  342. goto Cleanup;
  343. case HRESULT_FROM_WIN32( RPC_S_CALL_FAILED ):
  344. LogMsg( L"PollingCallback: GetStatusReport() failed. hr = RPC_S_CALL_FAILED. Aborting polling.", hr );
  345. goto Cleanup;
  346. default:
  347. LogMsg( L"PollingCallback: GetStatusReport() failed. hr = %#08x. Continuing to poll.", hr );
  348. break;
  349. }
  350. if ( hr2 == E_ABORT )
  351. {
  352. LogMsg( L"PollingCallback: UI layer returned E_ABORT. Aborting polling." );
  353. break;
  354. }
  355. } // if:
  356. if ( hr == S_OK )
  357. {
  358. HRESULT hrTmp;
  359. hr = THR( pcccb->SendStatusReport(
  360. bstrNodeName,
  361. clsidTaskMajor,
  362. clsidTaskMinor,
  363. ulMin,
  364. ulMax,
  365. ulCurrent,
  366. hrStatus,
  367. bstrDescription,
  368. &ft,
  369. bstrReference
  370. ) );
  371. if ( hr == E_ABORT )
  372. {
  373. LogMsg( L"PollingCallback: UI layer returned E_ABORT. Aborting polling." );
  374. }
  375. hrTmp = hr;
  376. hr = THR( piccpc->SetHResult( hrTmp ) );
  377. if ( FAILED( hr ) )
  378. {
  379. LogMsg( L"PollingCallback: SetHResult() failed. hr = 0x%08x", hr );
  380. } // if:
  381. } // if:
  382. else
  383. {
  384. Sleep( 1000 );
  385. //
  386. // Check to see if we need to bail.
  387. //
  388. hr = THR( CServiceManager::S_HrGetManagerPointer( &psp ) );
  389. if ( FAILED( hr ) )
  390. break;
  391. psp->Release();
  392. psp = NULL;
  393. }
  394. } // while:
  395. Cleanup:
  396. if ( psp != NULL )
  397. {
  398. psp->Release();
  399. } // if:
  400. if ( pgit != NULL )
  401. {
  402. pgit->Release();
  403. } // if:
  404. if ( pccs != NULL )
  405. {
  406. pccs->Release();
  407. } // if:
  408. if ( piccpc != NULL )
  409. {
  410. piccpc->Release();
  411. } // if:
  412. if ( piccpci != NULL )
  413. {
  414. piccpci->Release();
  415. } // if:
  416. if ( pcpc != NULL )
  417. {
  418. pcpc->Release();
  419. } // if:
  420. if ( pcp != NULL )
  421. {
  422. pcp->Release();
  423. } // if:
  424. if ( pcccb != NULL )
  425. {
  426. pcccb->Release();
  427. } // if:
  428. TraceSysFreeString( bstrNodeName );
  429. TraceSysFreeString( bstrDescription );
  430. TraceSysFreeString( bstrReference );
  431. TraceSysFreeString( bstrLastNodeName );
  432. HRETURN( hr );
  433. } //*** CTaskPollingCallback::BeginTask
  434. //////////////////////////////////////////////////////////////////////////////
  435. //++
  436. //
  437. // STDMETHODIMP
  438. // CTaskPollingCallback::StopTask( void )
  439. //
  440. //--
  441. //////////////////////////////////////////////////////////////////////////////
  442. STDMETHODIMP
  443. CTaskPollingCallback::StopTask( void )
  444. {
  445. TraceFunc( "[IDoTask]" );
  446. HRESULT hr = S_OK;
  447. m_fStop = true;
  448. HRETURN( hr );
  449. } //*** CTaskPollingCallback::StopTask
  450. //////////////////////////////////////////////////////////////////////////////
  451. //++
  452. //
  453. // STDMETHODIMP
  454. // CTaskPollingCallback::SetServerGITCookie(
  455. // DWORD dwGITCookieIn
  456. // )
  457. //
  458. //--
  459. //////////////////////////////////////////////////////////////////////////////
  460. STDMETHODIMP
  461. CTaskPollingCallback::SetServerGITCookie(
  462. DWORD dwGITCookieIn
  463. )
  464. {
  465. TraceFunc( "[ITaskPollingCallback]" );
  466. HRESULT hr = S_OK;
  467. m_dwServerGITCookie = dwGITCookieIn;
  468. HRETURN( hr );
  469. } //*** CTaskPollingCallback::SetServerGITCookie