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.

1381 lines
34 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. BaseHSM.cpp
  5. Abstract:
  6. Implementation of ISakNode interface.
  7. Author:
  8. Rohde Wakefield [rohde] 04-Mar-1997
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "CSakData.h"
  13. #include "CSakSnap.h"
  14. /////////////////////////////////////////////////////////////////////////////
  15. //
  16. // CoComObjectRoot
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. //---------------------------------------------------------------------------
  20. //
  21. // FinalConstruct
  22. //
  23. // Initialize this level of the object hierarchy
  24. //
  25. HRESULT CSakNode::FinalConstruct( )
  26. {
  27. WsbTraceIn( L"CSakNode::FinalConstruct", L"" );
  28. // Connection point variables
  29. m_Advise = 0;
  30. m_bEnumState = FALSE;
  31. m_scopeID = UNINITIALIZED;
  32. m_bChildrenAreValid = FALSE;
  33. m_bHasDynamicChildren = FALSE;
  34. m_cChildProps = 0;
  35. m_cChildPropsShow = 0;
  36. m_bSupportsPropertiesNoEngine = FALSE;
  37. m_bSupportsPropertiesSingle = FALSE;
  38. m_bSupportsPropertiesMulti = FALSE;
  39. m_bSupportsRefreshNoEngine = FALSE;
  40. m_bSupportsRefreshSingle = FALSE;
  41. m_bSupportsRefreshMulti = FALSE;
  42. m_bSupportsDeleteSingle = FALSE;
  43. m_bSupportsDeleteMulti = FALSE;
  44. m_PrivateData = 0;
  45. // Initialize toolbar stuff. If not overrided,
  46. // node does not have a toolbar
  47. m_ToolbarBitmap = UNINITIALIZED;
  48. m_cToolbarButtons = 0;
  49. INT i;
  50. for( i = 0; i < MAX_TOOLBAR_BUTTONS; i++ ) {
  51. m_ToolbarButtons[i].nBitmap = UNINITIALIZED;
  52. m_ToolbarButtons[i].idCommand = UNINITIALIZED;
  53. m_ToolbarButtons[i].fsState = TBSTATE_ENABLED;
  54. m_ToolbarButtons[i].fsType = TBSTYLE_BUTTON;
  55. m_ToolbarButtons[i].idButtonText = UNINITIALIZED;
  56. m_ToolbarButtons[i].idTooltipText = UNINITIALIZED;
  57. }
  58. // Do not initialize m_nOpenIcon and m_nCloseIcon. The derived classes
  59. // will do that.
  60. HRESULT hr = CComObjectRoot::FinalConstruct( );
  61. WsbTraceOut( L"CSakNode::FinalConstruct", L"hr = <%ls>", WsbHrAsString( hr ) );
  62. return( hr );
  63. }
  64. HRESULT CSakNode::OnToolbarButtonClick( IDataObject * /* pDataObject */, long /* cmdId */ )
  65. {
  66. return S_OK;
  67. }
  68. //---------------------------------------------------------------------------
  69. //
  70. // FinalRelease
  71. //
  72. // Clean up this level of the object hierarchy
  73. //
  74. void CSakNode::FinalRelease( )
  75. {
  76. WsbTraceIn( L"CSakNode::FinalRelease", L"" );
  77. //
  78. // Free the children of this node.
  79. //
  80. DeleteAllChildren( );
  81. //
  82. // Free the child properties list and their widths.
  83. //
  84. FreeChildProps();
  85. CComObjectRoot::FinalRelease( );
  86. WsbTraceOut( L"CSakNode::FinalRelease", L"" );
  87. }
  88. void CSakNode::SetConnection( IUnknown *pUnkConnection )
  89. {
  90. WsbTraceIn( L"CSakNode::SetConnection", L"" );
  91. HRESULT hr = S_OK;
  92. try {
  93. WsbAffirmPointer ( pUnkConnection );
  94. m_pUnkConnection = pUnkConnection;
  95. //
  96. // Set up the connection point
  97. //
  98. WsbAffirmHr( AtlAdvise( pUnkConnection, (IUnknown *) (ISakNode*) this, IID_IHsmEvent, &m_Advise ) );
  99. } WsbCatch ( hr );
  100. WsbTraceOut( L"CSakNode::SetConnection", L"" );
  101. }
  102. // Connection point "callback"
  103. STDMETHODIMP CSakNode::OnStateChange( )
  104. {
  105. WsbTraceIn( L"CSakNode::OnStateChange", L"" );
  106. HRESULT hr = S_OK;
  107. try {
  108. WsbAffirmHr( m_pSakSnapAsk->UpdateAllViews( this ) );
  109. } WsbCatch( hr );
  110. WsbTraceOut( L"CSakNode::OnStateChange", L"hr = <%ls>", WsbHrAsString( hr ) );
  111. return( S_OK );
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. //
  115. // ISakNode
  116. //
  117. /////////////////////////////////////////////////////////////////////////////
  118. //---------------------------------------------------------------------------
  119. //
  120. // get/put_DisplayName
  121. //
  122. // Give back the 'DisplayName' property.
  123. //
  124. STDMETHODIMP CSakNode::get_DisplayName( BSTR *pName )
  125. {
  126. WsbTraceIn( L"CSakNode::get_DisplayName", L"pName = <0x%p>", pName );
  127. HRESULT hr = S_OK;
  128. try {
  129. WsbAffirmPointer( pName );
  130. *pName = 0;
  131. BSTR name = 0;
  132. if( m_szName ) {
  133. name = SysAllocString( m_szName );
  134. WsbAffirmAlloc( name );
  135. }
  136. *pName = name;
  137. } WsbCatch( hr );
  138. WsbTraceOut( L"CSakNode::get_DisplayName", L"hr = <%ls>, *pName = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pName ) );
  139. return( hr );
  140. }
  141. STDMETHODIMP CSakNode::put_DisplayName( OLECHAR *pszName )
  142. {
  143. WsbTraceIn( L"CSakNode::put_DisplayName", L"pszName = <%ls>", pszName );
  144. HRESULT hr = S_OK;
  145. m_szName = pszName;
  146. WsbTraceOut( L"CSakNode::put_DisplayName", L"hr = <%ls>", WsbHrAsString( hr ) );
  147. return( hr );
  148. }
  149. STDMETHODIMP CSakNode::get_DisplayName_SortKey( BSTR *pName )
  150. {
  151. WsbTraceIn( L"CSakNode::get_DisplayName_SortKey", L"pName = <0x%p>", pName );
  152. HRESULT hr = S_OK;
  153. try {
  154. WsbAffirmPointer( pName );
  155. *pName = 0;
  156. BSTR name = 0;
  157. if( m_szName_SortKey ) {
  158. name = SysAllocString( m_szName_SortKey );
  159. WsbAffirmAlloc( name );
  160. } else if( m_szName ) {
  161. name = SysAllocString( m_szName );
  162. WsbAffirmAlloc( name );
  163. }
  164. *pName = name;
  165. } WsbCatch( hr );
  166. WsbTraceOut( L"CSakNode::get_DisplayName_SortKey", L"hr = <%ls>, *pName = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pName ) );
  167. return( hr );
  168. }
  169. STDMETHODIMP CSakNode::put_DisplayName_SortKey( OLECHAR *pszName )
  170. {
  171. WsbTraceIn( L"CSakNode::put_DisplayName_SortKey", L"pszName = <%ls>", pszName );
  172. HRESULT hr = S_OK;
  173. m_szName_SortKey = pszName;
  174. WsbTraceOut( L"CSakNode::put_DisplayName_SortKey", L"hr = <%ls>", WsbHrAsString( hr ) );
  175. return( hr );
  176. }
  177. //---------------------------------------------------------------------------
  178. //
  179. // get/put_Type
  180. //
  181. // Give back the 'Type' property.
  182. //
  183. STDMETHODIMP CSakNode::get_Type( BSTR *pType )
  184. {
  185. WsbTraceIn( L"CSakNode::get_Type", L"pType = <0x%p>", pType );
  186. HRESULT hr = S_OK;
  187. try {
  188. WsbAffirmPointer( pType );
  189. *pType = 0;
  190. BSTR type = 0;
  191. if( m_szType ) {
  192. type = SysAllocString( m_szType );
  193. WsbAffirmAlloc( type );
  194. }
  195. *pType = type;
  196. } WsbCatch( hr );
  197. WsbTraceOut( L"CSakNode::get_Type", L"hr = <%ls>, *pType = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pType ) );
  198. return( hr );
  199. }
  200. STDMETHODIMP CSakNode::put_Type( OLECHAR *pszType )
  201. {
  202. WsbTraceIn( L"CSakNode::put_Type", L"pszType = <%ls>", pszType );
  203. HRESULT hr = S_OK;
  204. m_szType = pszType;
  205. WsbTraceOut( L"CSakNode::put_Type", L"hr = <%ls>", WsbHrAsString( hr ) );
  206. return( hr );
  207. }
  208. STDMETHODIMP CSakNode::get_Type_SortKey( BSTR *pType )
  209. {
  210. WsbTraceIn( L"CSakNode::get_Type_SortKey", L"pType = <0x%p>", pType );
  211. HRESULT hr = S_OK;
  212. try {
  213. WsbAffirmPointer( pType );
  214. *pType = 0;
  215. BSTR type = 0;
  216. if( m_szType ) {
  217. type = SysAllocString( m_szType );
  218. WsbAffirmAlloc( type );
  219. }
  220. *pType = type;
  221. } WsbCatch( hr );
  222. WsbTraceOut( L"CSakNode::get_Type_SortKey", L"hr = <%ls>, *pType = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pType ) );
  223. return( hr );
  224. }
  225. //---------------------------------------------------------------------------
  226. //
  227. // get/put_Description
  228. //
  229. // Give back the 'Description' property.
  230. //
  231. STDMETHODIMP CSakNode::get_Description( BSTR *pDesc )
  232. {
  233. WsbTraceIn( L"CSakNode::get_Description", L"pDesc = <0x%p>", pDesc );
  234. HRESULT hr = S_OK;
  235. try {
  236. WsbAffirmPointer( pDesc );
  237. *pDesc = 0;
  238. BSTR desc = 0;
  239. if( m_szDesc ) {
  240. desc = SysAllocString( m_szDesc );
  241. WsbAffirmAlloc( desc );
  242. }
  243. *pDesc = desc;
  244. } WsbCatch( hr );
  245. WsbTraceOut( L"CSakNode::get_Description", L"hr = <%ls>, *pDesc = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pDesc ) );
  246. return( hr );
  247. }
  248. STDMETHODIMP CSakNode::put_Description( OLECHAR *pszDesc )
  249. {
  250. WsbTraceIn( L"CSakNode::put_Description", L"pszDesc = <%ls>", pszDesc );
  251. HRESULT hr = S_OK;
  252. m_szDesc = pszDesc;
  253. WsbTraceOut( L"CSakNode::put_Description", L"hr = <%ls>", WsbHrAsString( hr ) );
  254. return( hr );
  255. }
  256. STDMETHODIMP CSakNode::get_Description_SortKey( BSTR *pDesc )
  257. {
  258. WsbTraceIn( L"CSakNode::get_Description_SortKey", L"pDesc = <0x%p>", pDesc );
  259. HRESULT hr = S_OK;
  260. try {
  261. WsbAffirmPointer( pDesc );
  262. *pDesc = 0;
  263. BSTR desc = 0;
  264. if( m_szDesc ) {
  265. desc = SysAllocString( m_szDesc );
  266. WsbAffirmAlloc( desc );
  267. }
  268. *pDesc = desc;
  269. } WsbCatch( hr );
  270. WsbTraceOut( L"CSakNode::get_Description_SortKey", L"hr = <%ls>, *pDesc = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pDesc ) );
  271. return( hr );
  272. }
  273. //---------------------------------------------------------------------------
  274. //
  275. // ChildrenAreValid
  276. //
  277. // Report if node's current list of children are valid. Things that can make the
  278. // children invalid are:
  279. // 1) They have not yet been discovered.
  280. // 2) Something has occurred in the "external" world to cause them to become out-of-date.
  281. //
  282. STDMETHODIMP CSakNode::ChildrenAreValid( void )
  283. {
  284. WsbTraceIn( L"CSakNode::ChildrenAreValid", L"" );
  285. HRESULT hr = m_bChildrenAreValid ? S_OK : S_FALSE;
  286. WsbTraceOut( L"CSakNode::ChildrenAreValid", L"hr = <%ls>", WsbHrAsString( hr ) );
  287. return( hr );
  288. }
  289. //---------------------------------------------------------------------------
  290. //
  291. // InvalidateChildren
  292. //
  293. STDMETHODIMP CSakNode::InvalidateChildren( void )
  294. {
  295. WsbTraceIn( L"CSakNode::InvalidateChildren", L"" );
  296. HRESULT hr = S_OK;
  297. m_bChildrenAreValid = FALSE;
  298. WsbTraceOut( L"CSakNode::InvalidateChildren", L"hr = <%ls>", WsbHrAsString( hr ) );
  299. return( hr );
  300. }
  301. //---------------------------------------------------------------------------
  302. //
  303. // GetEnumState / SetEnumState
  304. //
  305. // Report if node's children have already been enumerated once. This is a convenience
  306. // function to help users of nodes from needlessly enumerating children if it has already
  307. // been done.
  308. //
  309. // !! future work - if the hsm engine changes the children of a node, making re-enumeration
  310. // necessary, this switch could be turned back to FALSE so that the next time a node
  311. // is queried as to its enumeration state, it would show up as needing enumeration.
  312. //
  313. STDMETHODIMP CSakNode::GetEnumState( BOOL* pState )
  314. {
  315. WsbTraceIn( L"CSakNode::GetEnumState", L"pState = <0x%p>", pState );
  316. HRESULT hr = S_OK;
  317. *pState = m_bEnumState;
  318. WsbTraceOut( L"CSakNode::GetEnumState", L"hr = <%ls>, *pState = <%ls>", WsbHrAsString( hr ), WsbPtrToBoolAsString( pState ) );
  319. return( hr );
  320. }
  321. STDMETHODIMP CSakNode::SetEnumState( BOOL state )
  322. {
  323. WsbTraceIn( L"CSakNode::SetEnumState", L"state = <%ls>", WsbBoolAsString( state ) );
  324. HRESULT hr = S_OK;
  325. m_bEnumState = state;
  326. WsbTraceOut( L"CSakNode::SetEnumState", L"hr = <%ls>", WsbHrAsString( hr ) );
  327. return( hr );
  328. }
  329. //---------------------------------------------------------------------------
  330. //
  331. // GetHsmObj
  332. //
  333. // Return a pointer to the underlying Hsm Object that the CBaseHsm
  334. // object encapsulates.
  335. //
  336. STDMETHODIMP CSakNode::GetHsmObj( IUnknown** ppHsmObj )
  337. {
  338. WsbTraceIn( L"CSakNode::GetHsmObj", L"ppHsmObj = <0x%p>", ppHsmObj );
  339. HRESULT hr = S_OK;
  340. m_pHsmObj.CopyTo( ppHsmObj );
  341. WsbTraceOut( L"CSakNode::GetHsmObj", L"hr = <%ls>, *ppHsmObj = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppHsmObj ) );
  342. return( hr );
  343. }
  344. //---------------------------------------------------------------------------
  345. //
  346. // GetParent
  347. //
  348. // Return the cookie of the parent node
  349. //
  350. STDMETHODIMP CSakNode::GetParent( ISakNode** ppParent )
  351. {
  352. WsbTraceIn( L"CSakNode::GetParent", L"ppParent = <0x%p>", ppParent );
  353. HRESULT hr = S_OK;
  354. try {
  355. WsbAffirmPointer( ppParent );
  356. m_pParent.CopyTo( ppParent );
  357. } WsbCatch( hr );
  358. WsbTraceOut( L"CSakNode::GetParent", L"hr = <%ls>, *ppParent = <0x%p>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppParent ) );
  359. return( hr );
  360. }
  361. //---------------------------------------------------------------------------
  362. //
  363. // GetScopeID / SetScopeID
  364. //
  365. // Put and set the scopeview ID for this item into the node, itself.
  366. //
  367. STDMETHODIMP CSakNode::GetScopeID( HSCOPEITEM* pid )
  368. {
  369. WsbTraceIn( L"CSakNode::GetScopeID", L"pid = <0x%p>", pid );
  370. HRESULT hr = S_OK;
  371. *pid = m_scopeID;
  372. if( m_scopeID == UNINITIALIZED ) {
  373. hr = E_PENDING;
  374. }
  375. WsbTraceOut( L"CSakNode::GetScopeID", L"hr = <%ls>, *pid = <0x%p>", WsbHrAsString( hr ), *pid );
  376. return( hr );
  377. }
  378. STDMETHODIMP CSakNode::SetScopeID( HSCOPEITEM id )
  379. {
  380. WsbTraceIn( L"CSakNode::SetScopeID", L"id = <0x%p>", id );
  381. HRESULT hr = S_OK;
  382. m_scopeID = id;
  383. WsbTraceOut( L"CSakNode::SetScopeID", L"hr = <%ls>", WsbHrAsString( hr ) );
  384. return( hr );
  385. }
  386. //---------------------------------------------------------------------------
  387. //
  388. // EnumChildren
  389. //
  390. // Create an enumerator and return the children.
  391. //
  392. STDMETHODIMP CSakNode::EnumChildren( IEnumUnknown ** ppEnum )
  393. {
  394. WsbTraceIn( L"CSakNode::EnumChildren", L"ppEnum = <0x%p>", ppEnum );
  395. HRESULT hr = S_OK;
  396. CEnumUnknown * pEnum = 0;
  397. try {
  398. WsbAffirmPointer( ppEnum );
  399. *ppEnum = 0;
  400. //
  401. // New an ATL enumerator
  402. //
  403. pEnum = new CEnumUnknown;
  404. WsbAffirmAlloc( pEnum );
  405. //
  406. // Initialize it to copy the current child interface pointers
  407. //
  408. WsbAffirmHr( pEnum->FinalConstruct() );
  409. if( m_Children.begin( ) ) {
  410. WsbAffirmHr( pEnum->Init( (IUnknown**)m_Children.begin( ), (IUnknown**)m_Children.end( ), NULL, AtlFlagCopy ) );
  411. } else {
  412. static IUnknown* pUnkDummy;
  413. WsbAffirmHr( pEnum->Init( &pUnkDummy, &pUnkDummy, NULL, AtlFlagCopy ) );
  414. }
  415. WsbAffirmHr( pEnum->QueryInterface( IID_IEnumUnknown, (void**)ppEnum ) );
  416. } WsbCatchAndDo( hr,
  417. if( pEnum ) delete pEnum;
  418. );
  419. WsbTraceOut( L"CSakNode::EnumChildren", L"hr = <%ls>, *ppEnum = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppEnum ) );
  420. return( hr );
  421. }
  422. //---------------------------------------------------------------------------
  423. //
  424. // EnumChildDisplayPropWidths
  425. //
  426. // Enumerate back the widths for the properties of my children that should be
  427. // shown in the result pane view.
  428. //
  429. STDMETHODIMP CSakNode::EnumChildDisplayPropWidths( IEnumString** ppEnum )
  430. {
  431. WsbTraceIn( L"CSakNode::EnumChildDisplayPropWidths", L"ppEnum = <0x%p>", ppEnum );
  432. HRESULT hr = S_OK;
  433. CEnumString * pEnum = 0;
  434. try {
  435. WsbAffirmPointer( ppEnum );
  436. WsbAffirm( m_cChildPropsShow > 0, S_FALSE );
  437. *ppEnum = 0;
  438. //
  439. // New an ATL enumerator
  440. //
  441. pEnum = new CEnumString;
  442. WsbAffirmAlloc( pEnum );
  443. WsbAffirmHr( pEnum->FinalConstruct( ) );
  444. WsbAffirmHr( pEnum->Init( &m_rgszChildPropWidths[0], &m_rgszChildPropWidths[m_cChildPropsShow], NULL, AtlFlagCopy ) );
  445. WsbAffirmHr( pEnum->QueryInterface( IID_IEnumString, (void**)ppEnum ) );
  446. } WsbCatchAndDo( hr,
  447. if( pEnum ) delete pEnum;
  448. );
  449. WsbTraceOut( L"CSakNode::EnumChildDisplayPropWidths", L"hr = <%ls>, *ppEnum = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppEnum ) );
  450. return( hr );
  451. }
  452. //---------------------------------------------------------------------------
  453. //
  454. // EnumChildDisplayProps
  455. //
  456. // Enumerate back the properties of my children that should be shown in the
  457. // result pane view.
  458. //
  459. STDMETHODIMP CSakNode::EnumChildDisplayProps( IEnumString ** ppEnum )
  460. {
  461. WsbTraceIn( L"CSakNode::EnumChildDisplayProps", L"ppEnum = <0x%p>", ppEnum );
  462. HRESULT hr = S_OK;
  463. CEnumString * pEnum = 0;
  464. try {
  465. WsbAffirmPointer( ppEnum );
  466. WsbAffirm( m_cChildPropsShow > 0, S_FALSE );
  467. *ppEnum = 0;
  468. //
  469. // New an ATL enumerator
  470. //
  471. pEnum = new CEnumString;
  472. WsbAffirmAlloc( pEnum );
  473. WsbAffirmHr( pEnum->FinalConstruct( ) );
  474. WsbAffirmHr( pEnum->Init( &m_rgszChildPropIds[0], &m_rgszChildPropIds[m_cChildPropsShow], NULL, AtlFlagCopy ) );
  475. WsbAffirmHr( pEnum->QueryInterface( IID_IEnumString, (void**)ppEnum ) );
  476. } WsbCatchAndDo( hr,
  477. if( pEnum ) delete pEnum;
  478. );
  479. WsbTraceOut( L"CSakNode::EnumChildDisplayProps", L"hr = <%ls>, *ppEnum = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppEnum ) );
  480. return( hr );
  481. }
  482. //---------------------------------------------------------------------------
  483. //
  484. // EnumChildDisplayTitles
  485. //
  486. // Enumerate back the properties of my children that should be shown in the
  487. // result pane view.
  488. //
  489. STDMETHODIMP CSakNode::EnumChildDisplayTitles( IEnumString ** ppEnum )
  490. {
  491. WsbTraceIn( L"CSakNode::EnumChildDisplayTitles", L"ppEnum = <0x%p>", ppEnum );
  492. HRESULT hr = S_OK;
  493. CEnumString * pEnum = 0;
  494. try {
  495. WsbAffirmPointer( ppEnum );
  496. WsbAffirm( m_cChildPropsShow > 0, S_FALSE );
  497. *ppEnum = 0;
  498. //
  499. // New an ATL enumerator
  500. //
  501. pEnum = new CEnumString;
  502. WsbAffirmAlloc( pEnum );
  503. WsbAffirmHr( pEnum->FinalConstruct( ) );
  504. WsbAffirmHr( pEnum->Init( &m_rgszChildPropTitles[0], &m_rgszChildPropTitles[m_cChildPropsShow], NULL, AtlFlagCopy ) );
  505. WsbAffirmHr( pEnum->QueryInterface( IID_IEnumString, (void**)ppEnum ) );
  506. } WsbCatchAndDo( hr,
  507. if( pEnum ) delete pEnum;
  508. );
  509. WsbTraceOut( L"CSakNode::EnumChildDisplayTitles", L"hr = <%ls>, *ppEnum = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppEnum ) );
  510. return( hr );
  511. }
  512. /////////////////////////////////////////////////////////////////////////////
  513. //
  514. // Helper Functions for derived classes
  515. //
  516. /////////////////////////////////////////////////////////////////////////////
  517. //---------------------------------------------------------------------------
  518. //
  519. // LoadContextMenu
  520. //
  521. // Loads the specified menu resource and returns the first
  522. // popup menu in it - used for context menus
  523. //
  524. HRESULT CSakNode::LoadContextMenu( UINT nId, HMENU *phMenu )
  525. {
  526. WsbTraceIn( L"CSakNode::LoadContextMenu", L"nId = <%u>, phMenu = <0x%p>", nId, phMenu );
  527. *phMenu = LoadMenu ( _Module.m_hInst, MAKEINTRESOURCE( nId ) );
  528. HRESULT hr = *phMenu ? S_OK : E_FAIL;
  529. WsbTraceOut( L"CSakNode::LoadContextMenu", L"hr = <%ls>, *phMenu = <0x%p>", WsbHrAsString( hr ), *phMenu );
  530. return( hr );
  531. }
  532. //---------------------------------------------------------------------------
  533. //
  534. // FindNodeOfType
  535. //
  536. // Recursive search through nodes. Give back the IUnknown* interface of the
  537. // "nodetype" object (JobDefLst, JobPolLst, etc).
  538. //
  539. STDMETHODIMP
  540. CSakNode::FindNodeOfType(REFGUID nodetype, ISakNode** ppNode)
  541. {
  542. WsbTraceIn( L"CSakNode::FindNodeOfType", L"nodetype = <%ls>, ppNode = <0x%p>", WsbGuidAsString( nodetype ), ppNode );
  543. HRESULT hr = S_FALSE;
  544. // check if this is the node we are looking for.
  545. if( IsEqualGUID( *m_rTypeGuid, nodetype ) ) {
  546. *ppNode = (ISakNode*)this;
  547. (*ppNode)->AddRef( );
  548. hr = S_OK;
  549. } else {
  550. // Search for correct node in this node's children.
  551. try {
  552. ISakNode** ppNodeEnum;
  553. for( ppNodeEnum = m_Children.begin( ); ppNodeEnum < m_Children.end( ); ppNodeEnum++ ) {
  554. if( *ppNodeEnum ) {
  555. hr = (*ppNodeEnum)->FindNodeOfType( nodetype, ppNode );
  556. if( hr == S_OK ) {
  557. break;
  558. }
  559. }
  560. }
  561. } WsbCatch( hr );
  562. }
  563. WsbTraceOut( L"CSakNode::FindNodeOfType", L"hr = <%ls>, *ppNode = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppNode ) );
  564. return( hr );
  565. }
  566. //-----------------------------------------------------------------------------
  567. //
  568. // SetChildProps
  569. //
  570. // Set the result view column properties
  571. //
  572. HRESULT
  573. CSakNode::SetChildProps (
  574. const TCHAR* ResIdPropsIds,
  575. LONG ResIdPropsTitles,
  576. LONG ResIdPropsWidths
  577. )
  578. /*++
  579. Routine Description:
  580. Set the result view Ids, Titles, and Width strings from the
  581. given resource Ids.
  582. Arguments:
  583. Return Value:
  584. S_OK - All added fine - continue.
  585. E_UNEXPECTED - Some error occurred.
  586. --*/
  587. {
  588. WsbTraceIn( L"CSakNode::SetChildProps", L"ResIdPropsIds = <%ls>, ResIdPropsTitles = <%ld>, ResIdPropsWidths = <%ld>", ResIdPropsIds, ResIdPropsTitles, ResIdPropsWidths );
  589. CString szResource;
  590. CWsbStringPtr szWsbData;
  591. OLECHAR* szData;
  592. HRESULT hr = S_OK;
  593. INT i = 0;
  594. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  595. try {
  596. // First clean up the current properties (if any)
  597. FreeChildProps();
  598. // Properties Ids
  599. szWsbData = ResIdPropsIds;
  600. szData = szWsbData;
  601. szData = wcstok( szData, L":" );
  602. while( szData ) {
  603. m_rgszChildPropIds[m_cChildProps] = SysAllocString( szData );
  604. WsbAffirmAlloc( m_rgszChildPropIds[m_cChildProps] );
  605. szData = wcstok( NULL, L":" );
  606. m_cChildProps++;
  607. }
  608. // Property Titles
  609. i = 0;
  610. szResource.LoadString (ResIdPropsTitles);
  611. szWsbData = szResource;
  612. szData = szWsbData;
  613. szData = wcstok( szData, L":" );
  614. while( szData ) {
  615. m_rgszChildPropTitles[i] = SysAllocString( szData );
  616. WsbAffirmAlloc( m_rgszChildPropTitles[i] );
  617. szData = wcstok( NULL, L":" );
  618. i++;
  619. }
  620. // Properties Widths
  621. i = 0;
  622. szResource.LoadString( ResIdPropsWidths );
  623. szWsbData = szResource;
  624. szData = szWsbData;
  625. szData = wcstok( szData, L":" );
  626. while( szData ) {
  627. m_rgszChildPropWidths[i] = SysAllocString( szData );
  628. WsbAffirmAlloc( m_rgszChildPropWidths[i] );
  629. szData = wcstok( NULL, L":" );
  630. i++;
  631. }
  632. //
  633. // By default, show all props
  634. //
  635. m_cChildPropsShow = m_cChildProps;
  636. } WsbCatch( hr );
  637. WsbTraceOut( L"CSakNode::SetChildProps", L"hr = <%ls>", WsbHrAsString( hr ) );
  638. return( hr );
  639. }
  640. //-------------------------------------------------------------------------------
  641. //
  642. // FreeChildProps
  643. //
  644. // free up the old child properties and widths
  645. //
  646. HRESULT
  647. CSakNode::FreeChildProps()
  648. {
  649. WsbTraceIn( L"CSakNode::FreeChildProps", L"" );
  650. HRESULT hr = S_OK;
  651. for( INT i = 0; i < m_cChildProps; i++ ) {
  652. if( m_rgszChildPropIds[i] ) SysFreeString( m_rgszChildPropIds[i] );
  653. if( m_rgszChildPropTitles[i]) SysFreeString( m_rgszChildPropTitles[i] );
  654. if( m_rgszChildPropWidths[i]) SysFreeString( m_rgszChildPropWidths[i] );
  655. }
  656. m_cChildProps = 0;
  657. m_cChildPropsShow = 0;
  658. WsbTraceOut( L"CSakNode::FreeChildProps", L"hr = <%ls>", WsbHrAsString( hr ) );
  659. return( hr );
  660. }
  661. //---------------------------------------------------------------------------------
  662. //
  663. // RefreshObject
  664. //
  665. // Fetch up-to-date information for the object. Implemented in derived
  666. // classes
  667. //
  668. STDMETHODIMP
  669. CSakNode::RefreshObject ()
  670. {
  671. WsbTraceIn( L"CSakNode::RefreshObject", L"" );
  672. HRESULT hr = S_OK;
  673. WsbTraceOut( L"CSakNode::RefreshObject", L"hr = <%ls>", WsbHrAsString( hr ) );
  674. return( hr );
  675. }
  676. //---------------------------------------------------------------------------------
  677. //
  678. // DeleteObject
  679. //
  680. // Fetch up-to-date information for the object. Implemented in derived
  681. // classes
  682. //
  683. STDMETHODIMP
  684. CSakNode::DeleteObject ()
  685. {
  686. WsbTraceIn( L"CSakNode::DeleteObject", L"" );
  687. HRESULT hr = S_OK;
  688. WsbTraceOut( L"CSakNode::DeleteObject", L"hr = <%ls>", WsbHrAsString( hr ) );
  689. return( hr );
  690. }
  691. /////////////////////////////////////////////////////////////////////////////
  692. //
  693. // Local utility functions
  694. //
  695. /////////////////////////////////////////////////////////////////////////////
  696. STDMETHODIMP
  697. CSakNode::GetMenuHelp (
  698. LONG sCmd,
  699. BSTR * szHelp
  700. )
  701. /*++
  702. Routine Description:
  703. Retrieve .
  704. Arguments:
  705. pDataObject - identifies the node to be worked on.
  706. pContextMenuCallback - The MMC menu interface to use.
  707. Return Value:
  708. S_OK - All added fine - continue.
  709. E_UNEXPECTED - Some error occurred.
  710. --*/
  711. {
  712. WsbTraceIn( L"CSakNode::GetMenuHelp", L"sCmd = <%ld>, szHelp = <0x%p>", sCmd, szHelp );
  713. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  714. HRESULT hr = S_OK;
  715. CString string;
  716. try {
  717. if ( string.LoadString ( sCmd ) ) {
  718. *szHelp = string.AllocSysString ( );
  719. } else {
  720. //
  721. // Must not be a help string - return S_FALSE
  722. //
  723. *szHelp = 0;
  724. hr = S_FALSE;
  725. }
  726. } catch ( CMemoryException ) {
  727. //
  728. // If out of memory, return as such
  729. //
  730. *szHelp = 0;
  731. hr = E_OUTOFMEMORY;
  732. }
  733. WsbTraceOut( L"CSakNode::GetMenuHelp", L"hr = <%ls>, *szHelp = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( szHelp ) );
  734. return( hr );
  735. }
  736. STDMETHODIMP CSakNode::SupportsProperties ( BOOL bMultiSelect )
  737. {
  738. WsbTraceIn( L"CSakNode::SupportsProperties", L"" );
  739. HRESULT hr = S_OK;
  740. if( bMultiSelect ) {
  741. hr = m_bSupportsPropertiesMulti ? S_OK : S_FALSE;
  742. } else {
  743. hr = m_bSupportsPropertiesSingle ? S_OK : S_FALSE;
  744. }
  745. WsbTraceOut( L"CSakNode::SupportsProperties", L"hr = <%ls>", WsbHrAsString( hr ) );
  746. return( hr );
  747. }
  748. STDMETHODIMP CSakNode::SupportsPropertiesNoEngine ( )
  749. {
  750. WsbTraceIn( L"CSakNode::SupportsPropertiesNoEngine", L"" );
  751. HRESULT hr = S_OK;
  752. hr = m_bSupportsPropertiesNoEngine ? S_OK : S_FALSE;
  753. WsbTraceOut( L"CSakNode::SupportsPropertiesNoEngine", L"hr = <%ls>", WsbHrAsString( hr ) );
  754. return( hr );
  755. }
  756. STDMETHODIMP CSakNode::SupportsRefresh ( BOOL bMultiSelect )
  757. {
  758. WsbTraceIn( L"CSakNode::SupportsRefresh", L"" );
  759. HRESULT hr = S_OK;
  760. if( bMultiSelect ) {
  761. hr = m_bSupportsRefreshMulti ? S_OK : S_FALSE;
  762. } else {
  763. hr = m_bSupportsRefreshSingle ? S_OK : S_FALSE;
  764. }
  765. WsbTraceOut( L"CSakNode::SupportsRefresh", L"hr = <%ls>", WsbHrAsString( hr ) );
  766. return( hr );
  767. }
  768. STDMETHODIMP CSakNode::SupportsRefreshNoEngine ( )
  769. {
  770. WsbTraceIn( L"CSakNode::SupportsRefreshNoEngine", L"" );
  771. HRESULT hr = S_OK;
  772. hr = m_bSupportsRefreshNoEngine ? S_OK : S_FALSE;
  773. WsbTraceOut( L"CSakNode::SupportsRefreshNoEngine", L"hr = <%ls>", WsbHrAsString( hr ) );
  774. return( hr );
  775. }
  776. STDMETHODIMP CSakNode::SupportsDelete ( BOOL bMultiSelect )
  777. {
  778. WsbTraceIn( L"CSakNode::SupportsDelete", L"" );
  779. HRESULT hr = S_OK;
  780. if( bMultiSelect ) {
  781. hr = m_bSupportsDeleteMulti ? S_OK : S_FALSE;
  782. } else {
  783. hr = m_bSupportsDeleteSingle ? S_OK : S_FALSE;
  784. }
  785. WsbTraceOut( L"CSakNode::SupportsDelete", L"hr = <%ls>", WsbHrAsString( hr ) );
  786. return( hr );
  787. }
  788. STDMETHODIMP CSakNode::IsContainer (void )
  789. {
  790. WsbTraceIn( L"CSakNode::IsContainer", L"" );
  791. HRESULT hr = m_bIsContainer ? S_OK : S_FALSE;
  792. WsbTraceOut( L"CSakNode::IsContainer", L"hr = <%ls>", WsbHrAsString( hr ) );
  793. return( hr );
  794. }
  795. STDMETHODIMP CSakNode::HasDynamicChildren( void )
  796. {
  797. WsbTraceIn( L"CSakNode::HasDynamicChildren", L"" );
  798. HRESULT hr = m_bHasDynamicChildren ? S_OK : S_FALSE;
  799. WsbTraceOut( L"CSakNode::HasDynamicChildren", L"hr = <%ls>", WsbHrAsString( hr ) );
  800. return( hr );
  801. }
  802. STDMETHODIMP CSakNode::IsValid( void )
  803. {
  804. WsbTraceIn( L"CSakNode::IsValid", L"" );
  805. HRESULT hr = S_OK;
  806. WsbTraceOut( L"CSakNode::IsValid", L"hr = <%ls>", WsbHrAsString( hr ) );
  807. return( hr );
  808. }
  809. STDMETHODIMP CSakNode::GetNodeType ( GUID* pGuid )
  810. {
  811. WsbTraceIn( L"CSakNode::GetNodeType", L"pGuid = <0x%p>", pGuid );
  812. HRESULT hr = S_OK;
  813. *pGuid = *m_rTypeGuid;
  814. WsbTraceOut( L"CSakNode::GetNodeType", L"hr = <%ls>, *pGuid = <%ls>", WsbHrAsString( hr ), WsbPtrToGuidAsString( pGuid ) );
  815. return( hr );
  816. }
  817. STDMETHODIMP CSakNode::AddPropertyPages( RS_NOTIFY_HANDLE /*handle*/, IUnknown* /*pUnkPropSheetCallback*/, IEnumGUID* /*pEnumObjectId*/, IEnumUnknown* /*pEnumUnkNode*/ )
  818. {
  819. //
  820. // CSakNode does not implement prop sheets. However, some
  821. // derived nodes also do not implement, so we provide a default
  822. // not impl here
  823. //
  824. WsbTraceIn( L"CSakNode::AddPropertyPages", L"" );
  825. HRESULT hr = S_OK;
  826. WsbTraceOut( L"CSakNode::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) );
  827. return( hr );
  828. }
  829. STDMETHODIMP CSakNode::GetObjectId( GUID *pObjectId)
  830. {
  831. HRESULT hr = S_OK;
  832. WsbTraceIn( L"CSakNode::GetObjectId", L"" );
  833. *pObjectId = m_ObjectId;
  834. WsbTraceOut( L"CSakNode::GetObjectId", L"hr = <%ls>", WsbHrAsString( hr ) );
  835. return( hr );
  836. }
  837. STDMETHODIMP CSakNode::SetObjectId( GUID pObjectId)
  838. {
  839. HRESULT hr = S_OK;
  840. WsbTraceIn( L"CSakNode::SetObjectId", L"" );
  841. m_ObjectId = pObjectId;
  842. WsbTraceOut( L"CSakNode::SetObjectId", L"hr = <%ls>", WsbHrAsString( hr ) );
  843. return( hr );
  844. }
  845. STDMETHODIMP CSakNode::GetPrivateData( RS_PRIVATE_DATA *pData )
  846. {
  847. WsbTraceIn( L"CSakNode::GetPrivateData", L"" );
  848. HRESULT hr = S_OK;
  849. try {
  850. WsbAffirmPointer( pData );
  851. *pData = m_PrivateData;
  852. } WsbCatch( hr );
  853. WsbTraceOut( L"CSakNode::GetPrivateData", L"hr = <%ls>, *pData = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)pData ) );
  854. return( hr );
  855. }
  856. STDMETHODIMP CSakNode::SetPrivateData( RS_PRIVATE_DATA Data )
  857. {
  858. WsbTraceIn( L"CSakNode::SetPrivateData", L"pData = <0x%p>", Data );
  859. HRESULT hr = S_OK;
  860. m_PrivateData = Data;
  861. WsbTraceOut( L"CSakNode::SetPrivateData", L"hr = <%ls>", WsbHrAsString( hr ) );
  862. return( hr );
  863. }
  864. //---------------------------------------------------------------------------
  865. //
  866. // CSakNode::ActivateView
  867. //
  868. // Activate a result pane view - not supported in CSakNode.
  869. //
  870. STDMETHODIMP
  871. CSakNode::ActivateView( OLE_HANDLE )
  872. {
  873. WsbTraceIn( L"CSakNode::ActivateView", L"" );
  874. HRESULT hr = S_FALSE;
  875. WsbTraceOut( L"CSakNode::ActivateView", L"hr = <%ls>", WsbHrAsString( hr ) );
  876. return( hr );
  877. }
  878. STDMETHODIMP
  879. CSakNode::HasToolbar( )
  880. {
  881. return ( m_cToolbarButtons > 0 ) ? S_OK : S_FALSE;
  882. }
  883. STDMETHODIMP
  884. CSakNode::SetupToolbar( IToolbar *pToolbar )
  885. {
  886. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  887. CBitmap *pBmpToolbar;
  888. HRESULT hr = S_OK;
  889. MMCBUTTON mmcButton;
  890. if( ( m_cToolbarButtons > 0 ) && ( m_ToolbarBitmap != UNINITIALIZED ) ) {
  891. try {
  892. //
  893. // Add the bitmap
  894. //
  895. pBmpToolbar = new ::CBitmap;
  896. pBmpToolbar->LoadBitmap(m_ToolbarBitmap);
  897. WsbAffirmHr ( pToolbar->AddBitmap(m_cToolbarButtons, *pBmpToolbar, 16, 16, RGB(255, 0, 255)) );
  898. //
  899. // Convert the RS button format to MMCBUTTON
  900. //
  901. for( INT i = 0; i < m_cToolbarButtons; i++ ) {
  902. mmcButton.nBitmap = m_ToolbarButtons[i].nBitmap;
  903. mmcButton.idCommand = m_ToolbarButtons[i].idCommand;
  904. mmcButton.fsState = m_ToolbarButtons[i].fsState;
  905. mmcButton.fsType = m_ToolbarButtons[i].fsType;
  906. CString szButtonText;
  907. szButtonText.Format( m_ToolbarButtons[i].idButtonText );
  908. mmcButton.lpButtonText = szButtonText.GetBuffer(0);
  909. CString szTooltipText;
  910. szTooltipText.Format( m_ToolbarButtons[i].idTooltipText );
  911. mmcButton.lpTooltipText = szTooltipText.GetBuffer(0);
  912. WsbAffirmHr( pToolbar->AddButtons( 1, &mmcButton ) );
  913. }
  914. } WsbCatch( hr );
  915. } else {
  916. hr = S_FALSE;
  917. }
  918. return hr;
  919. }
  920. //------------------------------------------------------------------------------
  921. //
  922. // RefreshScopePane
  923. //
  924. // Refreshes the scope pane from this node down
  925. //
  926. //
  927. HRESULT CSakNode::RefreshScopePane( )
  928. {
  929. WsbTraceIn( L"CSakNode::RefreshScopePane", L"" );
  930. HRESULT hr = S_OK;
  931. try {
  932. //
  933. // Refresh the scope pane
  934. //
  935. WsbAffirmHr( m_pSakSnapAsk->UpdateAllViews( (ISakNode*)this ) );
  936. } WsbCatch( hr );
  937. WsbTraceOut( L"CSakNode::RefreshScopePane", L"hr = <%ls>", WsbHrAsString( hr ) );
  938. return( hr );
  939. }
  940. ULONG
  941. CSakNode::InternalAddRef(
  942. )
  943. {
  944. WsbTraceIn( L"CSakNode::InternalAddRef", L"m_Name = <%ls>", m_szName );
  945. ULONG retval = CComObjectRoot::InternalAddRef( );
  946. WsbTraceOut( L"CSakNode::InternalAddRef", L"retval = <%lu>, type = <%ls>", retval, GetClassNameFromNodeType( *m_rTypeGuid ) );
  947. return( retval );
  948. }
  949. ULONG
  950. CSakNode::InternalRelease(
  951. )
  952. {
  953. WsbTraceIn( L"CSakNode::InternalRelease", L"m_Name = <%ls>", m_szName );
  954. ULONG retval = CComObjectRoot::InternalRelease( );
  955. WsbTraceOut( L"CSakNode::InternalRelease", L"retval = <%lu>, type = <%ls>", retval, GetClassNameFromNodeType( *m_rTypeGuid ) );
  956. return( retval );
  957. }
  958. int
  959. CSakNode::AddResultImage( UINT nId )
  960. {
  961. return( CSakSnap::AddImage( nId ) );
  962. }
  963. int
  964. CSakNode::AddScopeImage( UINT nId )
  965. {
  966. return( CSakData::AddImage( nId ) );
  967. }
  968. HRESULT
  969. CSakNode::AddChild( ISakNode* pChild )
  970. {
  971. HRESULT hr = S_OK;
  972. try {
  973. WsbAffirmPointer( pChild );
  974. WsbAffirmHr( m_Children.Add( pChild ) );
  975. } WsbCatch( hr );
  976. return( hr );
  977. }
  978. BSTR CSakNode::SysAlloc64BitSortKey( LONGLONG Number )
  979. {
  980. BSTR retval = 0;
  981. CString sortKey;
  982. sortKey.Format( L"%16.16I64X", Number );
  983. retval = SysAllocString( sortKey );
  984. return( retval );
  985. }