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.

1114 lines
28 KiB

  1. // Copyright Microsoft Corportation 1999-2000
  2. // Compdata.cpp : Implementation of CCompdata
  3. // IComponentData interface for ts mmc snapin
  4. // nadima
  5. #include "stdafx.h"
  6. #include "ntverp.h"
  7. #include "Tsmmc.h"
  8. #include "Compdata.h"
  9. #include "comp.h"
  10. #include "connode.h"
  11. #include "newcondlg.h"
  12. #include "property.h"
  13. #define ICON_MACHINE 1
  14. #define ICON_CONNECTED_MACHINE 2
  15. #define MSRDPCLIENT_CONTROL_GUID _T("{7cacbd7b-0d99-468f-ac33-22e495c0afe5}")
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CCompdata
  18. //
  19. CCompdata::CCompdata( )
  20. {
  21. m_pMainRoot = NULL;
  22. m_rootID = 0;
  23. LoadString( _Module.GetResourceInstance( ) , IDS_ROOTNODE_TEXT , m_szRootNodeName,
  24. SIZEOF_TCHARBUFFER( m_szRootNodeName ) );
  25. m_bIsDirty = FALSE;
  26. m_pConsole = NULL;
  27. m_pConsoleNameSpace = NULL;
  28. m_pDisplayHelp = NULL;
  29. }
  30. CCompdata::~CCompdata( )
  31. {
  32. if ( m_pMainRoot != NULL )
  33. {
  34. delete m_pMainRoot;
  35. }
  36. }
  37. //------------------------------------------------------------------------------------
  38. STDMETHODIMP CCompdata::CompareObjects( LPDATAOBJECT , LPDATAOBJECT )
  39. {
  40. return E_NOTIMPL;
  41. }
  42. //------------------------------------------------------------------------------------
  43. STDMETHODIMP CCompdata::GetDisplayInfo( LPSCOPEDATAITEM pItem)
  44. {
  45. CBaseNode* pNode = (CBaseNode*) pItem->lParam;
  46. if ( pNode->GetNodeType() == CONNECTION_NODE )
  47. {
  48. CConNode* conNode = (CConNode*) pNode;
  49. if ( pItem->mask & SDI_STR )
  50. {
  51. pItem->displayname = conNode->GetDescription();
  52. }
  53. }
  54. else if (pNode->GetNodeType() == MAIN_NODE)
  55. {
  56. if (pItem->mask & SDI_STR)
  57. {
  58. pItem->displayname = m_szRootNodeName;
  59. }
  60. }
  61. return S_OK;
  62. }
  63. //--------------------------------------------------------------------------------------------------
  64. STDMETHODIMP CCompdata::QueryDataObject( MMC_COOKIE cookie , DATA_OBJECT_TYPES type , LPDATAOBJECT *ppDataObject )
  65. {
  66. *ppDataObject = NULL;
  67. switch ( type )
  68. {
  69. case CCT_SCOPE: // FALL THROUGH
  70. case CCT_SNAPIN_MANAGER:
  71. if ( cookie == 0 )
  72. {
  73. *ppDataObject = ( LPDATAOBJECT )new CBaseNode( );
  74. if(!*ppDataObject)
  75. {
  76. return E_OUTOFMEMORY;
  77. }
  78. ((CBaseNode*) *ppDataObject)->SetNodeType(MAIN_NODE);
  79. }
  80. else
  81. {
  82. *ppDataObject = ( LPDATAOBJECT )cookie;
  83. // this is the only scopenode keep this one alive
  84. ( ( LPDATAOBJECT )*ppDataObject)->AddRef( );
  85. }
  86. break;
  87. case CCT_RESULT:
  88. // here we can cast from cookie for each node
  89. break;
  90. case CCT_UNINITIALIZED:
  91. break;
  92. }
  93. return( *ppDataObject == NULL ) ? E_FAIL : S_OK ;
  94. }
  95. //--------------------------------------------------------------------------------------------------
  96. STDMETHODIMP CCompdata::Notify( LPDATAOBJECT pDataObj , MMC_NOTIFY_TYPE event , LPARAM arg , LPARAM param )
  97. {
  98. HRESULT hr = NOERROR;
  99. switch ( event )
  100. {
  101. case MMCN_RENAME:
  102. ODS( L"IComponentdata -- MMCN_RENAME\n");
  103. break;
  104. case MMCN_EXPAND:
  105. ODS( L"IComponentdata -- MMCN_EXPAND\n" );
  106. ExpandScopeTree( pDataObj , ( BOOL ) arg , ( HSCOPEITEM )param );
  107. break;
  108. case MMCN_DELETE:
  109. ODS( L"IComponentdata -- MMCN_DELETE\n" );
  110. OnDelete( pDataObj );
  111. break;
  112. case MMCN_PROPERTY_CHANGE:
  113. ODS( L"IComponentdata -- MMCN_PROPERTY_CHANGE\n" );
  114. break;
  115. case MMCN_PRELOAD:
  116. ODS( L"PRELOAD - MMCN_PRELOAD\n");
  117. break;
  118. default:
  119. ODS( L"CCompdata::Notify - - event not defined!\n" );
  120. hr = E_NOTIMPL;
  121. }
  122. return hr;
  123. }
  124. //--------------------------------------------------------------------------------------------------
  125. STDMETHODIMP CCompdata::CreateComponent( LPCOMPONENT* ppComponent )
  126. {
  127. #ifdef ECP_TIMEBOMB
  128. if(!CheckTimeBomb())
  129. {
  130. return E_FAIL;
  131. }
  132. #endif
  133. CComObject< CComp > *pComp;
  134. HRESULT hr = CComObject< CComp >::CreateInstance( &pComp );
  135. if ( SUCCEEDED( hr ) )
  136. {
  137. hr = pComp->QueryInterface( IID_IComponent , ( LPVOID *)ppComponent );
  138. }
  139. if ( SUCCEEDED( hr ) )
  140. {
  141. pComp->SetCompdata( this );
  142. }
  143. return hr;
  144. }
  145. //--------------------------------------------------------------------------------------------------
  146. STDMETHODIMP CCompdata::Initialize( LPUNKNOWN pUnk )
  147. {
  148. HRESULT hr;
  149. hr = pUnk->QueryInterface( IID_IConsole , ( LPVOID *)&m_pConsole );
  150. if(FAILED(hr))
  151. {
  152. return hr;
  153. }
  154. hr = pUnk->QueryInterface( IID_IDisplayHelp, (LPVOID*)&m_pDisplayHelp );
  155. if(FAILED(hr))
  156. {
  157. return hr;
  158. }
  159. hr = pUnk->QueryInterface( IID_IConsoleNameSpace , ( LPVOID * )&m_pConsoleNameSpace );
  160. if(FAILED(hr))
  161. {
  162. return hr;
  163. }
  164. //
  165. // Load the scope pane icons
  166. //
  167. IImageList *pImageList;
  168. hr = m_pConsole->QueryScopeImageList(&pImageList);
  169. ASSERT(S_OK == hr);
  170. HR_RET_IF_FAIL(hr);
  171. if (!AddImages( pImageList))
  172. {
  173. ODS(L"AddImages failed!\n");
  174. return S_FALSE;
  175. }
  176. pImageList->Release();
  177. if(!AtlAxWinInit())
  178. {
  179. return E_FAIL;
  180. }
  181. return hr;
  182. }
  183. //--------------------------------------------------------------------------
  184. BOOL CCompdata::AddImages(IImageList* pImageList )
  185. {
  186. HICON hiconMachine = LoadIcon( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDI_ICON_MACHINE ) );
  187. HICON hiconConnectedMachine = LoadIcon( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDI_ICON_CONNECTED_MACHINE ) );
  188. HRESULT hr;
  189. ASSERT(pImageList);
  190. if (!pImageList)
  191. {
  192. return FALSE;
  193. }
  194. hr = pImageList->ImageListSetIcon( ( PLONG_PTR )hiconMachine , ICON_MACHINE );
  195. if (FAILED(hr))
  196. {
  197. return FALSE;
  198. }
  199. hr = pImageList->ImageListSetIcon( ( PLONG_PTR )hiconConnectedMachine , ICON_CONNECTED_MACHINE );
  200. if (FAILED(hr))
  201. {
  202. return FALSE;
  203. }
  204. return TRUE;
  205. }
  206. //--------------------------------------------------------------------------------------------------
  207. STDMETHODIMP CCompdata::Destroy()
  208. {
  209. HRESULT hr = S_OK;
  210. ODS(L"In CCompData::Destroy\n");
  211. ASSERT(m_pConsoleNameSpace);
  212. if(!m_pConsoleNameSpace)
  213. {
  214. return E_FAIL;
  215. }
  216. //
  217. // If there are any connection nodes left
  218. // they have to be deleted so they free
  219. // references to the TS control and the
  220. // multihost control
  221. //
  222. while(m_conNodesArray.GetSize())
  223. {
  224. CConNode** ppConNode = m_conNodesArray.GetAt(0);
  225. if(ppConNode)
  226. {
  227. //
  228. // Delete the connode and free any references
  229. // it has to controls
  230. //
  231. if(!DeleteConnode( *ppConNode))
  232. {
  233. hr = E_FAIL;
  234. goto bail_out;
  235. }
  236. }
  237. m_conNodesArray.DeleteItemAt(0);
  238. }
  239. hr = S_OK;
  240. bail_out:
  241. if ( m_pConsole != NULL )
  242. {
  243. m_pConsole->Release( );
  244. m_pConsole = NULL;
  245. }
  246. if ( m_pConsoleNameSpace != NULL )
  247. {
  248. m_pConsoleNameSpace->Release( );
  249. m_pConsoleNameSpace = NULL;
  250. }
  251. if ( m_pDisplayHelp )
  252. {
  253. m_pDisplayHelp->Release();
  254. m_pDisplayHelp = NULL;
  255. }
  256. AtlAxWinTerm();
  257. return hr;
  258. }
  259. //--------------------------------------------------------------------------
  260. BOOL CCompdata::OnDelete( LPDATAOBJECT pDo )
  261. {
  262. CConNode *pNode = dynamic_cast< CConNode *>( pDo );
  263. if ( pNode == NULL )
  264. {
  265. ODS( L"TSCC: OnDelete, node == NULL\n");
  266. return FALSE;
  267. }
  268. BOOL bFound;
  269. int idx = m_conNodesArray.FindItem( pNode , bFound );
  270. HRESULT hr;
  271. if ( bFound )
  272. {
  273. ASSERT(m_pConsoleNameSpace);
  274. if(!m_pConsoleNameSpace)
  275. {
  276. return E_FAIL;
  277. }
  278. ASSERT(m_pConsole);
  279. if(!m_pConsole)
  280. {
  281. return E_FAIL;
  282. }
  283. if(IsTSClientConnected(pNode))
  284. {
  285. //
  286. // Display a warning message prompt
  287. // deleting a connected node
  288. //
  289. int retVal =0;
  290. TCHAR szSnapinName[MAX_PATH];
  291. TCHAR szWarnDelete[MAX_PATH];
  292. if(LoadString(_Module.GetResourceInstance(),
  293. IDS_PROJNAME,
  294. szSnapinName,
  295. SIZEOF_TCHARBUFFER( szSnapinName)))
  296. {
  297. if(LoadString(_Module.GetResourceInstance(),
  298. IDS_MSG_WARNDELETE,
  299. szWarnDelete,
  300. SIZEOF_TCHARBUFFER(szWarnDelete)))
  301. {
  302. hr = m_pConsole->MessageBox( szWarnDelete, szSnapinName,
  303. MB_YESNO,
  304. &retVal);
  305. if(SUCCEEDED(hr) && (IDNO == retVal))
  306. {
  307. //We need to bail out user selected NO
  308. return TRUE;
  309. }
  310. }
  311. }
  312. }
  313. //
  314. // Delete the node
  315. //
  316. hr = m_pConsoleNameSpace->DeleteItem( pNode->GetScopeID(), TRUE);
  317. if (FAILED(hr))
  318. {
  319. return hr;
  320. }
  321. //
  322. // Delete the connode and free any references
  323. // it has to controls
  324. //
  325. DeleteConnode( pNode);
  326. m_conNodesArray.DeleteItemAt( idx );
  327. }
  328. m_pConsole->UpdateAllViews( ( LPDATAOBJECT )m_conNodesArray.GetAt( 0 ) , 0 , 0 );
  329. return TRUE;
  330. }
  331. //
  332. // Delete the given connection node
  333. // by disconnecting any connected clients
  334. // and releasing references to any controls
  335. //
  336. BOOL CCompdata::DeleteConnode(CConNode* pNode)
  337. {
  338. HRESULT hr = S_OK;
  339. BOOL fRet = TRUE;
  340. IMsRdpClient* pTS = NULL;
  341. if(!pNode)
  342. {
  343. fRet = FALSE;
  344. goto bail_out;
  345. }
  346. pTS = pNode->GetTsClient();
  347. if(NULL != pTS)
  348. {
  349. if (pNode->IsConnected())
  350. {
  351. hr = pTS->Disconnect();
  352. }
  353. if (SUCCEEDED(hr))
  354. {
  355. IMstscMhst* pMultiHost = NULL;
  356. pMultiHost = pNode->GetMultiHostCtl();
  357. //Remove references to controls to Release() them.
  358. pNode->SetTsClient(NULL);
  359. pNode->SetMultiHostCtl(NULL);
  360. //Remove the TS client from MultiHost control
  361. if(NULL != pMultiHost)
  362. {
  363. pMultiHost->Remove( pTS);
  364. pMultiHost->Release();
  365. pMultiHost = NULL;
  366. }
  367. }
  368. else
  369. {
  370. DBGMSG(L"Failed to disconnect: 0x%x\n", hr);
  371. fRet = FALSE;
  372. }
  373. pTS->Release();
  374. pTS = NULL;
  375. }
  376. pNode->Release();
  377. bail_out:
  378. return fRet;
  379. }
  380. //
  381. // Encrypt's and stores the password szPass in the connection
  382. // node.
  383. //
  384. HRESULT CCompdata::EncryptAndStorePass(LPTSTR szPass, CConNode* pConNode)
  385. {
  386. HRESULT hr = E_FAIL;
  387. if(!szPass || !pConNode) {
  388. return E_INVALIDARG;
  389. }
  390. hr = pConNode->SetClearTextPass(szPass);
  391. return hr;
  392. }
  393. //--------------------------------------------------------------------------------------------------
  394. STDMETHODIMP CCompdata::GetSnapinDescription( LPOLESTR * ppStr)
  395. {
  396. TCHAR tchDescription[ 1024 ];
  397. int iCharCount = LoadString( _Module.GetResourceInstance( ) , IDS_DESCRIPTION , tchDescription , SIZE_OF_BUFFER( tchDescription ) );
  398. *ppStr = ( LPOLESTR )CoTaskMemAlloc( iCharCount * sizeof( TCHAR ) + sizeof( TCHAR ) );
  399. if ( *ppStr != NULL )
  400. {
  401. lstrcpy( *ppStr , tchDescription );
  402. return S_OK;
  403. }
  404. return E_OUTOFMEMORY;
  405. }
  406. //--------------------------------------------------------------------------------------------------
  407. STDMETHODIMP CCompdata::GetProvider( LPOLESTR * ppStr)
  408. {
  409. TCHAR tchProvider[ 128 ];
  410. int iCharCount = LoadString( _Module.GetResourceInstance( ) , IDS_PROVIDER , tchProvider , SIZE_OF_BUFFER( tchProvider ) );
  411. *ppStr = ( LPOLESTR )CoTaskMemAlloc( iCharCount * sizeof( TCHAR ) + sizeof( TCHAR ) );
  412. if ( *ppStr != NULL )
  413. {
  414. lstrcpy( *ppStr , tchProvider );
  415. return S_OK;
  416. }
  417. return E_OUTOFMEMORY;
  418. }
  419. //--------------------------------------------------------------------------------------------------
  420. STDMETHODIMP CCompdata::GetSnapinVersion( LPOLESTR * ppStr )
  421. {
  422. char chVersion[ 32 ] = VER_PRODUCTVERSION_STR;
  423. TCHAR tchVersion[ 32 ];
  424. int iCharCount = MultiByteToWideChar( CP_ACP , 0 , chVersion , sizeof( chVersion ) , tchVersion , SIZE_OF_BUFFER( tchVersion ) );
  425. *ppStr = ( LPOLESTR )CoTaskMemAlloc( ( iCharCount + 1 ) * sizeof( TCHAR ) );
  426. if ( *ppStr != NULL && iCharCount != 0 )
  427. {
  428. lstrcpy( *ppStr , tchVersion );
  429. return S_OK;
  430. }
  431. return E_OUTOFMEMORY;
  432. }
  433. //--------------------------------------------------------------------------------------------------
  434. STDMETHODIMP CCompdata::GetSnapinImage( HICON * phIcon)
  435. {
  436. *phIcon = ( HICON )LoadImage( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDI_ICON_MACHINES ) , IMAGE_ICON , 32 ,32 , LR_DEFAULTCOLOR );
  437. return S_OK;
  438. }
  439. //--------------------------------------------------------------------------------------------------
  440. STDMETHODIMP CCompdata::GetStaticFolderImage( HBITMAP *phSmallImage , HBITMAP *phSmallImageOpen , HBITMAP *phLargeImage, COLORREF *pClr )
  441. {
  442. *phSmallImage = ( HBITMAP )LoadImage( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( UI_IDB_DOMAINEX ) , IMAGE_BITMAP , 16 ,16 , LR_DEFAULTCOLOR );
  443. *phSmallImageOpen = ( HBITMAP )LoadImage( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( UI_IDB_DOMAIN ) , IMAGE_BITMAP , 16 ,16 , LR_DEFAULTCOLOR );
  444. *phLargeImage = ( HBITMAP )LoadImage( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( UI_IDB_SERVER ) , IMAGE_BITMAP , 32 ,32 , LR_DEFAULTCOLOR );
  445. *pClr = RGB( 0 , 255 , 0 );
  446. return S_OK;
  447. }
  448. //----------------------------------------------------------------------------------------------------------
  449. // MMC will ask for our help file
  450. //----------------------------------------------------------------------------------------------------------
  451. STDMETHODIMP CCompdata::GetHelpTopic( LPOLESTR *ppszHelpFile )
  452. {
  453. ODS( L"CCompdata::GetHelpTopic called\n" );
  454. if( ppszHelpFile == NULL )
  455. {
  456. return E_INVALIDARG;
  457. }
  458. TCHAR tchHelpFile[ MAX_PATH ];
  459. if(!LoadString( _Module.GetResourceInstance( ) , IDS_TSCMMCSNAPHELP , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile )))
  460. {
  461. ODS( L"Error loading help file");
  462. return E_FAIL;
  463. }
  464. // mmc will call CoTaskMemFree
  465. *ppszHelpFile = ( LPOLESTR )CoTaskMemAlloc( sizeof( tchHelpFile ) );
  466. if( *ppszHelpFile != NULL )
  467. {
  468. if( GetSystemWindowsDirectory( *ppszHelpFile , MAX_PATH ) != 0 )
  469. {
  470. lstrcat( *ppszHelpFile , tchHelpFile );
  471. }
  472. else
  473. {
  474. lstrcpy( *ppszHelpFile , tchHelpFile );
  475. }
  476. ODS( *ppszHelpFile );
  477. ODS( L"\n" );
  478. return S_OK;
  479. }
  480. return E_OUTOFMEMORY;
  481. }
  482. //----------------------------------------------------------------------------------------------------------
  483. // Prepareing for parent entry
  484. BOOL CCompdata::ExpandScopeTree( LPDATAOBJECT pRoot , BOOL bExpand , HSCOPEITEM hConsole )
  485. {
  486. if ( !bExpand )
  487. {
  488. return FALSE;
  489. }
  490. CBaseNode *pNode = dynamic_cast< CBaseNode *>( pRoot );
  491. if ( pNode == NULL )
  492. {
  493. return FALSE;
  494. }
  495. if ( pNode->GetNodeType( ) != MAIN_NODE ) // ROOT_NODE add subscope items
  496. {
  497. return FALSE;
  498. }
  499. //
  500. // Keep track of the ID of the root node
  501. //
  502. m_rootID = hConsole;
  503. // make sure we're not re-adding
  504. if ( m_pMainRoot != NULL )
  505. {
  506. return TRUE;
  507. }
  508. //
  509. // In the case when we we have just loaded connection node
  510. // info from msc file, the new nodes have to be added to the
  511. // tree on the first expansion
  512. //
  513. for (int i=0; i<m_conNodesArray.GetSize(); i++)
  514. {
  515. CConNode** ppNode = m_conNodesArray.GetAt(i);
  516. if (!ppNode || *ppNode == NULL)
  517. {
  518. return S_FALSE;
  519. }
  520. if (FAILED(InsertConnectionScopeNode( *ppNode)))
  521. {
  522. return FALSE;
  523. }
  524. }
  525. return TRUE;
  526. }
  527. //
  528. // Figure out if the TS client is currently running in the result pane
  529. // and if so..is it connected
  530. //
  531. BOOL CCompdata::IsTSClientConnected(CConNode* pConNode)
  532. {
  533. short conn_status;
  534. IMsRdpClient* pTS;
  535. ASSERT(pConNode);
  536. if(!pConNode)
  537. {
  538. return FALSE;
  539. }
  540. if(pConNode->IsConnected())
  541. {
  542. pTS = pConNode->GetTsClient();
  543. if (NULL != pTS)
  544. {
  545. if(FAILED(pTS->get_Connected(&conn_status)))
  546. {
  547. return FALSE;
  548. }
  549. pTS->Release();
  550. //
  551. // Update connection node's con status
  552. //
  553. BOOL bConnected = (conn_status != 0);
  554. pConNode->SetConnected(bConnected);
  555. return (bConnected);
  556. }
  557. else
  558. {
  559. return FALSE;
  560. }
  561. }
  562. return FALSE;
  563. }
  564. HRESULT CCompdata::InsertConnectionScopeNode(CConNode* pNode)
  565. {
  566. //
  567. // Insert a new scope node for the connection node pNode
  568. //
  569. ASSERT(pNode);
  570. if (!pNode)
  571. {
  572. return S_FALSE;
  573. }
  574. SCOPEDATAITEM sdi;
  575. ZeroMemory( &sdi , sizeof( SCOPEDATAITEM ) );
  576. sdi.mask = SDI_STR | SDI_PARAM | SDI_PARENT | SDI_CHILDREN | SDI_IMAGE | SDI_OPENIMAGE;
  577. sdi.displayname = MMC_CALLBACK;
  578. sdi.relativeID = m_rootID;
  579. sdi.cChildren = 0;
  580. sdi.nImage = NOT_CONNECTED_IMAGE;
  581. sdi.nOpenImage = CONNECTED_IMAGE;
  582. sdi.lParam = (LPARAM)pNode;
  583. HRESULT hr;
  584. hr = m_pConsoleNameSpace->InsertItem( &sdi );
  585. if ( FAILED( hr ) )
  586. {
  587. return S_FALSE;
  588. }
  589. //
  590. // Keep track of the scope ID
  591. //
  592. pNode->SetScopeID(sdi.ID);
  593. return S_OK;
  594. }
  595. HRESULT CCompdata::AddNewConnection()
  596. {
  597. //
  598. // Invoke add new connection dialog...
  599. //
  600. HWND hwndMain;
  601. HRESULT hr;
  602. m_pConsole->GetMainWindow( &hwndMain);
  603. HINSTANCE hInst = _Module.GetModuleInstance();
  604. CNewConDlg dlg( hwndMain, hInst);
  605. INT_PTR dlgRetVal =dlg.DoModal();
  606. if (IDOK != dlgRetVal)
  607. {
  608. return S_FALSE;
  609. }
  610. CConNode* pConNode = new CConNode;
  611. if ( pConNode == NULL )
  612. {
  613. ODS( L"Scope node failed allocation\n" );
  614. return FALSE;
  615. }
  616. pConNode->SetNodeType( CONNECTION_NODE );
  617. pConNode->SetDescription( dlg.GetDescription());
  618. pConNode->SetServerName( dlg.GetServer());
  619. pConNode->SetConnectToConsole( dlg.GetConnectToConsole());
  620. pConNode->SetSavePassword( dlg.GetSavePassword());
  621. pConNode->SetUserName( dlg.GetUserName());
  622. pConNode->SetDomain( dlg.GetDomain());
  623. //
  624. // Encrypt the password and store it in the
  625. // connode
  626. //
  627. if (dlg.GetPasswordSpecified())
  628. {
  629. hr = EncryptAndStorePass( dlg.GetPassword(), pConNode);
  630. ASSERT(SUCCEEDED(hr));
  631. if(FAILED(hr))
  632. {
  633. return hr;
  634. }
  635. pConNode->SetPasswordSpecified(TRUE);
  636. }
  637. else
  638. {
  639. pConNode->SetPasswordSpecified(FALSE);
  640. }
  641. //
  642. // Need to mark state as dirty
  643. //
  644. m_bIsDirty = TRUE;
  645. m_conNodesArray.Insert( pConNode);
  646. //
  647. // Insert the actual scope node
  648. //
  649. hr = InsertConnectionScopeNode( pConNode);
  650. return hr;
  651. }
  652. //IPersistStreamInit
  653. STDMETHODIMP CCompdata::GetClassID(CLSID *pClassID)
  654. {
  655. UNREFERENCED_PARAMETER(pClassID);
  656. ATLTRACENOTIMPL(_T("CCOMPDATA::GetClassID"));
  657. }
  658. STDMETHODIMP CCompdata::IsDirty()
  659. {
  660. if (m_bIsDirty)
  661. {
  662. //
  663. // Signal that changes have been made
  664. //
  665. return S_OK;
  666. }
  667. return S_FALSE;
  668. }
  669. STDMETHODIMP CCompdata::SetDirty(BOOL dirty)
  670. {
  671. m_bIsDirty = dirty;
  672. return S_OK;
  673. }
  674. STDMETHODIMP CCompdata::Load(IStream *pStm)
  675. {
  676. HRESULT hr;
  677. ATLTRACE(_T("CCOMPDATA::Load"));
  678. //
  679. // Initialize from the stream
  680. // there should be no connection nodes at this time
  681. //
  682. if ( m_conNodesArray.GetSize() != 0)
  683. {
  684. ASSERT(m_conNodesArray.GetSize());
  685. return FALSE;
  686. }
  687. LONG nodeCount;
  688. ULONG cbRead;
  689. //
  690. // Read in the nodeCount
  691. //
  692. hr = pStm->Read( &nodeCount, sizeof(nodeCount), &cbRead);
  693. HR_RET_IF_FAIL(hr);
  694. //
  695. // Create new connection nodes from the persisted data
  696. //
  697. for (int i = 0; i < nodeCount; i++)
  698. {
  699. CConNode* pNode = new CConNode();
  700. if (!pNode)
  701. {
  702. return E_OUTOFMEMORY;
  703. }
  704. hr = pNode->InitFromStream( pStm);
  705. HR_RET_IF_FAIL(hr);
  706. pNode->SetNodeType( CONNECTION_NODE );
  707. m_conNodesArray.Insert(pNode);
  708. }
  709. return S_OK;
  710. }
  711. STDMETHODIMP CCompdata::Save(IStream *pStm, BOOL fClearDirty)
  712. {
  713. HRESULT hr;
  714. ATLTRACE(_T("CCOMPDATA::Save"));
  715. UNREFERENCED_PARAMETER(fClearDirty);
  716. //
  717. // Save the connection nodes to the stream
  718. //
  719. LONG nodeCount;
  720. nodeCount = m_conNodesArray.GetSize();
  721. ULONG cbWritten;
  722. //
  723. // Write out the nodecount
  724. //
  725. hr = pStm->Write( &nodeCount, sizeof(nodeCount), &cbWritten);
  726. HR_RET_IF_FAIL(hr);
  727. //
  728. // Persist out each connection node's data
  729. //
  730. for (int i = 0; i < nodeCount; i++)
  731. {
  732. CConNode** ppNode = m_conNodesArray.GetAt(i);
  733. ASSERT(ppNode);
  734. if (!ppNode || *ppNode == NULL)
  735. {
  736. return S_FALSE;
  737. }
  738. hr = (*ppNode)->PersistToStream( pStm);
  739. HR_RET_IF_FAIL(hr);
  740. }
  741. //
  742. // We are clean at this point
  743. //
  744. SetDirty(FALSE);
  745. return S_OK;
  746. }
  747. STDMETHODIMP CCompdata::GetSizeMax(ULARGE_INTEGER *pcbSize)
  748. {
  749. ATLTRACENOTIMPL(_T("CCOMPDATA::GetSizeMax"));
  750. UNREFERENCED_PARAMETER(pcbSize);
  751. }
  752. STDMETHODIMP CCompdata::InitNew()
  753. {
  754. ATLTRACE(_T("CCOMPDATA::InitNew\n"));
  755. return S_OK;
  756. }
  757. // IExtendPropertySheet
  758. STDMETHODIMP CCompdata::CreatePropertyPages(
  759. LPPROPERTYSHEETCALLBACK psc,
  760. LONG_PTR Handle,
  761. LPDATAOBJECT pDo
  762. )
  763. {
  764. IPropertySheetProvider* pPropSheetProvider = NULL;
  765. CProperty* prop = NULL;
  766. UNREFERENCED_PARAMETER(Handle);
  767. HRESULT hr = S_FALSE;
  768. if (!psc || !pDo) {
  769. return E_UNEXPECTED;
  770. }
  771. ASSERT( ((CBaseNode*)pDo)->GetNodeType() == CONNECTION_NODE);
  772. if (((CBaseNode*)pDo)->GetNodeType() != CONNECTION_NODE) {
  773. return E_UNEXPECTED;
  774. }
  775. CConNode* pCon = (CConNode*) pDo;
  776. ASSERT(pCon);
  777. if (!pCon) {
  778. return S_FALSE;
  779. }
  780. HWND hMain;
  781. if (FAILED( m_pConsole->GetMainWindow(&hMain ))) {
  782. hMain = NULL;
  783. return E_FAIL;
  784. }
  785. prop = new CProperty( hMain, _Module.GetModuleInstance());
  786. if (!prop) {
  787. return E_OUTOFMEMORY;
  788. }
  789. prop->SetDisplayHelp( m_pDisplayHelp );
  790. prop->SetDescription( pCon->GetDescription());
  791. prop->SetServer( pCon->GetServerName() );
  792. prop->SetResType( pCon->GetResType() );
  793. prop->SetWidth( pCon->GetDesktopWidth() );
  794. prop->SetHeight( pCon->GetDesktopHeight() );
  795. prop->SetProgramPath( pCon->GetProgramPath() );
  796. prop->SetWorkDir( pCon->GetWorkDir());
  797. //
  798. // Enable the start program option if a program is specified
  799. //
  800. if (lstrcmp(pCon->GetProgramPath(), L""))
  801. {
  802. prop->SetStartProgram(TRUE);
  803. }
  804. else
  805. {
  806. prop->SetStartProgram(FALSE);
  807. }
  808. prop->SetSavePassword( pCon->GetSavePassword() );
  809. prop->SetUserName( pCon->GetUserName() );
  810. prop->SetDomain( pCon->GetDomain());
  811. prop->SetConnectToConsole( pCon->GetConnectToConsole());
  812. prop->SetRedirectDrives( pCon->GetRedirectDrives() );
  813. //hr = prop->InitPropSheets( hMain, psc, pCon, Handle);
  814. //ASSERT(S_OK == hr);
  815. if (prop->CreateModalPropPage())
  816. {
  817. BOOL bThisNodeIsDirty = FALSE;
  818. //user OK'd the property sheet
  819. //
  820. // Save the new values if any changes have been made
  821. //
  822. //
  823. // Prop page 1 values
  824. //
  825. if (lstrcmp(prop->GetDescription(),pCon->GetDescription()))
  826. {
  827. bThisNodeIsDirty = TRUE;
  828. pCon->SetDescription( prop->GetDescription());
  829. }
  830. if (lstrcmp(prop->GetServer(),pCon->GetServerName()))
  831. {
  832. bThisNodeIsDirty = TRUE;
  833. pCon->SetServerName( prop->GetServer());
  834. }
  835. if (lstrcmp(prop->GetUserName(),pCon->GetUserName()))
  836. {
  837. bThisNodeIsDirty = TRUE;
  838. pCon->SetUserName( prop->GetUserName());
  839. }
  840. if(prop->GetChangePassword())
  841. {
  842. if (prop->GetPasswordSpecified())
  843. {
  844. //
  845. // User requested to change password. Encrypt and
  846. // store this new password
  847. //
  848. bThisNodeIsDirty = TRUE;
  849. hr = EncryptAndStorePass( prop->GetPassword(), pCon);
  850. ASSERT(SUCCEEDED(hr));
  851. if(FAILED(hr))
  852. {
  853. DBGMSG(_T("EncryptAndStorePassFailed 0x%x\n"), hr);
  854. goto bail_out;
  855. }
  856. pCon->SetPasswordSpecified(TRUE);
  857. }
  858. else
  859. {
  860. pCon->SetPasswordSpecified(FALSE);
  861. }
  862. }
  863. if (lstrcmp(prop->GetDomain(),pCon->GetDomain()))
  864. {
  865. bThisNodeIsDirty = TRUE;
  866. pCon->SetDomain( prop->GetDomain());
  867. }
  868. if (prop->GetSavePassword() != pCon->GetSavePassword())
  869. {
  870. bThisNodeIsDirty = TRUE;
  871. pCon->SetSavePassword( prop->GetSavePassword());
  872. }
  873. if (prop->GetConnectToConsole() != pCon->GetConnectToConsole())
  874. {
  875. bThisNodeIsDirty = TRUE;
  876. pCon->SetConnectToConsole( prop->GetConnectToConsole());
  877. }
  878. //
  879. // Prop page 2
  880. //
  881. if (prop->GetResType() != pCon->GetResType())
  882. {
  883. bThisNodeIsDirty = TRUE;
  884. pCon->SetResType( prop->GetResType());
  885. }
  886. if (prop->GetWidth() != pCon->GetDesktopWidth())
  887. {
  888. bThisNodeIsDirty = TRUE;
  889. pCon->SetDesktopWidth( prop->GetWidth());
  890. }
  891. if (prop->GetHeight() != pCon->GetDesktopHeight())
  892. {
  893. bThisNodeIsDirty = TRUE;
  894. pCon->SetDesktopHeight( prop->GetHeight());
  895. }
  896. //
  897. // Prop page 3
  898. //
  899. if (lstrcmp(prop->GetProgramPath(), pCon->GetProgramPath()))
  900. {
  901. bThisNodeIsDirty = TRUE;
  902. pCon->SetProgramPath( prop->GetProgramPath());
  903. }
  904. if (lstrcmp(prop->GetWorkDir(), pCon->GetWorkDir()))
  905. {
  906. bThisNodeIsDirty = TRUE;
  907. pCon->SetWorkDir( prop->GetWorkDir());
  908. }
  909. if (prop->GetRedirectDrives() != pCon->GetRedirectDrives())
  910. {
  911. bThisNodeIsDirty = TRUE;
  912. pCon->SetRedirectDrives( prop->GetRedirectDrives() );
  913. }
  914. if(bThisNodeIsDirty)
  915. {
  916. //Set snapin-wide is dirty flag for persistence
  917. m_bIsDirty = TRUE;
  918. //Mark the conn settings as uninitialized so that they are
  919. //reset on the next connection
  920. pCon->SetConnectionInitialized(FALSE);
  921. }
  922. }
  923. bail_out:
  924. if (prop) {
  925. delete prop;
  926. }
  927. //
  928. // We return failure because we're not using MMC's prop sheet
  929. // mechanism as we want a modal prop sheet. Returning failure
  930. // causes MMC to properly cleanup all the propsheet resources
  931. // it allocated
  932. //
  933. return E_FAIL;
  934. }
  935. STDMETHODIMP CCompdata::QueryPagesFor( LPDATAOBJECT pDo)
  936. {
  937. if ( dynamic_cast< CConNode *>( pDo ) == NULL )
  938. {
  939. return S_FALSE;
  940. }
  941. return S_OK;
  942. }