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.

748 lines
21 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. Slave.cpp
  5. Abstract:
  6. File for Implementation of CPCHMasterSlave and CPCHUserProcess classes,
  7. used to establish a connection between the service and a slave process.
  8. Revision History:
  9. Davide Massarenti created 03/28/2000
  10. ********************************************************************/
  11. #include "stdafx.h"
  12. #include <UserEnv.h>
  13. /////////////////////////////////////////////////////////////////////////////
  14. static const WCHAR c_HelpHost[] = HC_ROOT_HELPSVC_BINARIES L"\\HelpHost.exe";
  15. static const DWORD c_Timeout = 100 * 1000;
  16. /////////////////////////////////////////////////////////////////////////////
  17. CPCHUserProcess::UserEntry::UserEntry()
  18. {
  19. // CComBSTR m_bstrUser
  20. m_dwSessionID = 0; // DWORD m_dwSessionID;
  21. //
  22. // CComBSTR m_bstrVendorID;
  23. // CComBSTR m_bstrPublicKey;
  24. //
  25. // GUID m_guid;
  26. // CComPtr<IPCHSlaveProcess> m_spConnection;
  27. m_hToken = NULL; // HANDLE m_hToken;
  28. m_hProcess = NULL; // HANDLE m_hProcess;
  29. m_phEvent = NULL; // HANDLE* m_phEvent;
  30. ::ZeroMemory( &m_guid, sizeof(m_guid) );
  31. }
  32. CPCHUserProcess::UserEntry::~UserEntry()
  33. {
  34. Cleanup();
  35. }
  36. void CPCHUserProcess::UserEntry::Cleanup()
  37. {
  38. m_bstrUser .Empty ();
  39. m_dwSessionID = 0;
  40. m_bstrVendorID .Empty ();
  41. m_bstrPublicKey.Empty ();
  42. m_spConnection .Release();
  43. if(m_hProcess)
  44. {
  45. ::CloseHandle( m_hProcess ); m_hProcess = NULL;
  46. }
  47. if(m_hToken)
  48. {
  49. ::CloseHandle( m_hToken ); m_hToken = NULL;
  50. }
  51. }
  52. ////////////////////
  53. bool CPCHUserProcess::UserEntry::operator==( /*[in]*/ const UserEntry& ue ) const
  54. {
  55. if(ue.m_bstrUser)
  56. {
  57. if(m_bstrUser == ue.m_bstrUser && m_dwSessionID == ue.m_dwSessionID) return true;
  58. }
  59. if(ue.m_bstrVendorID)
  60. {
  61. if(MPC::StrICmp( m_bstrVendorID, ue.m_bstrVendorID ) == 0) return true;
  62. }
  63. return false;
  64. }
  65. bool CPCHUserProcess::UserEntry::operator==( /*[in]*/ const GUID& guid ) const
  66. {
  67. return ::IsEqualGUID( m_guid, guid ) ? true : false;
  68. }
  69. ////////////////////
  70. HRESULT CPCHUserProcess::UserEntry::Clone( /*[in]*/ const UserEntry& ue )
  71. {
  72. __HCP_FUNC_ENTRY( "CPCHUserProcess::UserEntry::Clone" );
  73. HRESULT hr;
  74. Cleanup();
  75. m_bstrUser = ue.m_bstrUser; // CComBSTR m_bstrUser;
  76. m_dwSessionID = ue.m_dwSessionID; // DWORD m_dwSessionID;
  77. //
  78. m_bstrVendorID = ue.m_bstrVendorID; // CComBSTR m_bstrVendorID;
  79. m_bstrPublicKey = ue.m_bstrPublicKey; // CComBSTR m_bstrPublicKey;
  80. //
  81. // GUID m_guid; // Used for establishing the connection.
  82. // CComPtr<IPCHSlaveProcess> m_spConnection; // Live object.
  83. // HANDLE m_hToken; // User token.
  84. // HANDLE m_hProcess; // Process handle.
  85. // HANDLE* m_phEvent; // To notify activator.
  86. if(ue.m_hToken)
  87. {
  88. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::DuplicateTokenEx( ue.m_hToken, 0, NULL, SecurityImpersonation, TokenPrimary, &m_hToken ));
  89. }
  90. hr = S_OK;
  91. __HCP_FUNC_CLEANUP;
  92. __HCP_FUNC_EXIT(hr);
  93. }
  94. HRESULT CPCHUserProcess::UserEntry::Connect( /*[out]*/ HANDLE& hEvent )
  95. {
  96. __HCP_FUNC_ENTRY( "CPCHUserProcess::UserEntry::Connect" );
  97. HRESULT hr;
  98. //
  99. // Logon the user, if not already done.
  100. //
  101. if(m_hToken == NULL)
  102. {
  103. CPCHAccounts acc;
  104. LPCWSTR szUser = SAFEBSTR( m_bstrUser );
  105. //// // DEBUG
  106. //// // DEBUG
  107. //// // DEBUG
  108. //// __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::OpenProcessToken( ::GetCurrentProcess(), TOKEN_ALL_ACCESS, &m_hToken ));
  109. //
  110. // Only keep the account enabled for the time it takes to create its token.
  111. //
  112. __MPC_EXIT_IF_METHOD_FAILS(hr, acc.ChangeUserStatus( szUser, /*fEnable*/true ));
  113. __MPC_EXIT_IF_METHOD_FAILS(hr, acc.LogonUser ( szUser, NULL, m_hToken ));
  114. __MPC_EXIT_IF_METHOD_FAILS(hr, acc.ChangeUserStatus( szUser, /*fEnable*/false ));
  115. }
  116. if(m_hProcess == NULL ||
  117. m_spConnection == NULL )
  118. {
  119. __MPC_EXIT_IF_METHOD_FAILS(hr, SendActivation( hEvent ));
  120. }
  121. hr = S_OK;
  122. __HCP_FUNC_CLEANUP;
  123. __HCP_FUNC_EXIT(hr);
  124. }
  125. HRESULT CPCHUserProcess::UserEntry::SendActivation( /*[out]*/ HANDLE& hEvent )
  126. {
  127. __HCP_FUNC_ENTRY( "CPCHUserProcess::UserEntry::SendActivation" );
  128. HRESULT hr;
  129. DWORD dwRes;
  130. PROCESS_INFORMATION piProcessInformation;
  131. STARTUPINFOW siStartupInfo;
  132. VOID* pEnvBlock = NULL;
  133. MPC::wstring strExe( c_HelpHost ); MPC::SubstituteEnvVariables( strExe );
  134. WCHAR rgCommandLine[1024];
  135. ::ZeroMemory( (PVOID)&piProcessInformation, sizeof( piProcessInformation ) );
  136. ::ZeroMemory( (PVOID)&siStartupInfo , sizeof( siStartupInfo ) ); siStartupInfo.cb = sizeof( siStartupInfo );
  137. //
  138. // Generate random ID.
  139. //
  140. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateGuid( &m_guid ));
  141. //
  142. // Create event.
  143. //
  144. __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL )));
  145. //
  146. // Create process as user.
  147. //
  148. {
  149. CComBSTR bstrGUID( m_guid );
  150. swprintf( rgCommandLine, L"\"%s\" -guid %s", strExe.c_str(), (BSTR)bstrGUID );
  151. }
  152. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CreateEnvironmentBlock( &pEnvBlock, m_hToken, TRUE ));
  153. //// // DEBUG
  154. //// // DEBUG
  155. //// // DEBUG
  156. //// __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CreateProcessW( NULL,
  157. //// rgCommandLine,
  158. //// NULL,
  159. //// NULL,
  160. //// FALSE,
  161. //// NORMAL_PRIORITY_CLASS,
  162. //// NULL,
  163. //// NULL,
  164. //// &siStartupInfo,
  165. //// &piProcessInformation ));
  166. // REAL
  167. // REAL
  168. // REAL
  169. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CreateProcessAsUserW( m_hToken ,
  170. NULL ,
  171. rgCommandLine ,
  172. NULL ,
  173. NULL ,
  174. FALSE ,
  175. NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT ,
  176. pEnvBlock ,
  177. NULL ,
  178. &siStartupInfo ,
  179. &piProcessInformation ));
  180. m_hProcess = piProcessInformation.hProcess; piProcessInformation.hProcess = NULL;
  181. hr = S_OK;
  182. __HCP_FUNC_CLEANUP;
  183. if(pEnvBlock) ::DestroyEnvironmentBlock( pEnvBlock );
  184. if(piProcessInformation.hProcess) ::CloseHandle( piProcessInformation.hProcess );
  185. if(piProcessInformation.hThread ) ::CloseHandle( piProcessInformation.hThread );
  186. __HCP_FUNC_EXIT(hr);
  187. }
  188. ////////////////////
  189. HRESULT CPCHUserProcess::UserEntry::InitializeForVendorAccount( /*[in]*/ BSTR bstrUser ,
  190. /*[in]*/ BSTR bstrVendorID ,
  191. /*[in]*/ BSTR bstrPublicKey )
  192. {
  193. __HCP_FUNC_ENTRY( "CPCHUserProcess::UserEntry::InitializeForVendorAccount" );
  194. HRESULT hr;
  195. Cleanup();
  196. m_bstrUser = bstrUser;
  197. m_bstrVendorID = bstrVendorID;
  198. m_bstrPublicKey = bstrPublicKey;
  199. hr = S_OK;
  200. __HCP_FUNC_EXIT(hr);
  201. }
  202. HRESULT CPCHUserProcess::UserEntry::InitializeForImpersonation( /*[in]*/ HANDLE hToken )
  203. {
  204. __HCP_FUNC_ENTRY( "CPCHUserProcess::UserEntry::InitializeForImpersonation" );
  205. HRESULT hr;
  206. MPC::Impersonation imp;
  207. MPC::wstring strUser;
  208. DWORD dwSize;
  209. PSID pUserSid = NULL;
  210. if(hToken == NULL)
  211. {
  212. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize( MAXIMUM_ALLOWED ));
  213. hToken = imp;
  214. }
  215. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::DuplicateTokenEx( hToken, 0, NULL, SecurityImpersonation, TokenPrimary, &m_hToken ));
  216. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::GetTokenInformation( m_hToken, TokenSessionId, &m_dwSessionID, sizeof(m_dwSessionID), &dwSize ));
  217. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::GetTokenSids ( m_hToken, &pUserSid, NULL ));
  218. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::ConvertSIDToPrincipal( pUserSid, strUser )); m_bstrUser = strUser.c_str();
  219. hr = S_OK;
  220. __HCP_FUNC_CLEANUP;
  221. MPC::SecurityDescriptor::ReleaseMemory( pUserSid );
  222. __HCP_FUNC_EXIT(hr);
  223. }
  224. /////////////////////////////////////////////////////////////////////////////
  225. /////////////////////////////////////////////////////////////////////////////
  226. CPCHUserProcess::CPCHUserProcess()
  227. {
  228. // List m_lst;
  229. (void)MPC::_MPC_Module.RegisterCallback( this, (void (CPCHUserProcess::*)())Shutdown );
  230. }
  231. CPCHUserProcess::~CPCHUserProcess()
  232. {
  233. MPC::CallDestructorForAll( m_lst );
  234. MPC::_MPC_Module.UnregisterCallback( this );
  235. }
  236. ////////////////////
  237. CPCHUserProcess* CPCHUserProcess::s_GLOBAL( NULL );
  238. HRESULT CPCHUserProcess::InitializeSystem()
  239. {
  240. if(s_GLOBAL == NULL)
  241. {
  242. s_GLOBAL = new CPCHUserProcess;
  243. }
  244. return s_GLOBAL ? S_OK : E_OUTOFMEMORY;
  245. }
  246. void CPCHUserProcess::FinalizeSystem()
  247. {
  248. if(s_GLOBAL)
  249. {
  250. delete s_GLOBAL; s_GLOBAL = NULL;
  251. }
  252. }
  253. ////////////////////////////////////////////////////////////////////////////////
  254. void CPCHUserProcess::Shutdown()
  255. {
  256. __HCP_FUNC_ENTRY( "CPCHUserProcess::Shutdown" );
  257. MPC::SmartLock<_ThreadModel> lock( this );
  258. m_lst.clear();
  259. }
  260. CPCHUserProcess::UserEntry* CPCHUserProcess::Lookup( /*[in]*/ const UserEntry& ue, /*[in]*/ bool fRelease )
  261. {
  262. UserEntry* ueReal;
  263. //
  264. // Locate vendor and connect to it.
  265. //
  266. for(Iter it = m_lst.begin(); it != m_lst.end(); )
  267. {
  268. ueReal = *it;
  269. if(ueReal && *ueReal == ue)
  270. {
  271. if(fRelease)
  272. {
  273. delete ueReal;
  274. m_lst.erase( it++ ); continue;
  275. }
  276. else
  277. {
  278. return ueReal;
  279. }
  280. }
  281. it++;
  282. }
  283. return NULL;
  284. }
  285. HRESULT CPCHUserProcess::Remove( /*[in]*/ const UserEntry& ue )
  286. {
  287. __HCP_FUNC_ENTRY( "CPCHUserProcess::Remove" );
  288. HRESULT hr;
  289. MPC::SmartLock<_ThreadModel> lock( this );
  290. (void)Lookup( ue, /*fRelease*/true );
  291. hr = S_OK;
  292. __HCP_FUNC_EXIT(hr);
  293. }
  294. HRESULT CPCHUserProcess::Connect( /*[in ]*/ const UserEntry& ue ,
  295. /*[out]*/ IPCHSlaveProcess* *spConnection )
  296. {
  297. __HCP_FUNC_ENTRY( "CPCHUserProcess::Connect" );
  298. HRESULT hr;
  299. MPC::SmartLock<_ThreadModel> lock( this );
  300. HANDLE hEvent = NULL;
  301. UserEntry* ueReal = NULL;
  302. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHUserProcess::Connect" );
  303. //
  304. // Locate vendor and connect to it.
  305. //
  306. ueReal = Lookup( ue, /*fRelease*/false );
  307. if(ueReal == NULL)
  308. {
  309. __MPC_EXIT_IF_ALLOC_FAILS(hr, ueReal, new UserEntry);
  310. m_lst.push_back( ueReal );
  311. __MPC_EXIT_IF_METHOD_FAILS(hr, ueReal->Clone( ue ));
  312. }
  313. __MPC_EXIT_IF_METHOD_FAILS(hr, ueReal->Connect( hEvent ));
  314. //
  315. // If "Connect" returns an event handle, wait on it.
  316. //
  317. if(hEvent)
  318. {
  319. ueReal->m_phEvent = &hEvent; // For waiting response...
  320. lock = NULL;
  321. if(::WaitForSingleObject( hEvent, c_Timeout ) != WAIT_OBJECT_0)
  322. {
  323. __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  324. }
  325. lock = this;
  326. //
  327. // Relocate vendor (we release the lock on the object, so "ueReal" is not valid anymore.
  328. //
  329. ueReal = Lookup( ue, /*fRelease*/false );
  330. if(ueReal == NULL)
  331. {
  332. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_FILE_NOT_FOUND);
  333. }
  334. }
  335. __MPC_EXIT_IF_METHOD_FAILS(hr, ueReal->m_spConnection.QueryInterface( spConnection ));
  336. hr = S_OK;
  337. __HCP_FUNC_CLEANUP;
  338. if(hEvent) ::CloseHandle( hEvent );
  339. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHUserProcess::Connect - done" );
  340. __HCP_FUNC_EXIT(hr);
  341. }
  342. HRESULT CPCHUserProcess::RegisterHost( /*[in]*/ BSTR bstrID ,
  343. /*[in]*/ IPCHSlaveProcess* pObj )
  344. {
  345. __HCP_FUNC_ENTRY( "CPCHUserProcess::RegisterHost" );
  346. HRESULT hr;
  347. MPC::SmartLock<_ThreadModel> lock( this );
  348. UserEntry* ueReal = NULL;
  349. GUID guid;
  350. //
  351. // Validate input.
  352. //
  353. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CLSIDFromString( bstrID, &guid ));
  354. //
  355. // Locate vendor and connect to it.
  356. //
  357. for(Iter it = m_lst.begin(); it != m_lst.end(); it++)
  358. {
  359. ueReal = *it;
  360. if(ueReal && *ueReal == guid)
  361. {
  362. break;
  363. }
  364. }
  365. if(ueReal == NULL)
  366. {
  367. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_FILE_NOT_FOUND);
  368. }
  369. __MPC_EXIT_IF_METHOD_FAILS(hr, pObj->Initialize( ueReal->m_bstrVendorID, ueReal->m_bstrPublicKey ));
  370. ueReal->m_spConnection = pObj;
  371. hr = S_OK;
  372. __HCP_FUNC_CLEANUP;
  373. if(ueReal)
  374. {
  375. if(ueReal->m_phEvent)
  376. {
  377. //
  378. // Signal the event handle, to awake the activator.
  379. //
  380. ::SetEvent( *(ueReal->m_phEvent) );
  381. ueReal->m_phEvent = NULL;
  382. }
  383. }
  384. __HCP_FUNC_EXIT(hr);
  385. }
  386. ////////////////////////////////////////////////////////////////////////////////
  387. ////////////////////////////////////////////////////////////////////////////////
  388. HRESULT CPCHUserProcess::SendResponse( /*[in]*/ DWORD dwArgc ,
  389. /*[in]*/ LPCWSTR* lpszArgv )
  390. {
  391. __HCP_FUNC_ENTRY( "CPCHUserProcess::SendResponse" );
  392. HRESULT hr;
  393. int i;
  394. CComBSTR bstrGUID;
  395. CComPtr<IPCHService> srv;
  396. CComPtr<CPCHSlaveProcess> obj;
  397. #ifdef DEBUG
  398. bool fDebug = false;
  399. #endif
  400. //
  401. // Parse the arguments.
  402. //
  403. for(i=1; i<dwArgc; i++)
  404. {
  405. LPCWSTR szArg = lpszArgv[i];
  406. if(szArg[0] == '-' ||
  407. szArg[0] == '/' )
  408. {
  409. szArg++;
  410. if(_wcsicmp( szArg, L"guid" ) == 0 && (i<dwArgc-1))
  411. {
  412. bstrGUID = lpszArgv[++i];
  413. continue;
  414. }
  415. #ifdef DEBUG
  416. if(_wcsicmp( szArg, L"debug" ) == 0)
  417. {
  418. fDebug = true;
  419. continue;
  420. }
  421. #endif
  422. }
  423. __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  424. }
  425. #ifdef DEBUG
  426. if(fDebug) DebugBreak();
  427. #endif
  428. //
  429. // Create the COM object.
  430. //
  431. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &obj ));
  432. //
  433. // Register it with the service.
  434. //
  435. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_PCHService, NULL, CLSCTX_ALL, IID_IPCHService, (void**)&srv ));
  436. __MPC_EXIT_IF_METHOD_FAILS(hr, srv->RegisterHost( bstrGUID, obj ));
  437. hr = S_OK;
  438. __HCP_FUNC_CLEANUP;
  439. __HCP_FUNC_EXIT(hr);
  440. }
  441. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  442. CPCHSlaveProcess::CPCHSlaveProcess()
  443. {
  444. // CComBSTR m_bstrVendorID;
  445. // CComBSTR m_bstrPublicKey;
  446. m_ScriptLauncher = NULL; // CPCHScriptWrapper_Launcher* m_ScriptLauncher;
  447. }
  448. CPCHSlaveProcess::~CPCHSlaveProcess()
  449. {
  450. delete m_ScriptLauncher;
  451. }
  452. HRESULT CPCHSlaveProcess::Initialize( /*[in]*/ BSTR bstrVendorID, /*[in]*/ BSTR bstrPublicKey )
  453. {
  454. m_bstrVendorID = bstrVendorID;
  455. m_bstrPublicKey = bstrPublicKey;
  456. return S_OK;
  457. }
  458. HRESULT CPCHSlaveProcess::CreateInstance( /*[in ]*/ REFCLSID rclsid ,
  459. /*[in ]*/ IUnknown* pUnkOuter ,
  460. /*[out]*/ IUnknown* *ppvObject )
  461. {
  462. HRESULT hr;
  463. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::CreateInstance" );
  464. hr = ::CoCreateInstance( rclsid, pUnkOuter, CLSCTX_ALL, IID_IUnknown, (void**)ppvObject );
  465. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::CreateInstance - done" );
  466. return hr;
  467. }
  468. HRESULT CPCHSlaveProcess::CreateScriptWrapper( /*[in ]*/ REFCLSID rclsid ,
  469. /*[in ]*/ BSTR bstrCode ,
  470. /*[in ]*/ BSTR bstrURL ,
  471. /*[out]*/ IUnknown* *ppObj )
  472. {
  473. __HCP_FUNC_ENTRY( "CPCHSlaveProcess::CreateScriptWrapper" );
  474. HRESULT hr;
  475. MPC::SmartLock<_ThreadModel> lock( this );
  476. if(!m_ScriptLauncher)
  477. {
  478. __MPC_EXIT_IF_ALLOC_FAILS(hr, m_ScriptLauncher, new CPCHScriptWrapper_Launcher);
  479. }
  480. __MPC_EXIT_IF_METHOD_FAILS(hr, m_ScriptLauncher->CreateScriptWrapper( rclsid, bstrCode, bstrURL, ppObj ));
  481. hr = S_OK;
  482. __HCP_FUNC_CLEANUP;
  483. __HCP_FUNC_EXIT(hr);
  484. }
  485. HRESULT CPCHSlaveProcess::OpenBlockingStream( /*[in ]*/ BSTR bstrURL ,
  486. /*[out]*/ IUnknown* *ppvObject )
  487. {
  488. __HCP_FUNC_ENTRY( "CPCHSlaveProcess::OpenBlockingStream" );
  489. HRESULT hr;
  490. CComPtr<IStream> stream;
  491. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::OpenBlockingStream" );
  492. __MPC_EXIT_IF_METHOD_FAILS(hr, URLOpenBlockingStreamW( NULL, bstrURL, &stream, 0, NULL ));
  493. __MPC_EXIT_IF_METHOD_FAILS(hr, stream.QueryInterface( ppvObject ));
  494. hr = S_OK;
  495. __HCP_FUNC_CLEANUP;
  496. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::OpenBlockingStream - done" );
  497. __HCP_FUNC_EXIT(hr);
  498. }
  499. HRESULT CPCHSlaveProcess::IsNetworkAlive( /*[out]*/ VARIANT_BOOL* pfRetVal )
  500. {
  501. __HCP_FUNC_ENTRY( "CPCHSlaveProcess::IsNetworkAlive" );
  502. HRESULT hr;
  503. __MPC_PARAMCHECK_BEGIN(hr)
  504. __MPC_PARAMCHECK_POINTER_AND_SET(pfRetVal,VARIANT_FALSE);
  505. __MPC_PARAMCHECK_END();
  506. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::IsNetworkAlive" );
  507. if(SUCCEEDED(MPC::Connectivity::NetworkAlive( HC_TIMEOUT_CONNECTIONCHECK )))
  508. {
  509. *pfRetVal = VARIANT_TRUE;
  510. }
  511. hr = S_OK;
  512. __HCP_FUNC_CLEANUP;
  513. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::IsNetworkAlive - done" );
  514. __HCP_FUNC_EXIT(hr);
  515. }
  516. HRESULT CPCHSlaveProcess::IsDestinationReachable( /*[in ]*/ BSTR bstrDestination, /*[out]*/ VARIANT_BOOL *pfRetVal )
  517. {
  518. __HCP_FUNC_ENTRY( "CPCHSlaveProcess::IsDestinationReachable" );
  519. HRESULT hr;
  520. __MPC_PARAMCHECK_BEGIN(hr)
  521. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrDestination);
  522. __MPC_PARAMCHECK_POINTER_AND_SET(pfRetVal,VARIANT_FALSE);
  523. __MPC_PARAMCHECK_END();
  524. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::IsDestinationReachable" );
  525. if(SUCCEEDED(MPC::Connectivity::DestinationReachable( bstrDestination, HC_TIMEOUT_CONNECTIONCHECK )))
  526. {
  527. *pfRetVal = VARIANT_TRUE;
  528. }
  529. hr = S_OK;
  530. __HCP_FUNC_CLEANUP;
  531. DEBUG_AppendPerf( DEBUG_PERF_HELPHOST, "CPCHSlaveProcess::IsDestinationReachable - done" );
  532. __HCP_FUNC_EXIT(hr);
  533. }