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.

1482 lines
41 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. ConnectionToServer.cpp
  6. Abstract:
  7. Implementation file for utility functions for connecting to a server.
  8. Revision History:
  9. mmaguire 11/10/97 - created
  10. byao 4/24/98 - modified for Remote Access Policy UI
  11. --*/
  12. //////////////////////////////////////////////////////////////////////////////
  13. //////////////////////////////////////////////////////////////////////////////
  14. // BEGIN INCLUDES
  15. //
  16. // standard includes:
  17. //
  18. #include "Precompiled.h"
  19. //
  20. // where we can find declaration for main class in this file:
  21. //
  22. #include "ConnectionToServer.h"
  23. //
  24. //
  25. // where we can find declarations needed in this file:
  26. //
  27. #include "MachineNode.h"
  28. #include "Component.h"
  29. #include "ComponentData.h"
  30. #include "ChangeNotification.h"
  31. #include "LogMacNd.h"
  32. #include "LogComp.h"
  33. #include "LogCompD.h"
  34. //
  35. // END INCLUDES
  36. //////////////////////////////////////////////////////////////////////////////
  37. // Initialize the Help ID pairs
  38. //const DWORD CConnectionToServer::m_dwHelpMap[] =
  39. //{
  40. // 0, 0
  41. //};
  42. // reload Sdo for refresh
  43. // happening in the main thread
  44. HRESULT CConnectionToServer::ReloadSdo(ISdo** ppSdoService, ISdoDictionaryOld **ppSdoDictionaryOld)
  45. {
  46. HRESULT hr = S_OK;
  47. // this is reload
  48. ASSERT(m_spSdoMachine);
  49. ASSERT(m_spSdoDictionaryOld);
  50. ASSERT(m_spSdo);
  51. CComPtr<IUnknown> spUnk;
  52. // service Sdo
  53. if(ppSdoService)
  54. {
  55. CComBSTR bstrServiceName;
  56. if( m_fExtendingIAS )
  57. {
  58. bstrServiceName = L"IAS";
  59. }
  60. else
  61. {
  62. bstrServiceName = L"RemoteAccess";
  63. }
  64. // Get the service Sdo.
  65. hr = m_spSdoMachine->GetServiceSDO ( DATA_STORE_LOCAL
  66. , bstrServiceName
  67. , (IUnknown **)&spUnk
  68. );
  69. if ( FAILED(hr) )
  70. return hr;
  71. m_spSdo.Release();
  72. hr = spUnk->QueryInterface( IID_ISdo, (void **) &m_spSdo );
  73. *ppSdoService = m_spSdo;
  74. (*ppSdoService)->AddRef();
  75. }
  76. if ( FAILED(hr) )
  77. return hr;
  78. // Dictionary Sdo
  79. if (ppSdoDictionaryOld)
  80. {
  81. spUnk.Release();
  82. m_spSdoDictionaryOld.Release();
  83. // Get the dictionary Sdo.
  84. hr = m_spSdoMachine->GetDictionarySDO ( (IUnknown **)&spUnk );
  85. if ( FAILED(hr) )
  86. return hr;
  87. hr = spUnk->QueryInterface( IID_ISdoDictionaryOld, (void **) &m_spSdoDictionaryOld );
  88. if ( FAILED(hr) )
  89. return hr;
  90. *ppSdoDictionaryOld = m_spSdoDictionaryOld;
  91. (*ppSdoDictionaryOld)->AddRef();
  92. }
  93. return hr;
  94. }
  95. //////////////////////////////////////////////////////////////////////////////
  96. /*++
  97. CConnectionToServer::CConnectionToServer
  98. Constructor
  99. --*/
  100. //////////////////////////////////////////////////////////////////////////////
  101. CConnectionToServer::CConnectionToServer
  102. (
  103. CMachineNode* pMachineNode,
  104. BSTR bstrServerAddress, // server we are connecting to
  105. BOOL fExtendingIAS // are we extending IAS or Network Console
  106. )
  107. {
  108. TRACE_FUNCTION("CConnectionToServer::CConnectionToServer");
  109. // Check for preconditions:
  110. // may be null when doing the logging node
  111. //_ASSERTE( pMachineNode != NULL );
  112. m_pMachineNode = pMachineNode;
  113. m_bstrServerAddress = bstrServerAddress;
  114. m_fExtendingIAS = fExtendingIAS;
  115. m_pStreamSdoServiceMarshal = NULL;
  116. m_pStreamSdoDictionaryOldMarshal = NULL;
  117. m_fDSAvailable = FALSE;
  118. if ( !m_bstrServerAddress.Length() )
  119. {
  120. DWORD dwBufferSize = IAS_MAX_COMPUTERNAME_LENGTH;
  121. if ( !GetComputerName(m_szLocalComputerName, &dwBufferSize) )
  122. {
  123. m_szLocalComputerName[0]=_T('\0');
  124. }
  125. }
  126. }
  127. //////////////////////////////////////////////////////////////////////////////
  128. /*++
  129. CConnectionToServer::~CConnectionToServer
  130. Destructor
  131. --*/
  132. //////////////////////////////////////////////////////////////////////////////
  133. CConnectionToServer::~CConnectionToServer()
  134. {
  135. TRACE_FUNCTION("CConnectionToServer::~CConnectionToServer");
  136. // Check for preconditions:
  137. HRESULT hr;
  138. // Release this stream pointer if this hasn't already been done.
  139. if( m_pStreamSdoServiceMarshal != NULL )
  140. {
  141. m_pStreamSdoServiceMarshal->Release();
  142. };
  143. if( m_pStreamSdoDictionaryOldMarshal != NULL )
  144. {
  145. m_pStreamSdoDictionaryOldMarshal->Release();
  146. };
  147. }
  148. //////////////////////////////////////////////////////////////////////////////
  149. /*++
  150. CConnectionToServer::OnInitDialog
  151. --*/
  152. //////////////////////////////////////////////////////////////////////////////
  153. LRESULT CConnectionToServer::OnInitDialog(
  154. UINT uMsg
  155. , WPARAM wParam
  156. , LPARAM lParam
  157. , BOOL& bHandled
  158. )
  159. {
  160. TRACE_FUNCTION("CConnectionToServer::OnInitDialog");
  161. // Check for preconditions:
  162. _ASSERTE( m_pMachineNode != NULL );
  163. CComponentData *pComponentData = m_pMachineNode->GetComponentData();
  164. _ASSERTE( pComponentData != NULL );
  165. _ASSERTE( pComponentData->m_spConsole != NULL );
  166. _ASSERTE( m_pMachineNode->m_pPoliciesNode != NULL );
  167. // Change the icon for the scope node from being normal to a busy icon.
  168. CComQIPtr< IConsoleNameSpace, &IID_IConsoleNameSpace > spConsoleNameSpace( pComponentData->m_spConsole );
  169. LPSCOPEDATAITEM psdiPoliciesNode;
  170. m_pMachineNode->m_pPoliciesNode->GetScopeData( &psdiPoliciesNode );
  171. _ASSERTE( psdiPoliciesNode );
  172. SCOPEDATAITEM sdi;
  173. sdi.mask = SDI_IMAGE | SDI_OPENIMAGE;
  174. sdi.nImage = IDBI_NODE_POLICIES_BUSY_CLOSED;
  175. sdi.nOpenImage = IDBI_NODE_POLICIES_BUSY_OPEN;
  176. sdi.ID = psdiPoliciesNode->ID;
  177. // Change the stored indices as well so that MMC will use them whenever it queries
  178. // the node for its images.
  179. LPRESULTDATAITEM prdiPoliciesNode;
  180. m_pMachineNode->m_pPoliciesNode->GetResultData( &prdiPoliciesNode );
  181. _ASSERTE( prdiPoliciesNode );
  182. prdiPoliciesNode->nImage = IDBI_NODE_POLICIES_BUSY_CLOSED;
  183. psdiPoliciesNode->nImage = IDBI_NODE_POLICIES_BUSY_CLOSED;
  184. psdiPoliciesNode->nOpenImage = IDBI_NODE_POLICIES_BUSY_OPEN;
  185. spConsoleNameSpace->SetItem( &sdi );
  186. // int nLoadStringResult;
  187. // TCHAR szConnectingStr[256];
  188. // TCHAR szConnectingMsg[1024];
  189. //
  190. // // Set the display name for this object
  191. // if ( LoadString( _Module.GetResourceInstance(),
  192. // IDS_CONNECTION_CONNECTING_TO_STR,
  193. // szConnectingStr,
  194. // 256
  195. // ) <= 0 )
  196. // {
  197. // _tcscpy( szConnectingMsg, _T("Connecting to ") );
  198. // }
  199. //
  200. // if ( !m_bstrServerAddress.Length() )
  201. // {
  202. // wsprintf(szConnectingMsg, _T("%ws %ws"), szConnectingStr, m_szLocalComputerName);
  203. // }
  204. // else
  205. // {
  206. // wsprintf(szConnectingMsg, _T("%ws %ws"), szConnectingStr, m_bstrServerAddress);
  207. // }
  208. //
  209. // SetDlgItemText(IDC_CONNECTION_STATUS__DIALOG__STATUS, szConnectingMsg);
  210. //
  211. // start the worker thread
  212. //
  213. StartWorkerThread();
  214. return 0;
  215. }
  216. //////////////////////////////////////////////////////////////////////////////
  217. /*++
  218. CConnectionToServer::OnReceiveThreadMessage
  219. Called when the worker thread wants to inform the main MMC thread of something.
  220. --*/
  221. //////////////////////////////////////////////////////////////////////////////
  222. LRESULT CConnectionToServer::OnReceiveThreadMessage(
  223. UINT uMsg
  224. , WPARAM wParam
  225. , LPARAM lParam
  226. , BOOL& bHandled
  227. )
  228. {
  229. TRACE_FUNCTION("CConnectionToServer::OnReceiveThreadMessage");
  230. // Check for preconditions:
  231. _ASSERTE( m_pMachineNode != NULL );
  232. CComponentData *pComponentData = m_pMachineNode->GetComponentData();
  233. _ASSERTE( pComponentData != NULL );
  234. _ASSERTE( pComponentData->m_spConsole != NULL );
  235. _ASSERTE( m_pMachineNode->m_pPoliciesNode != NULL );
  236. // The worker thread has notified us that it has finished.
  237. // Change the icon for the Policies node.
  238. CComQIPtr< IConsoleNameSpace, &IID_IConsoleNameSpace > spConsoleNameSpace( pComponentData->m_spConsole );
  239. LPSCOPEDATAITEM psdiPoliciesNode = NULL;
  240. m_pMachineNode->m_pPoliciesNode->GetScopeData( &psdiPoliciesNode );
  241. _ASSERTE( psdiPoliciesNode );
  242. SCOPEDATAITEM sdi;
  243. sdi.mask = SDI_IMAGE | SDI_OPENIMAGE;
  244. if( wParam == CONNECT_NO_ERROR )
  245. {
  246. // Everything was OK -- change the icon to the OK icon.
  247. sdi.nImage = IDBI_NODE_POLICIES_OK_CLOSED;
  248. sdi.nOpenImage = IDBI_NODE_POLICIES_OK_OPEN;
  249. // Change the stored indices as well so that MMC will use them whenever it queries
  250. // the node for its images.
  251. LPRESULTDATAITEM prdiPoliciesNode;
  252. m_pMachineNode->m_pPoliciesNode->GetResultData( &prdiPoliciesNode );
  253. m_pMachineNode->m_pPoliciesNode->m_fSdoConnected = TRUE;
  254. _ASSERTE( prdiPoliciesNode );
  255. prdiPoliciesNode->nImage = IDBI_NODE_POLICIES_OK_CLOSED;
  256. psdiPoliciesNode->nImage = IDBI_NODE_POLICIES_OK_CLOSED;
  257. psdiPoliciesNode->nOpenImage = IDBI_NODE_POLICIES_OK_OPEN;
  258. }
  259. else
  260. {
  261. // There was an error -- change the icon to the error icon.
  262. sdi.nImage = IDBI_NODE_POLICIES_ERROR_CLOSED;
  263. sdi.nOpenImage = IDBI_NODE_POLICIES_ERROR_OPEN;
  264. // Change the stored indices as well so that MMC will use them whenever it queries
  265. // the node for its images.
  266. LPRESULTDATAITEM prdiPoliciesNode;
  267. m_pMachineNode->m_pPoliciesNode->GetResultData( &prdiPoliciesNode );
  268. m_pMachineNode->m_pPoliciesNode->m_fSdoConnected = FALSE;
  269. _ASSERTE( prdiPoliciesNode );
  270. prdiPoliciesNode->nImage = IDBI_NODE_POLICIES_ERROR_CLOSED;
  271. psdiPoliciesNode->nImage = IDBI_NODE_POLICIES_ERROR_CLOSED;
  272. psdiPoliciesNode->nOpenImage = IDBI_NODE_POLICIES_ERROR_OPEN;
  273. }
  274. sdi.ID = psdiPoliciesNode->ID;
  275. spConsoleNameSpace->SetItem( &sdi );
  276. // We don't want to destroy the dialog, we just want to hide it.
  277. //ShowWindow( SW_HIDE );
  278. if( wParam == CONNECT_NO_ERROR )
  279. {
  280. // Tell the server node to grab its Sdo pointers.
  281. m_pMachineNode->LoadSdoData(m_fDSAvailable);
  282. //
  283. // Cause a view update.
  284. //
  285. CComponentData *pComponentData = m_pMachineNode->GetComponentData();
  286. _ASSERTE( pComponentData != NULL );
  287. _ASSERTE( pComponentData->m_spConsole != NULL );
  288. CChangeNotification *pChangeNotification = new CChangeNotification();
  289. pChangeNotification->m_dwFlags = CHANGE_UPDATE_CHILDREN_OF_SELECTED_NODE;
  290. pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0 );
  291. pChangeNotification->Release();
  292. }
  293. else if (wParam == CONNECT_SERVER_NOT_SUPPORTED)
  294. {
  295. m_pMachineNode->m_bServerSupported = FALSE;
  296. //
  297. // Cause a view update -- hide the node.
  298. //
  299. CComponentData *pComponentData = m_pMachineNode->GetComponentData();
  300. _ASSERTE( pComponentData != NULL );
  301. _ASSERTE( pComponentData->m_spConsole != NULL );
  302. CChangeNotification *pChangeNotification = new CChangeNotification();
  303. pChangeNotification->m_dwFlags = CHANGE_UPDATE_CHILDREN_OF_SELECTED_NODE;
  304. pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0 );
  305. pChangeNotification->Release();
  306. }
  307. else
  308. {
  309. // There was an error connecting.
  310. ShowErrorDialog( m_hWnd, IDS_ERROR_CANT_CONNECT);
  311. }
  312. return 0;
  313. }
  314. //////////////////////////////////////////////////////////////////////////////
  315. /*++
  316. CConnectionToServer::GetConnectionStatus
  317. Our connection status is basically a function of the status of the underlying
  318. worker thread. So here we give a connection status based on the worker thread's.
  319. --*/
  320. //////////////////////////////////////////////////////////////////////////////
  321. CONNECTION_STATUS CConnectionToServer::GetConnectionStatus( void )
  322. {
  323. TRACE_FUNCTION("CConnectionToServer::GetConnectionStatus");
  324. // Check for preconditions:
  325. CONNECTION_STATUS csStatus;
  326. switch( GetWorkerThreadStatus() )
  327. {
  328. case WORKER_THREAD_NEVER_STARTED:
  329. csStatus = NO_CONNECTION_ATTEMPTED;
  330. break;
  331. case WORKER_THREAD_STARTING:
  332. case WORKER_THREAD_STARTED:
  333. csStatus = CONNECTING;
  334. break;
  335. case WORKER_THREAD_FINISHED:
  336. csStatus = CONNECTED;
  337. break;
  338. case WORKER_THREAD_START_FAILED:
  339. case WORKER_THREAD_ACTION_INTERRUPTED:
  340. csStatus = CONNECTION_ATTEMPT_FAILED;
  341. break;
  342. default:
  343. csStatus = UNKNOWN;
  344. break;
  345. }
  346. return csStatus;
  347. }
  348. //////////////////////////////////////////////////////////////////////////////
  349. /*++
  350. CConnectionToServer::GetSdoService
  351. --*/
  352. //////////////////////////////////////////////////////////////////////////////
  353. HRESULT CConnectionToServer::GetSdoService( ISdo **ppSdoService )
  354. {
  355. TRACE_FUNCTION("CConnectionToServer::GetSdoService");
  356. // Check for preconditions:
  357. _ASSERTE( ppSdoService != NULL );
  358. if( CONNECTED != GetConnectionStatus() )
  359. {
  360. *ppSdoService = NULL;
  361. return E_FAIL;
  362. }
  363. HRESULT hr = S_OK;
  364. // If we get here, our status is CONNECTED, in which case
  365. // our worker thread should have marshalled an ISdo interface
  366. // of the server into the m_pStreadSdoMarshal.
  367. if( m_pStreamSdoServiceMarshal == NULL )
  368. {
  369. // We have already unmarshalled our ISdo interface to the server.
  370. _ASSERTE( m_spSdo != NULL );
  371. }
  372. else
  373. {
  374. // Unmarshall an ISdo interface pointer to the server.
  375. hr = CoGetInterfaceAndReleaseStream(
  376. m_pStreamSdoServiceMarshal //Pointer to the stream from which the object is to be marshaled.
  377. , IID_ISdo //Reference to the identifier of the interface.
  378. , (LPVOID *) &m_spSdo //Address of output variable that receives the interface pointer requested in riid.
  379. );
  380. // CoGetInterfaceAndReleaseStream releases this pointer even if it fails.
  381. // We set it to NULL so that our destructor doesn't try to release this again.
  382. m_pStreamSdoServiceMarshal = NULL;
  383. // Unmarshall an ISdo interface pointer to the server.
  384. hr = CoGetInterfaceAndReleaseStream(
  385. m_pStreamSdoMachineMarshal //Pointer to the stream from which the object is to be marshaled.
  386. , IID_ISdoMachine //Reference to the identifier of the interface.
  387. , (LPVOID *) &m_spSdoMachine //Address of output variable that receives the interface pointer requested in riid.
  388. );
  389. // CoGetInterfaceAndReleaseStream releases this pointer even if it fails.
  390. // We set it to NULL so that our destructor doesn't try to release this again.
  391. m_pStreamSdoMachineMarshal = NULL;
  392. }
  393. *ppSdoService = m_spSdo;
  394. return hr;
  395. }
  396. //////////////////////////////////////////////////////////////////////////////
  397. /*++
  398. CConnectionToServer::GetSdoDictionaryOld
  399. --*/
  400. //////////////////////////////////////////////////////////////////////////////
  401. HRESULT CConnectionToServer::GetSdoDictionaryOld( ISdoDictionaryOld **ppSdoDictionaryOld )
  402. {
  403. TRACE_FUNCTION("CConnectionToServer::GetSdoDictionaryOld");
  404. // Check for preconditions:
  405. _ASSERTE( ppSdoDictionaryOld != NULL );
  406. if( CONNECTED != GetConnectionStatus() )
  407. {
  408. *ppSdoDictionaryOld = NULL;
  409. return E_FAIL;
  410. }
  411. HRESULT hr = S_OK;
  412. // If we get here, our status is CONNECTED, in which case
  413. // our worker thread should have marshalled an ISdo interface
  414. // of the server into the m_pStreadSdoMarshal.
  415. if( m_pStreamSdoDictionaryOldMarshal == NULL )
  416. {
  417. // We have already unmarshalled our ISdo interface to the server.
  418. _ASSERTE( m_spSdoDictionaryOld != NULL );
  419. }
  420. else
  421. {
  422. // Unmarshall an ISdo interface pointer to the server.
  423. hr = CoGetInterfaceAndReleaseStream(
  424. m_pStreamSdoDictionaryOldMarshal //Pointer to the stream from which the object is to be marshaled.
  425. , IID_ISdoDictionaryOld //Reference to the identifier of the interface.
  426. , (LPVOID *) &m_spSdoDictionaryOld //Address of output variable that receives the interface pointer requested in riid.
  427. );
  428. // CoGetInterfaceAndReleaseStream releases this pointer even if it fails.
  429. // We set it to NULL so that our destructor doesn't try to release this again.
  430. m_pStreamSdoDictionaryOldMarshal = NULL;
  431. }
  432. *ppSdoDictionaryOld = m_spSdoDictionaryOld;
  433. return hr;
  434. }
  435. //////////////////////////////////////////////////////////////////////////////
  436. /*++
  437. CConnectionToServer::OnCancel
  438. --*/
  439. //////////////////////////////////////////////////////////////////////////////
  440. LRESULT CConnectionToServer::OnCancel(
  441. UINT uMsg
  442. , WPARAM wParam
  443. , HWND hwnd
  444. , BOOL& bHandled
  445. )
  446. {
  447. TRACE_FUNCTION("CConnectionToServer::OnCancel");
  448. // Check for preconditions:
  449. // We don't want to destroy the dialog, we just want to hide it.
  450. //ShowWindow( SW_HIDE );
  451. return 0;
  452. }
  453. //////////////////////////////////////////////////////////////////////////////
  454. /*++
  455. CConnectionToServer::DoWorkerThreadAction
  456. Called by the worker thread to have this class perform its action
  457. in the new thread.
  458. --*/
  459. //////////////////////////////////////////////////////////////////////////////
  460. DWORD CConnectionToServer::DoWorkerThreadAction()
  461. {
  462. TRACE_FUNCTION("CConnectionToServer::DoWorkerThreadAction");
  463. HRESULT hr;
  464. DWORD dwReturnValue;
  465. CComPtr<ISdoMachine> spSdoMachine;
  466. // We must call CoInitialize because we are in a new thread.
  467. hr = CoInitialize( NULL );
  468. WriteTrace("RAP NODE: CoInitialize() , hr = %x", hr);
  469. if( FAILED( hr ) )
  470. {
  471. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoInitialize() failed, err = %x", hr);
  472. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  473. return( CONNECT_FAILED );
  474. }
  475. do // Loop for error checking only.
  476. {
  477. // MAM: 08/04/98 - no DS policy location support anymore
  478. #ifdef STORE_DATA_IN_DIRECTORY_SERVICE
  479. try
  480. {
  481. //
  482. // first, we check the domain type for this machine
  483. //
  484. CComPtr<ISdoMachineInfo> spServerInfoSdo;
  485. hr = ::CoCreateInstance(
  486. CLSID_SdoServerInfo, //Class identifier (CLSID) of the object
  487. NULL, //Pointer to whether object is or isn't part
  488. // of an aggregate
  489. CLSCTX_INPROC_SERVER, //Context for running executable code,
  490. IID_ISdoMachineInfo, //Reference to the identifier of the interface
  491. (LPVOID *) &spServerInfoSdo //Address of output variable that receives
  492. // the interface pointer requested in riid
  493. );
  494. if( FAILED(hr) || spServerInfoSdo == NULL )
  495. {
  496. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "CoCreateInstance(ServerInfo) failed, err=%x", hr);
  497. // MAM: Don't fail entire connect action if we couldn't figure out what we are --
  498. // just assume we don't have the DS available.
  499. //m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  500. //dwReturnValue = -1; // ISSUE: Need to figure out better return codes.
  501. //break;
  502. throw hr;
  503. }
  504. DOMAINTYPE serverDomainType;
  505. if (m_bstrServerAddress.Length())
  506. {
  507. hr = spServerInfoSdo->GetDomainInfo
  508. (
  509. OBJECT_TYPE_COMPUTER,
  510. m_bstrServerAddress,
  511. &serverDomainType
  512. );
  513. }
  514. else
  515. {
  516. BSTR bstrAddress = SysAllocString(m_szLocalComputerName);
  517. if ( bstrAddress )
  518. {
  519. hr = spServerInfoSdo->GetDomainInfo
  520. (
  521. OBJECT_TYPE_COMPUTER,
  522. bstrAddress,
  523. &serverDomainType
  524. );
  525. SysFreeString(bstrAddress);
  526. }
  527. else
  528. {
  529. hr = HRESULT_FROM_WIN32(GetLastError());
  530. ErrorTrace(ERROR_NAPMMC_CONNECTION,"GetComputerName() failed, err =%x", GetLastError());
  531. }
  532. }
  533. if ( FAILED(hr) )
  534. {
  535. ErrorTrace(ERROR_NAPMMC_CONNECTION, "GetDomainInfo() failed, err = %x", hr);
  536. // MAM: Don't fail entire connect action if we couldn't figure out what we are --
  537. // just assume we don't have the DS available.
  538. //m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  539. //dwReturnValue = -1; // ISSUE: Need to figure out better return codes.
  540. //break;
  541. throw hr;
  542. }
  543. if ( serverDomainType == DOMAIN_TYPE_NT5 )
  544. {
  545. m_fDSAvailable = TRUE;
  546. }
  547. else
  548. {
  549. //
  550. // for all other domain types, DS is treated as not available
  551. //
  552. m_fDSAvailable = FALSE;
  553. }
  554. }
  555. catch(...)
  556. {
  557. // MAM: Don't fail entire connect action if something failed here --
  558. // just assume we don't have the DS available.
  559. m_fDSAvailable = FALSE;
  560. }
  561. #else // STORE_DATA_IN_DIRECTORY_SERVICE
  562. m_fDSAvailable = FALSE;
  563. #endif // STORE_DATA_IN_DIRECTORY_SERVICE
  564. //
  565. // now, we can connect to the server based on the domain type
  566. //
  567. hr = CoCreateInstance(
  568. CLSID_SdoMachine //Class identifier (CLSID) of the object
  569. , NULL //Pointer to whether object is or isn't part of an aggregate
  570. , CLSCTX_INPROC_SERVER //Context for running executable code
  571. , IID_ISdoMachine //Reference to the identifier of the interface
  572. , (LPVOID *) &spSdoMachine //Address of output variable that receives the interface pointer requested in riid
  573. );
  574. WriteTrace("RAP NODE: CoCreateInstance , hr = %x", hr);
  575. if( FAILED (hr ) )
  576. {
  577. // Error -- couldn't CoCreate SDO.
  578. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoCreateInstance failed, err = %x", hr);
  579. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  580. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  581. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  582. break;
  583. }
  584. #ifdef STORE_DATA_IN_DIRECTORY_SERVICE
  585. LONG lFlags=0;
  586. if ( m_fDSAvailable )
  587. {
  588. lFlags |= RETRIEVE_SERVER_DATA_FROM_DS;
  589. }
  590. #endif // STORE_DATA_IN_DIRECTORY_SERVICE
  591. if( !m_bstrServerAddress.Length() )
  592. {
  593. hr = spSdoMachine->Attach( NULL );
  594. }
  595. else
  596. {
  597. hr = spSdoMachine->Attach( m_bstrServerAddress );
  598. }
  599. WriteTrace("RAP NODE: ISdoMachine::Attach , hr = %x", hr);
  600. if( FAILED( hr ) )
  601. {
  602. // Error -- couldn't connect SDO up to this server.
  603. ErrorTrace(ERROR_NAPMMC_CONNECTION, "ISdoMachine::Connect failed, err = %x", hr);
  604. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  605. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  606. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  607. break;
  608. }
  609. // Marshall the ISdo pointer so that the main thread can unmarshall
  610. // it and use the connection we have established.
  611. hr = CoMarshalInterThreadInterfaceInStream(
  612. IID_ISdoMachine //Reference to the identifier of the interface.
  613. , spSdoMachine //Pointer to the interface to be marshaled.
  614. , &( m_pStreamSdoMachineMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface.
  615. );
  616. // check if the machine is downlevel servers -- NT4, if it is, return CONNECT_SERVER_NOT_SUPPORTED
  617. {
  618. IASOSTYPE OSType;
  619. spSdoMachine->GetOSType(&OSType);
  620. if(SYSTEM_TYPE_NT4_WORKSTATION == OSType || SYSTEM_TYPE_NT4_SERVER == OSType)
  621. {
  622. WriteTrace("RAP NODE: NT4 machine, not supported ", hr);
  623. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  624. dwReturnValue = CONNECT_SERVER_NOT_SUPPORTED; // ISSUE: Need to figure out better return codes.
  625. break;
  626. }
  627. }
  628. CComPtr<IUnknown> spUnknownServiceSdo;
  629. CComBSTR bstrServiceName;
  630. if( m_fExtendingIAS )
  631. {
  632. bstrServiceName = L"IAS";
  633. }
  634. else
  635. {
  636. bstrServiceName = L"RemoteAccess";
  637. }
  638. // Get the service Sdo.
  639. hr = spSdoMachine->GetServiceSDO ( DATA_STORE_LOCAL
  640. , bstrServiceName
  641. , (IUnknown **)&spUnknownServiceSdo
  642. );
  643. WriteTrace("RAP NODE: ISdoMachine::GetServiceSDO , hr = %x", hr);
  644. if ( FAILED(hr) )
  645. {
  646. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get dictionary object, err = %x", hr);
  647. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  648. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  649. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  650. break;
  651. }
  652. CComPtr<ISdo> spServiceSdo;
  653. hr = spUnknownServiceSdo->QueryInterface( IID_ISdo, (void **) &spServiceSdo );
  654. WriteTrace("RAP NODE: spUnknownServiceSdo->QueryInterface( IID_ISdo, hr = %x", hr);
  655. if ( FAILED(hr) )
  656. {
  657. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get service object, err = %x", hr);
  658. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  659. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  660. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  661. break;
  662. }
  663. // We must manually AddRef here because we just copied a pointer
  664. // into our smart pointer and the smart pointer won't catch that.
  665. // 39470 *RRAS snapin mmc process does not get shut down upon closing if F1 help is used.
  666. // spServiceSdo->AddRef();
  667. CComPtr<IUnknown> spUnknownDictionarySdo;
  668. // Get the dictionary Sdo.
  669. hr = spSdoMachine->GetDictionarySDO ( (IUnknown **)&spUnknownDictionarySdo );
  670. WriteTrace("RAP NODE: spSdoMachine->GetDictionarySDO , hr = %x", hr);
  671. if ( FAILED(hr) )
  672. {
  673. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get dictionary object, err = %x", hr);
  674. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  675. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  676. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  677. break;
  678. }
  679. CComPtr<ISdoDictionaryOld> spSdoDictionaryOld;
  680. hr = spUnknownDictionarySdo->QueryInterface( IID_ISdoDictionaryOld, (void **) &spSdoDictionaryOld );
  681. WriteTrace("RAP NODE: spUnknownDictionarySdo->QueryInterface( IID_ISdoDictionaryOld, hr = %x", hr);
  682. if ( FAILED(hr) )
  683. {
  684. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get dictionary object, err = %x", hr);
  685. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  686. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  687. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  688. break;
  689. }
  690. // We must manually AddRef here because we just copied a pointer
  691. // into our smart pointer and the smart pointer won't catch that.
  692. // 39470 *RRAS snapin mmc process does not get shut down upon closing if F1 help is used.
  693. // spSdoDictionaryOld->AddRef();
  694. // Marshall the ISdo pointer so that the main thread can unmarshall
  695. // it and use the connection we have established.
  696. hr = CoMarshalInterThreadInterfaceInStream(
  697. IID_ISdo //Reference to the identifier of the interface.
  698. , spServiceSdo //Pointer to the interface to be marshaled.
  699. , &( m_pStreamSdoServiceMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface.
  700. );
  701. WriteTrace("RAP NODE: CoMarshalInterThreadInterfaceInStream IID_ISdo , spServiceSdo, hr = %x", hr);
  702. if( FAILED( hr ) )
  703. {
  704. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoMarshalInterThreadInterfaceInStream failed, err = %x", hr);
  705. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  706. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  707. dwReturnValue = -1;
  708. break;
  709. }
  710. // Marshall the ISdo pointer so that the main thread can unmarshall
  711. // it and use the connection we have established.
  712. hr = CoMarshalInterThreadInterfaceInStream(
  713. IID_ISdoDictionaryOld //Reference to the identifier of the interface.
  714. , spSdoDictionaryOld //Pointer to the interface to be marshaled.
  715. , &( m_pStreamSdoDictionaryOldMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface.
  716. );
  717. WriteTrace("RAP NODE: CoMarshalInterThreadInterfaceInStream IID_ISdoDictionaryOld , spSdoDictionaryOld, hr = %x", hr);
  718. if( FAILED( hr ) )
  719. {
  720. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoMarshalInterThreadInterfaceInStream failed, err = %x", hr);
  721. WriteTrace("RAP NODE: ERROR, hr = %x ", hr);
  722. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  723. dwReturnValue = -1;
  724. break;
  725. }
  726. // If we made it to here, we are OK.
  727. _ASSERTE( m_pStreamSdoServiceMarshal != NULL );
  728. _ASSERTE( m_pStreamSdoDictionaryOldMarshal != NULL );
  729. m_wtsWorkerThreadStatus = WORKER_THREAD_FINISHED;
  730. dwReturnValue = 0;
  731. } while (0); // Loop for error checking only.
  732. CoUninitialize();
  733. DebugTrace(DEBUG_NAPMMC_CONNECTION, "NAP seems to have a valid connection to Sdo");
  734. // Tell the main MMC thread what's up.
  735. PostMessageToMainThread( dwReturnValue, NULL );
  736. return dwReturnValue;
  737. }
  738. //////////////////////////////////////////////////////////////////////////////
  739. /*++
  740. CLoggingConnectionToServer::CLoggingConnectionToServer
  741. Constructor
  742. --*/
  743. //////////////////////////////////////////////////////////////////////////////
  744. CLoggingConnectionToServer::CLoggingConnectionToServer
  745. (
  746. CLoggingMachineNode * pMachineNode,
  747. BSTR bstrServerAddress, // server we are connecting to
  748. BOOL fExtendingIAS // are we extending IAS or Network Console
  749. ) : CConnectionToServer(NULL, bstrServerAddress, fExtendingIAS)
  750. {
  751. TRACE_FUNCTION("CLoggingConnectionToServer::CConnectionToServer");
  752. // Check for preconditions:
  753. _ASSERTE( pMachineNode != NULL );
  754. m_pMachineNode = pMachineNode;
  755. m_bstrServerAddress = bstrServerAddress;
  756. m_fExtendingIAS = fExtendingIAS;
  757. m_pStreamSdoServiceMarshal = NULL;
  758. m_fDSAvailable = FALSE;
  759. if ( !m_bstrServerAddress.Length() )
  760. {
  761. DWORD dwBufferSize = IAS_MAX_COMPUTERNAME_LENGTH;
  762. if ( !GetComputerName(m_szLocalComputerName, &dwBufferSize) )
  763. {
  764. m_szLocalComputerName[0]=_T('\0');
  765. }
  766. }
  767. }
  768. //////////////////////////////////////////////////////////////////////////////
  769. /*++
  770. CLoggingConnectionToServer::~CLoggingConnectionToServer
  771. Destructor
  772. --*/
  773. //////////////////////////////////////////////////////////////////////////////
  774. CLoggingConnectionToServer::~CLoggingConnectionToServer()
  775. {
  776. TRACE_FUNCTION("CLoggingConnectionToServer::~CConnectionToServer");
  777. // Check for preconditions:
  778. HRESULT hr;
  779. // Release this stream pointer if this hasn't already been done.
  780. if( m_pStreamSdoServiceMarshal != NULL )
  781. {
  782. m_pStreamSdoServiceMarshal->Release();
  783. };
  784. }
  785. //////////////////////////////////////////////////////////////////////////////
  786. /*++
  787. CLoggingConnectionToServer::OnInitDialog
  788. --*/
  789. //////////////////////////////////////////////////////////////////////////////
  790. LRESULT CLoggingConnectionToServer::OnInitDialog(
  791. UINT uMsg
  792. , WPARAM wParam
  793. , LPARAM lParam
  794. , BOOL& bHandled
  795. )
  796. {
  797. TRACE_FUNCTION("CLoggingConnectionToServer::OnInitDialog");
  798. // Check for preconditions:
  799. _ASSERTE( m_pMachineNode != NULL );
  800. CLoggingComponentData *pComponentData = m_pMachineNode->GetComponentData();
  801. _ASSERTE( pComponentData != NULL );
  802. _ASSERTE( pComponentData->m_spConsole != NULL );
  803. _ASSERTE( m_pMachineNode->m_pLoggingNode != NULL );
  804. // Change the icon for the scope node from being normal to a busy icon.
  805. CComQIPtr< IConsoleNameSpace, &IID_IConsoleNameSpace > spConsoleNameSpace( pComponentData->m_spConsole );
  806. LPSCOPEDATAITEM psdiLoggingNode;
  807. m_pMachineNode->m_pLoggingNode->GetScopeData( &psdiLoggingNode );
  808. _ASSERTE( psdiLoggingNode );
  809. SCOPEDATAITEM sdi;
  810. sdi.mask = SDI_IMAGE | SDI_OPENIMAGE;
  811. sdi.nImage = IDBI_NODE_LOGGING_METHODS_BUSY_CLOSED;
  812. sdi.nOpenImage = IDBI_NODE_LOGGING_METHODS_BUSY_OPEN;
  813. sdi.ID = psdiLoggingNode->ID;
  814. // Change the stored indices as well so that MMC will use them whenever it queries
  815. // the node for its images.
  816. LPRESULTDATAITEM prdiLoggingNode;
  817. m_pMachineNode->m_pLoggingNode->GetResultData( &prdiLoggingNode );
  818. _ASSERTE( prdiLoggingNode );
  819. prdiLoggingNode->nImage = IDBI_NODE_LOGGING_METHODS_BUSY_CLOSED;
  820. psdiLoggingNode->nImage = IDBI_NODE_LOGGING_METHODS_BUSY_CLOSED;
  821. psdiLoggingNode->nOpenImage = IDBI_NODE_LOGGING_METHODS_BUSY_OPEN;
  822. spConsoleNameSpace->SetItem( &sdi );
  823. // int nLoadStringResult;
  824. // TCHAR szConnectingStr[256];
  825. // TCHAR szConnectingMsg[1024];
  826. //
  827. // // Set the display name for this object
  828. // if ( LoadString( _Module.GetResourceInstance(),
  829. // IDS_CONNECTION_CONNECTING_TO_STR,
  830. // szConnectingStr,
  831. // 256
  832. // ) <= 0 )
  833. // {
  834. // _tcscpy( szConnectingMsg, _T("Connecting to ") );
  835. // }
  836. //
  837. // if ( !m_bstrServerAddress.Length() )
  838. // {
  839. // wsprintf(szConnectingMsg, _T("%ws %ws"), szConnectingStr, m_szLocalComputerName);
  840. // }
  841. // else
  842. // {
  843. // wsprintf(szConnectingMsg, _T("%ws %ws"), szConnectingStr, m_bstrServerAddress);
  844. // }
  845. //
  846. // SetDlgItemText(IDC_CONNECTION_STATUS__DIALOG__STATUS, szConnectingMsg);
  847. //
  848. // start the worker thread
  849. //
  850. StartWorkerThread();
  851. return 0;
  852. }
  853. //////////////////////////////////////////////////////////////////////////////
  854. /*++
  855. CLoggingConnectionToServer::OnReceiveThreadMessage
  856. Called when the worker thread wants to inform the main MMC thread of something.
  857. --*/
  858. //////////////////////////////////////////////////////////////////////////////
  859. LRESULT CLoggingConnectionToServer::OnReceiveThreadMessage(
  860. UINT uMsg
  861. , WPARAM wParam
  862. , LPARAM lParam
  863. , BOOL& bHandled
  864. )
  865. {
  866. TRACE_FUNCTION("CLoggingConnectionToServer::OnReceiveThreadMessage");
  867. // Check for preconditions:
  868. _ASSERTE( m_pMachineNode != NULL );
  869. CLoggingComponentData *pComponentData = m_pMachineNode->GetComponentData();
  870. _ASSERTE( pComponentData != NULL );
  871. _ASSERTE( pComponentData->m_spConsole != NULL );
  872. _ASSERTE( m_pMachineNode->m_pLoggingNode != NULL );
  873. // The worker thread has notified us that it has finished.
  874. // Change the icon for the Policies node.
  875. CComQIPtr< IConsoleNameSpace, &IID_IConsoleNameSpace > spConsoleNameSpace( pComponentData->m_spConsole );
  876. LPSCOPEDATAITEM psdiLoggingNode = NULL;
  877. m_pMachineNode->m_pLoggingNode->GetScopeData( &psdiLoggingNode );
  878. _ASSERTE( psdiLoggingNode );
  879. SCOPEDATAITEM sdi;
  880. sdi.mask = SDI_IMAGE | SDI_OPENIMAGE;
  881. if ( wParam == CONNECT_NO_ERROR )
  882. {
  883. // Everything was OK -- change the icon to the OK icon.
  884. sdi.nImage = IDBI_NODE_LOGGING_METHODS_CLOSED;
  885. sdi.nOpenImage = IDBI_NODE_LOGGING_METHODS_OPEN;
  886. // Change the stored indices as well so that MMC will use them whenever it queries
  887. // the node for its images.
  888. LPRESULTDATAITEM prdiLoggingNode;
  889. m_pMachineNode->m_pLoggingNode->GetResultData( &prdiLoggingNode );
  890. _ASSERTE( prdiLoggingNode );
  891. prdiLoggingNode->nImage = IDBI_NODE_LOGGING_METHODS_CLOSED;
  892. psdiLoggingNode->nImage = IDBI_NODE_LOGGING_METHODS_CLOSED;
  893. psdiLoggingNode->nOpenImage = IDBI_NODE_LOGGING_METHODS_OPEN;
  894. }
  895. else
  896. {
  897. // There was an error -- change the icon to the error icon.
  898. sdi.nImage = IDBI_NODE_LOGGING_METHODS_ERROR_CLOSED;
  899. sdi.nOpenImage = IDBI_NODE_LOGGING_METHODS_ERROR_OPEN;
  900. // Change the stored indices as well so that MMC will use them whenever it queries
  901. // the node for its images.
  902. LPRESULTDATAITEM prdiLoggingNode;
  903. m_pMachineNode->m_pLoggingNode->GetResultData( &prdiLoggingNode );
  904. _ASSERTE( prdiLoggingNode );
  905. prdiLoggingNode->nImage = IDBI_NODE_LOGGING_METHODS_ERROR_CLOSED;
  906. psdiLoggingNode->nImage = IDBI_NODE_LOGGING_METHODS_ERROR_CLOSED;
  907. psdiLoggingNode->nOpenImage = IDBI_NODE_LOGGING_METHODS_ERROR_OPEN;
  908. }
  909. sdi.ID = psdiLoggingNode->ID;
  910. spConsoleNameSpace->SetItem( &sdi );
  911. // We don't want to destroy the dialog, we just want to hide it.
  912. //ShowWindow( SW_HIDE );
  913. if( wParam == CONNECT_NO_ERROR )
  914. {
  915. // Tell the server node to grab its Sdo pointers.
  916. m_pMachineNode->LoadSdoData(m_fDSAvailable);
  917. // Ask the server node to update all its info from the SDO's.
  918. m_pMachineNode->LoadCachedInfoFromSdo();
  919. //
  920. // Cause a view update.
  921. //
  922. CLoggingComponentData *pComponentData = m_pMachineNode->GetComponentData();
  923. _ASSERTE( pComponentData != NULL );
  924. _ASSERTE( pComponentData->m_spConsole != NULL );
  925. CChangeNotification *pChangeNotification = new CChangeNotification();
  926. pChangeNotification->m_dwFlags = CHANGE_UPDATE_CHILDREN_OF_SELECTED_NODE;
  927. pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0 );
  928. pChangeNotification->Release();
  929. }
  930. else if (wParam == CONNECT_SERVER_NOT_SUPPORTED)
  931. {
  932. m_pMachineNode->m_bServerSupported = FALSE;
  933. //
  934. // Cause a view update -- hide the node.
  935. //
  936. CLoggingComponentData *pComponentData = m_pMachineNode->GetComponentData();
  937. _ASSERTE( pComponentData != NULL );
  938. _ASSERTE( pComponentData->m_spConsole != NULL );
  939. CChangeNotification *pChangeNotification = new CChangeNotification();
  940. pChangeNotification->m_dwFlags = CHANGE_UPDATE_CHILDREN_OF_SELECTED_NODE;
  941. pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0 );
  942. pChangeNotification->Release();
  943. }
  944. else // CONNECT_FAILED
  945. {
  946. // There was an error connecting.
  947. ShowErrorDialog( m_hWnd, IDS_ERROR_CANT_CONNECT, NULL, 0, IDS_ERROR__LOGGING_TITLE );
  948. }
  949. return 0;
  950. }
  951. //////////////////////////////////////////////////////////////////////////////
  952. /*++
  953. CLoggingConnectionToServer::DoWorkerThreadAction
  954. Called by the worker thread to have this class perform its action
  955. in the new thread.
  956. --*/
  957. //////////////////////////////////////////////////////////////////////////////
  958. DWORD CLoggingConnectionToServer::DoWorkerThreadAction()
  959. {
  960. TRACE_FUNCTION("CLoggingConnectionToServer::DoWorkerThreadAction");
  961. HRESULT hr;
  962. DWORD dwReturnValue;
  963. CComPtr<ISdoMachine> spSdoMachine;
  964. // We must call CoInitialize because we are in a new thread.
  965. hr = CoInitialize( NULL );
  966. WriteTrace("LOGGING NODE: CoInitialize() , hr = %x", hr);
  967. if( FAILED( hr ) )
  968. {
  969. WriteTrace("LOGGING NODE: ERROR, hr = %x ", hr);
  970. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoInitialize() failed, err = %x", hr);
  971. return( CONNECT_FAILED );
  972. }
  973. do // Loop for error checking only.
  974. {
  975. //
  976. // now, we can connect to the server based on the domain type
  977. //
  978. hr = CoCreateInstance(
  979. CLSID_SdoMachine //Class identifier (CLSID) of the object
  980. , NULL //Pointer to whether object is or isn't part of an aggregate
  981. , CLSCTX_INPROC_SERVER //Context for running executable code
  982. , IID_ISdoMachine //Reference to the identifier of the interface
  983. , (LPVOID *) &spSdoMachine //Address of output variable that receives the interface pointer requested in riid
  984. );
  985. WriteTrace("LOGGING NODE: CoCreateInstance, hr = %x", hr);
  986. if( FAILED (hr ) )
  987. {
  988. // Error -- couldn't CoCreate SDO.
  989. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoCreateInstance failed, err = %x", hr);
  990. WriteTrace("LOGGING NODE: ERROR, hr = %x ", hr);
  991. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  992. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  993. break;
  994. }
  995. if( !m_bstrServerAddress.Length() )
  996. {
  997. hr = spSdoMachine->Attach( NULL );
  998. }
  999. else
  1000. {
  1001. hr = spSdoMachine->Attach( m_bstrServerAddress );
  1002. }
  1003. WriteTrace("LOGGING NODE: ISdoMachine::Attach, hr = %x", hr);
  1004. if( FAILED( hr ) )
  1005. {
  1006. // Error -- couldn't connect SDO up to this server.
  1007. ErrorTrace(ERROR_NAPMMC_CONNECTION, "ISdoMachine::Connect failed, err = %x", hr);
  1008. WriteTrace("LOGGING NODE: ERROR, hr = %x ", hr);
  1009. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  1010. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  1011. break;
  1012. }
  1013. // Marshall the ISdo pointer so that the main thread can unmarshall
  1014. // it and use the connection we have established.
  1015. hr = CoMarshalInterThreadInterfaceInStream(
  1016. IID_ISdoMachine //Reference to the identifier of the interface.
  1017. , spSdoMachine //Pointer to the interface to be marshaled.
  1018. , &( m_pStreamSdoMachineMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface.
  1019. );
  1020. // check if the machine is downlevel servers -- NT4, if it is, return CONNECT_SERVER_NOT_SUPPORTED
  1021. {
  1022. IASOSTYPE OSType;
  1023. spSdoMachine->GetOSType(&OSType);
  1024. if(SYSTEM_TYPE_NT4_WORKSTATION == OSType || SYSTEM_TYPE_NT4_SERVER == OSType)
  1025. {
  1026. WriteTrace("LOGGING NODE: NT4 machine, not supported ", hr);
  1027. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  1028. dwReturnValue = CONNECT_SERVER_NOT_SUPPORTED; // ISSUE: Need to figure out better return codes.
  1029. break;
  1030. }
  1031. }
  1032. CComPtr<IUnknown> spUnknownServiceSdo;
  1033. CComBSTR bstrServiceName;
  1034. if( m_fExtendingIAS )
  1035. {
  1036. bstrServiceName = L"IAS";
  1037. }
  1038. else
  1039. {
  1040. bstrServiceName = L"RemoteAccess";
  1041. }
  1042. // Get the service Sdo.
  1043. hr = spSdoMachine->GetServiceSDO ( DATA_STORE_LOCAL
  1044. , bstrServiceName
  1045. , (IUnknown **)&spUnknownServiceSdo
  1046. );
  1047. WriteTrace("LOGGING NODE: spSdoMachine->GetServiceSDO, hr = %x", hr);
  1048. if ( FAILED(hr) )
  1049. {
  1050. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get dictionary object, err = %x", hr);
  1051. WriteTrace("LOGGING NODE: ERROR, hr = %x ", hr);
  1052. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  1053. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  1054. break;
  1055. }
  1056. CComPtr<ISdo> spServiceSdo;
  1057. hr = spUnknownServiceSdo->QueryInterface( IID_ISdo, (void **) &spServiceSdo );
  1058. WriteTrace("LOGGING NODE: spUnknownServiceSdo->QueryInterface IID_ISdo, hr = %x", hr);
  1059. if ( FAILED(hr) )
  1060. {
  1061. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get service object, err = %x", hr);
  1062. WriteTrace("LOGGING NODE: ERROR, hr = %x ", hr);
  1063. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  1064. dwReturnValue = CONNECT_FAILED; // ISSUE: Need to figure out better return codes.
  1065. break;
  1066. }
  1067. // We must manually AddRef here because we just copied a pointer
  1068. // into our smart pointer and the smart pointer won't catch that.
  1069. // 39470 *RRAS snapin mmc process does not get shut down upon closing if F1 help is used.
  1070. // spServiceSdo->AddRef();
  1071. // Marshall the ISdo pointer so that the main thread can unmarshall
  1072. // it and use the connection we have established.
  1073. hr = CoMarshalInterThreadInterfaceInStream(
  1074. IID_ISdo //Reference to the identifier of the interface.
  1075. , spServiceSdo //Pointer to the interface to be marshaled.
  1076. , &( m_pStreamSdoServiceMarshal ) //Address of output variable that receives the IStream interface pointer for the marshaled interface.
  1077. );
  1078. WriteTrace("LOGGING NODE: CoMarshalInterThreadInterfaceInStream IID_ISdo spServiceSdo, hr = %x", hr);
  1079. if( FAILED( hr ) )
  1080. {
  1081. ErrorTrace(ERROR_NAPMMC_CONNECTION, "CoMarshalInterThreadInterfaceInStream failed, err = %x", hr);
  1082. WriteTrace("LOGGING NODE: ERROR, hr = %x ", hr);
  1083. m_wtsWorkerThreadStatus = WORKER_THREAD_ACTION_INTERRUPTED;
  1084. dwReturnValue = CONNECT_FAILED;
  1085. break;
  1086. }
  1087. // If we made it to here, we are OK.
  1088. _ASSERTE( m_pStreamSdoServiceMarshal != NULL );
  1089. m_wtsWorkerThreadStatus = WORKER_THREAD_FINISHED;
  1090. dwReturnValue = 0;
  1091. } while (0); // Loop for error checking only.
  1092. CoUninitialize();
  1093. DebugTrace(DEBUG_NAPMMC_CONNECTION, "NAP seems to have a valid connection to Sdo");
  1094. // Tell the main MMC thread what's up.
  1095. PostMessageToMainThread( dwReturnValue, NULL );
  1096. return dwReturnValue;
  1097. }