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.

914 lines
27 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. iroot.cpp
  5. Abstract:
  6. Internal implementation for the root subfolder.
  7. Environment:
  8. WIN32 User Mode
  9. Author:
  10. Darwin Ouyang (t-darouy) 30-Sept-1997
  11. --*/
  12. #include "StdAfx.h"
  13. #include "inode.h" // base class
  14. #include "iroot.h" // root folder
  15. #include "idevices.h" // devices folder
  16. #include "ilogging.h" // logging folder
  17. #include "faxsnapin.h" // snapin
  18. #include "faxdataobj.h" // dataobject
  19. #include "faxhelper.h" // ole helper functions
  20. #include "faxstrt.h" // string table
  21. #include "faxsecinfo.h" // fax security info
  22. #include "dgenprop.h" // general property sheet
  23. #include "droutpri.h" // routing priority property sheet
  24. #include <aclui.h> // acl editor property sheet
  25. #pragma hdrstop
  26. // context menu command
  27. #define RECONNECT_SERVER 101
  28. extern CStringTable * GlobalStringTable;
  29. // Generated with uuidgen. Each node must have a GUID associated with it.
  30. // This one is for the main root node.
  31. const GUID GUID_RootNode = /* 8f39b047-3071-11d1-9067-00a0c90ab504 */
  32. {
  33. 0x8f39b047,
  34. 0x3071,
  35. 0x11d1,
  36. {0x90, 0x67, 0x00, 0xa0, 0xc9, 0x0a, 0xb5, 0x04}
  37. };
  38. ////////////////////////////////////////////////////////////////////////////////////////////////////
  39. ////////////////////////////////////////////////////////////////////////////////////////////////////
  40. ////////////////////////////////////////////////////////////////////////////////////////////////////
  41. ////////////////////////////////////////////////////////////////////////////////////////////////////
  42. //
  43. //
  44. // Constructor and destructor
  45. //
  46. //
  47. CInternalRoot::CInternalRoot(
  48. IN CInternalNode * pParent,
  49. IN CFaxComponentData * pCompData )
  50. : CInternalNode( this, pCompData )
  51. /*++
  52. Routine Description:
  53. Constructor
  54. Arguments:
  55. pParent - pointer to parent node, in this case unused
  56. pCompData - pointer to IComponentData implementation for snapin global data
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. iDevices = NULL;
  62. iLogging = NULL;
  63. targetFaxServName = NULL;
  64. m_pCompData->m_FaxHandle = NULL;
  65. localNodeName = NULL;
  66. pMyPropSheet = NULL;
  67. pMyPropSheet2 = NULL;
  68. m_myPropPage = NULL;
  69. }
  70. CInternalRoot::~CInternalRoot()
  71. /*++
  72. Routine Description:
  73. Destructor
  74. Arguments:
  75. None.
  76. Return Value:
  77. None.
  78. --*/
  79. {
  80. if(iDevices != NULL ) {
  81. delete iDevices;
  82. }
  83. if(iLogging != NULL ) {
  84. delete iLogging;
  85. }
  86. if(m_pCompData->m_FaxHandle != NULL ) {
  87. FaxClose( m_pCompData->m_FaxHandle ); // close the connection
  88. m_pCompData->m_FaxHandle = NULL;
  89. }
  90. if(targetFaxServName != NULL ) {
  91. delete targetFaxServName;
  92. }
  93. }
  94. ////////////////////////////////////////////////////////////////////////////////////////////////////
  95. ////////////////////////////////////////////////////////////////////////////////////////////////////
  96. ////////////////////////////////////////////////////////////////////////////////////////////////////
  97. ////////////////////////////////////////////////////////////////////////////////////////////////////
  98. //
  99. //
  100. // Mandatory CInternalNode implementations.
  101. //
  102. //
  103. const GUID * CInternalRoot::GetNodeGUID()
  104. /*++
  105. Routine Description:
  106. Returns the node's associated GUID.
  107. Arguments:
  108. None.
  109. Return Value:
  110. A const pointer to a binary GUID.
  111. --*/
  112. {
  113. // DebugPrint(( TEXT("Trace: CInternalRoot::GetNodeGUID") ));
  114. return &GUID_RootNode;
  115. }
  116. const LPTSTR
  117. CInternalRoot::GetNodeDisplayName()
  118. /*++
  119. Routine Description:
  120. Returns a const TSTR pointer to the node's display name.
  121. Arguments:
  122. None.
  123. Return Value:
  124. A const pointer to a TSTR.
  125. --*/
  126. {
  127. // DebugPrint(( TEXT("Trace: CInternalRoot::GetNodeDisplayName") ));
  128. if( localNodeName == NULL ) {
  129. if( targetFaxServName != NULL ) {
  130. // remote machine
  131. localNodeName = new TCHAR[ StringSize( (::GlobalStringTable->GetString(IDS_ROOTNODENAME)) )
  132. + StringSize( targetFaxServName )
  133. + 1 ];
  134. assert( localNodeName != NULL );
  135. if (!localNodeName) {
  136. return NULL;
  137. }
  138. _tcscpy( localNodeName, ::GlobalStringTable->GetString(IDS_ROOTNODENAME) );
  139. _tcscat( localNodeName, targetFaxServName );
  140. } else {
  141. // local machine
  142. localNodeName = new TCHAR[ StringSize( (::GlobalStringTable->GetString(IDS_ROOTNODENAME)) )
  143. + StringSize( ::GlobalStringTable->GetString(IDS_LOCALMACHINE) )
  144. + 1 ];
  145. assert( localNodeName != NULL );
  146. if (!localNodeName) {
  147. return NULL;
  148. }
  149. _tcscpy( localNodeName, ::GlobalStringTable->GetString(IDS_ROOTNODENAME) );
  150. _tcscat( localNodeName, ::GlobalStringTable->GetString(IDS_LOCALMACHINE) );
  151. }
  152. }
  153. return localNodeName;
  154. }
  155. const LONG_PTR
  156. CInternalRoot::GetCookie()
  157. /*++
  158. Routine Description:
  159. Returns the cookie for this node.
  160. Arguments:
  161. None.
  162. Return Value:
  163. A const long containing the cookie for the pointer,
  164. in this case, a NULL, since the root node has no cookie.
  165. --*/
  166. {
  167. DebugPrint(( TEXT("Root Node Cookie: NULL") ));
  168. return NULL; // root node has no cookie.
  169. }
  170. void
  171. CInternalRoot::SetMachine(
  172. IN LPTSTR theName )
  173. /*++
  174. Routine Description:
  175. Sets the machine name for the root node. This is used by all other nodes
  176. to determine the target machine name.
  177. Arguments:
  178. A LPTSTR pointing to the machine name. It will be string copied to an internal store.
  179. Return Value:
  180. None.
  181. --*/
  182. {
  183. if(theName != NULL ) {
  184. targetFaxServName = new TCHAR[ MAX_COMPUTERNAME_LENGTH + 1 ];
  185. if (!targetFaxServName) {
  186. return;
  187. }
  188. ZeroMemory( (PVOID) targetFaxServName, (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( TCHAR ) );
  189. _tcsncpy( targetFaxServName, theName, MAX_COMPUTERNAME_LENGTH );
  190. targetFaxServName[MAX_COMPUTERNAME_LENGTH] = 0;
  191. } else {
  192. targetFaxServName = NULL;
  193. }
  194. }
  195. const LPTSTR
  196. CInternalRoot::GetMachine()
  197. /*++
  198. Routine Description:
  199. Returns the machine name for the root node. This is used by all other
  200. nodes to determine the target machine name.
  201. Arguments:
  202. None.
  203. Return Value:
  204. A const LPTSTR pointing to the machine name. Do not free this string, it is an internal
  205. buffer.
  206. --*/
  207. {
  208. return targetFaxServName;
  209. }
  210. ////////////////////////////////////////////////////////////////////////////////////////////////////
  211. ////////////////////////////////////////////////////////////////////////////////////////////////////
  212. ////////////////////////////////////////////////////////////////////////////////////////////////////
  213. ////////////////////////////////////////////////////////////////////////////////////////////////////
  214. //
  215. //
  216. // Internal Event Handlers
  217. //
  218. //
  219. HRESULT
  220. CInternalRoot::ScopeOnExpand(
  221. IN CFaxComponentData * pCompData,
  222. IN CFaxDataObject * pdo,
  223. IN LPARAM arg,
  224. IN LPARAM param )
  225. /*++
  226. Routine Description:
  227. Event handler for the MMCN_EXPAND message for the root node.
  228. Arguments:
  229. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  230. pdo - a pointer to the data object associated with this node
  231. arg, param - the arguements of the message
  232. Return Value:
  233. HRESULT which indicates SUCCEEDED() or FAILED()
  234. --*/
  235. {
  236. DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand") ));
  237. INT iResult;
  238. HRESULT hr = S_OK;
  239. LPCONSOLE console = pCompData->m_pConsole;
  240. HANDLE targetFaxServHandle = NULL;
  241. DWORD descCount = 0;
  242. assert(console != NULL); // make sure we QI'ed for the interface
  243. if(arg == TRUE) { // folder needs to be expanded
  244. DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - Expand folder") ));
  245. if(!pdo) {
  246. hr = console->MessageBox(::GlobalStringTable->GetString( IDS_CORRUPT_DATAOBJECT ),
  247. ::GlobalStringTable->GetString( IDS_ERR_TITLE ),
  248. MB_OK,
  249. &iResult);
  250. hr = E_INVALIDARG;
  251. return hr;
  252. }
  253. // Make sure that what we are placing ourselves under is the root node!
  254. if(pdo->GetCookie() != NULL)
  255. return S_FALSE;
  256. assert(pdo->GetContext() == CCT_SCOPE);
  257. //
  258. // Open the fax server connection.
  259. //
  260. try {
  261. if( FaxConnectFaxServer( targetFaxServName, &targetFaxServHandle ) == FALSE ) {
  262. m_pCompData->NotifyRpcError( TRUE );
  263. hr = console->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
  264. ::GlobalStringTable->GetString( IDS_ERR_TITLE ),
  265. MB_OK,
  266. &iResult);
  267. DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - open connection fail") ));
  268. hr = E_UNEXPECTED;
  269. } else {
  270. // sucessful connect!
  271. m_pCompData->NotifyRpcError( FALSE );
  272. }
  273. } catch( ... ) {
  274. m_pCompData->NotifyRpcError( TRUE );
  275. console->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
  276. ::GlobalStringTable->GetString( IDS_ERR_TITLE ),
  277. MB_OK,
  278. &iResult);
  279. hr = E_UNEXPECTED;
  280. DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - open connection fail") ));
  281. }
  282. //
  283. // short circuit if we failed to connect to faxsvc
  284. //
  285. if (FAILED(hr)) {
  286. return(hr);
  287. }
  288. m_pCompData->m_FaxHandle = targetFaxServHandle;
  289. //
  290. // Place our folder into the scope pane
  291. //
  292. // create a new internal representation of the devices folder.
  293. iDevices = new CInternalDevices( this, m_pCompData );
  294. assert( iDevices != NULL );
  295. if (!iDevices) {
  296. return(E_OUTOFMEMORY);
  297. }
  298. // insert devices folder
  299. hr = InsertItem( iDevices, param );
  300. // create a new internal representation of the logging folder.
  301. iLogging = new CInternalLogging( this, m_pCompData );
  302. assert( iLogging != NULL );
  303. if (!iLogging) {
  304. return(E_OUTOFMEMORY);
  305. }
  306. // insert logging folder
  307. hr = InsertItem( iLogging, param );
  308. } else if(arg == FALSE ) {
  309. DebugPrint(( TEXT("Trace: CInternalRoot::ScopeOnExpand - Contract folder") ));
  310. }
  311. return hr;
  312. }
  313. HRESULT
  314. CInternalRoot::ResultOnShow(
  315. IN CFaxComponent* pComp,
  316. IN CFaxDataObject * lpDataObject,
  317. IN LPARAM arg,
  318. IN LPARAM param)
  319. /*++
  320. Routine Description:
  321. Event handler for the MMCN_SHOW message for the root node.
  322. Arguments:
  323. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  324. lpDataObject - a pointer to the data object containing context information for this node.
  325. pdo - a pointer to the data object associated with this node
  326. arg, param - the arguements of the message
  327. Return Value:
  328. HRESULT which indicates SUCCEEDED() or FAILED()
  329. --*/
  330. {
  331. LPHEADERCTRL pIHeaderCtrl = pComp->m_pHeaderCtrl;
  332. HRESULT hr = S_OK;
  333. DebugPrint(( TEXT("Trace: CInternalRoot::ResultOnShow") ));
  334. assert( pIHeaderCtrl != NULL );
  335. if( arg == TRUE ) {
  336. do {
  337. // insert the icons into the image list
  338. hr = pComp->InsertIconsIntoImageList();
  339. assert( SUCCEEDED( hr ) );
  340. if( FAILED( hr ) ) {
  341. break;
  342. }
  343. hr = pIHeaderCtrl->InsertColumn( 0,
  344. ::GlobalStringTable->GetString( IDS_ROOT_NAME ),
  345. LVCFMT_LEFT,
  346. MMCLV_AUTO );
  347. if( FAILED( hr ) ) {
  348. break;
  349. }
  350. hr = pIHeaderCtrl->InsertColumn( 1,
  351. ::GlobalStringTable->GetString( IDS_ROOT_DESC ),
  352. LVCFMT_LEFT,
  353. MMCLV_AUTO );
  354. if( FAILED( hr ) ) {
  355. break;
  356. }
  357. } while( 0 );
  358. }
  359. return hr;
  360. }
  361. HRESULT
  362. CInternalRoot::ResultOnSelect(
  363. IN CFaxComponent* pComp,
  364. IN CFaxDataObject * lpDataObject,
  365. IN LPARAM arg,
  366. IN LPARAM param)
  367. /*++
  368. Routine Description:
  369. Event handler for the MMCN_SELECT message for the root node.
  370. Arguments:
  371. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  372. pdo - a pointer to the data object associated with this node
  373. arg, param - the arguements of the message
  374. Return Value:
  375. HRESULT which indicates SUCCEEDED() or FAILED()
  376. --*/
  377. {
  378. DebugPrint(( TEXT("Trace: CInternalRoot::ResultOnSelect") ));
  379. if( m_pCompData->QueryRpcError() == FALSE ) {
  380. pComp->m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE );
  381. pComp->m_pConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN );
  382. } else {
  383. pComp->m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, FALSE );
  384. pComp->m_pConsoleVerb->SetDefaultVerb( MMC_VERB_NONE );
  385. }
  386. return S_OK;
  387. }
  388. ////////////////////////////////////////////////////////////////////////////////////////////////////
  389. ////////////////////////////////////////////////////////////////////////////////////////////////////
  390. ////////////////////////////////////////////////////////////////////////////////////////////////////
  391. ////////////////////////////////////////////////////////////////////////////////////////////////////
  392. //
  393. //
  394. // IExtendPropertySheet implementation
  395. //
  396. //
  397. HRESULT
  398. STDMETHODCALLTYPE
  399. CInternalRoot::ComponentDataPropertySheetCreatePropertyPages(
  400. IN CFaxComponentData * pCompData,
  401. IN LPPROPERTYSHEETCALLBACK lpProvider,
  402. IN LONG_PTR handle,
  403. IN CFaxDataObject * lpIDataObject)
  404. /*++
  405. Routine Description:
  406. Event handler for the MMCN_EXPAND message for the root node.
  407. Arguments:
  408. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  409. pdo - a pointer to the data object associated with this node
  410. arg, param - the arguements of the message
  411. Return Value:
  412. HRESULT which indicates SUCCEEDED() or FAILED()
  413. --*/
  414. {
  415. DebugPrint(( TEXT("Trace: CInternalDevice::ComponentPropertySheetCreatePropertyPages") ));
  416. assert( lpIDataObject != NULL );
  417. assert( lpProvider != NULL );
  418. HRESULT hr;
  419. BOOL bResult = FALSE;
  420. PFAX_SECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  421. CFaxSecurityInformation * psi = NULL;
  422. DWORD descCount = 0;
  423. PFAX_GLOBAL_ROUTING_INFO pRoutingMethod;
  424. DWORD iRoutingMethodCount;
  425. DWORD i;
  426. WCHAR DllName[MAX_PATH];
  427. BOOL bUnknownMethod = FALSE;
  428. if( m_pCompData->QueryRpcError() == TRUE ) {
  429. assert( FALSE );
  430. return E_UNEXPECTED;
  431. }
  432. if( lpIDataObject == NULL || lpProvider == NULL ) {
  433. assert(FALSE);
  434. return E_POINTER;
  435. }
  436. pMyPropSheet = new CFaxGeneralSettingsPropSheet( ::GlobalStringTable->GetInstance(), handle, this );
  437. if (!pMyPropSheet) {
  438. hr = E_OUTOFMEMORY;
  439. goto e0;
  440. }
  441. hr = lpProvider->AddPage( pMyPropSheet->GetHandle() );
  442. if (FAILED(hr)) {
  443. goto e1;
  444. }
  445. try {
  446. //
  447. // do routing priority page
  448. //
  449. //
  450. // Check if we have non "default" extensions
  451. //
  452. if( !FaxEnumGlobalRoutingInfo( m_pCompData->m_FaxHandle,
  453. &pRoutingMethod,
  454. &iRoutingMethodCount ) ) {
  455. if (GetLastError() != ERROR_ACCESS_DENIED) {
  456. m_pCompData->NotifyRpcError( TRUE );
  457. assert(FALSE);
  458. }
  459. ::GlobalStringTable->SystemErrorMsg( GetLastError() );
  460. hr = E_UNEXPECTED;
  461. goto e1;
  462. } else {
  463. // go through the routing methods ensuring that
  464. // we know of all of them
  465. DWORD retval;
  466. retval = ExpandEnvironmentStrings(MSFAX_EXTENSION,DllName,MAX_PATH);
  467. if (retval == 0 || retval > MAX_PATH) {
  468. hr = E_OUTOFMEMORY;
  469. goto e1;
  470. }
  471. for( i=0; i<iRoutingMethodCount; i++ ) {
  472. if(wcscmp( pRoutingMethod[i].ExtensionImageName, DllName ) != 0) {
  473. bUnknownMethod = TRUE;
  474. break;
  475. }
  476. }
  477. FaxFreeBuffer( (PVOID)pRoutingMethod );
  478. // if we bumped into a method we don't know
  479. // then we put up the routing property sheet
  480. if( bUnknownMethod == TRUE ) {
  481. pMyPropSheet2 = new CFaxRoutePriPropSheet( ::GlobalStringTable->GetInstance(), handle, this, NULL );
  482. if (!pMyPropSheet2) {
  483. hr = E_OUTOFMEMORY;
  484. goto e1;
  485. }
  486. hr = lpProvider->AddPage( pMyPropSheet2->GetHandle() );
  487. if (FAILED(hr)) {
  488. goto e2;
  489. }
  490. }
  491. }
  492. if( FaxGetSecurityDescriptorCount( m_pCompData->m_FaxHandle, &descCount ) ) {
  493. // if there is only one descriptor we might as well just stick it in
  494. // the root node
  495. if( descCount == 1 ) {
  496. psi = new CComObject<CFaxSecurityInformation>;
  497. if (!psi) {
  498. hr = E_OUTOFMEMORY;
  499. goto e2;
  500. }
  501. psi->SetOwner( this );
  502. if( SUCCEEDED( psi->SetSecurityDescriptor( 0 ) ) ) {
  503. m_myPropPage = CreateSecurityPage( psi );
  504. hr = lpProvider->AddPage( m_myPropPage );
  505. } else {
  506. goto e3;
  507. }
  508. FaxFreeBuffer( (PVOID)pSecurityDescriptor );
  509. }
  510. }
  511. } catch ( ... ) {
  512. assert( FALSE );
  513. DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataPropertySheetCreatePropertyPages - RPC connection fail") ));
  514. m_pCompData->NotifyRpcError( TRUE );
  515. hr = E_UNEXPECTED;
  516. }
  517. return hr;
  518. e3:
  519. if (psi) delete(psi);
  520. e2:
  521. if (pMyPropSheet2) delete(pMyPropSheet2);
  522. e1:
  523. if (pMyPropSheet) delete(pMyPropSheet);
  524. e0:
  525. return(hr);
  526. }
  527. HRESULT
  528. STDMETHODCALLTYPE
  529. CInternalRoot::ComponentDataPropertySheetQueryPagesFor(
  530. IN CFaxComponentData * pCompData,
  531. IN CFaxDataObject * lpDataObject)
  532. /*++
  533. Routine Description:
  534. Returns S_OK to indicated there are property pages for this node.
  535. Arguments:
  536. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  537. lpDataObject - a pointer to the data object associated with this node
  538. Return Value:
  539. HRESULT which indicates SUCCEEDED() or FAILED()
  540. --*/
  541. {
  542. DebugPrint(( TEXT("Trace: CInternalDevice::ComponentPropertySheetQueryPagesFor") ));
  543. return S_OK;
  544. }
  545. ////////////////////////////////////////////////////////////////////////////////////////////////////
  546. ////////////////////////////////////////////////////////////////////////////////////////////////////
  547. ////////////////////////////////////////////////////////////////////////////////////////////////////
  548. ////////////////////////////////////////////////////////////////////////////////////////////////////
  549. //
  550. // IExtendContextMenu implementation
  551. //
  552. //
  553. HRESULT
  554. STDMETHODCALLTYPE
  555. CInternalRoot::ComponentDataContextMenuAddMenuItems(
  556. IN CFaxComponentData * pCompData,
  557. IN CFaxDataObject * piDataObject,
  558. IN LPCONTEXTMENUCALLBACK piCallback,
  559. IN OUT long __RPC_FAR *pInsertionAllowed)
  560. /*++
  561. Routine Description:
  562. Adds the context menu items to the root node.
  563. Arguments:
  564. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  565. piDataObject - a pointer to the data object associated with this node
  566. piCallback - a pointer the the IContextMenuCallback supplied by the MMC
  567. pInsertionAllowed - a set of flags to indicate whether context menu insertion is allows
  568. Return Value:
  569. HRESULT which indicates SUCCEEDED() or FAILED()
  570. --*/
  571. {
  572. DebugPrint(( TEXT("Trace: CInternalDevice::ComponentContextMenuAddMenuItems") ));
  573. CONTEXTMENUITEM menuItem;
  574. HRESULT hr = S_OK;
  575. if( !( *pInsertionAllowed | CCM_INSERTIONALLOWED_TOP ) ) {
  576. assert( FALSE );
  577. return E_UNEXPECTED;
  578. }
  579. if( m_pCompData->QueryRpcError() == TRUE ) {
  580. // build the submenu items
  581. ZeroMemory( ( void* )&menuItem, sizeof( menuItem ) );
  582. menuItem.strName = ::GlobalStringTable->GetString( IDS_RECONNECT );
  583. menuItem.strStatusBarText = ::GlobalStringTable->GetString( IDS_RECONNECT_DESC );
  584. menuItem.lCommandID = RECONNECT_SERVER;
  585. menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  586. menuItem.fFlags = MF_ENABLED;
  587. menuItem.fSpecialFlags = CCM_SPECIAL_DEFAULT_ITEM;
  588. hr = piCallback->AddItem( &menuItem );
  589. if( FAILED(hr) ) {
  590. assert(FALSE);
  591. return hr;
  592. }
  593. }
  594. return hr;
  595. }
  596. HRESULT
  597. STDMETHODCALLTYPE
  598. CInternalRoot::ComponentDataContextMenuCommand(
  599. IN CFaxComponentData * pCompData,
  600. IN long lCommandID,
  601. IN CFaxDataObject * piDataObject)
  602. /*++
  603. Routine Description:
  604. Handles the context menu events.
  605. Arguments:
  606. pCompData - a pointer to the instance of IComponentData which this root node is associated with.
  607. lCommandID - the command ID.
  608. piDataObject - a pointer to the data object associated with this node
  609. Return Value:
  610. HRESULT which indicates SUCCEEDED() or FAILED()
  611. --*/
  612. {
  613. DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataContextMenuCommand") ));
  614. HRESULT hr = S_OK;
  615. HANDLE targetFaxServHandle = NULL;
  616. int iResult;
  617. do {
  618. switch( lCommandID ) {
  619. case RECONNECT_SERVER:
  620. //
  621. // Re-open the fax server connection.
  622. //
  623. try {
  624. if( FaxConnectFaxServer( targetFaxServName, &targetFaxServHandle ) == FALSE ) {
  625. m_pCompData->NotifyRpcError( TRUE );
  626. hr = m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
  627. ::GlobalStringTable->GetString( IDS_ERR_TITLE ),
  628. MB_OK,
  629. &iResult);
  630. DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataContextMenuCommand - RE-OPEN connection fail") ));
  631. } else {
  632. // sucessful connect!
  633. m_pCompData->NotifyRpcError( FALSE );
  634. }
  635. } catch( ... ) {
  636. m_pCompData->NotifyRpcError( TRUE );
  637. m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_CONNECT_SERVER_FAIL ),
  638. ::GlobalStringTable->GetString( IDS_ERR_TITLE ),
  639. MB_OK,
  640. &iResult);
  641. DebugPrint(( TEXT("Trace: CInternalRoot::ComponentDataContextMenuCommand - RE-OPEN connection fail") ));
  642. hr = E_UNEXPECTED;
  643. break;
  644. }
  645. m_pCompData->m_FaxHandle = targetFaxServHandle;
  646. break;
  647. default:
  648. assert(FALSE);
  649. hr = E_UNEXPECTED;
  650. break;
  651. }
  652. } while( 0 );
  653. return hr;
  654. }
  655. ////////////////////////////////////////////////////////////////////////////////////////////////////
  656. ////////////////////////////////////////////////////////////////////////////////////////////////////
  657. ////////////////////////////////////////////////////////////////////////////////////////////////////
  658. ////////////////////////////////////////////////////////////////////////////////////////////////////
  659. //
  660. //
  661. // Utility Function
  662. //
  663. //
  664. HRESULT
  665. CInternalRoot::InsertItem(
  666. IN CInternalNode * iCookie,
  667. IN LPARAM param )
  668. /*++
  669. Routine Description:
  670. Wrapper that inserts an item into a scope view pane given a cookie.
  671. Arguments:
  672. iCookie - the cookie of the node that needs to be inserted into the view
  673. param - the HRESULTITEM of the parent to the node being inserted
  674. Return Value:
  675. HRESULT which indicates SUCCEEDED() or FAILED()
  676. --*/
  677. {
  678. SCOPEDATAITEM sdi;
  679. LPCONSOLENAMESPACE consoleNameSpace = m_pCompData->m_pConsoleNameSpace;
  680. assert(consoleNameSpace != NULL); // make sure we QI'ed for the interface
  681. ZeroMemory(&sdi, sizeof sdi);
  682. sdi.mask = SDI_STR | // displayname is valid
  683. SDI_PARAM | // lParam is valid
  684. SDI_IMAGE | // nImage is valid
  685. SDI_OPENIMAGE | // nOpenImage is valid
  686. SDI_CHILDREN | // cChildren is valid
  687. SDI_PARENT;
  688. sdi.relativeID = (HSCOPEITEM) param;
  689. sdi.nImage = iCookie->GetNodeDisplayImage();
  690. sdi.nOpenImage = iCookie->GetNodeDisplayOpenImage();
  691. sdi.displayname = MMC_CALLBACK;
  692. sdi.cChildren = 0;
  693. sdi.lParam = (LPARAM) iCookie; // The cookie
  694. return consoleNameSpace->InsertItem(&sdi);
  695. }