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.

744 lines
17 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. CPropSht.cpp
  5. Abstract:
  6. Implementation of Property-Sheet-Like container object
  7. for property sheet pages.
  8. Author:
  9. Art Bragg 10/8/97
  10. Revision History:
  11. --*/
  12. /////////////////////////////////////////////////////////////////////////////
  13. //
  14. //
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "stdafx.h"
  17. // To make sure callbacks are in correct order:
  18. // PropPageCallback -> MMC Callback -> MFC Callback
  19. // This is because MMC only stores one pointer, and they want it
  20. // to be MFC's
  21. // note that pfnCallback has already been set to PropPageCallback
  22. HRESULT CSakPropertyPage::SetMMCCallBack( )
  23. {
  24. HRESULT hr = S_OK;
  25. m_psp.pfnCallback = m_pMfcCallback;
  26. hr = MMCPropPageCallback( &( m_psp ) );
  27. m_pMfcCallback = m_psp.pfnCallback;
  28. m_psp.pfnCallback = PropPageCallback;
  29. return( hr );
  30. }
  31. // To make sure callbacks are in correct order:
  32. // PropPageCallback -> MMC Callback -> MFC Callback
  33. // This is because MMC only stores one pointer, and they want it
  34. // to be MFC's
  35. // note that pfnCallback has already been set to PropPageCallback
  36. HRESULT CSakWizardPage::SetMMCCallBack( )
  37. {
  38. HRESULT hr = S_OK;
  39. m_psp.pfnCallback = m_pMfcCallback;
  40. hr = MMCPropPageCallback( &( m_psp ) );
  41. m_pMfcCallback = m_psp.pfnCallback;
  42. m_psp.pfnCallback = PropPageCallback;
  43. return( hr );
  44. }
  45. HRESULT
  46. CSakPropertySheet::InitSheet(
  47. RS_NOTIFY_HANDLE Handle,
  48. IUnknown* pUnkPropSheetCallback,
  49. CSakNode* pSakNode,
  50. ISakSnapAsk* pSakSnapAsk,
  51. IEnumGUID* pEnumObjectId,
  52. IEnumUnknown* pEnumUnkNode
  53. )
  54. {
  55. WsbTraceIn( L"CSakPropertySheet::InitSheet", L"" );
  56. HRESULT hr = S_OK;
  57. try {
  58. //
  59. // Set data members
  60. //
  61. WsbAffirmHr( RsQueryInterface( pUnkPropSheetCallback, IPropertySheetCallback, m_pPropSheetCallback ) );
  62. m_pSakNode = pSakNode;
  63. m_Handle = Handle;
  64. m_bMultiSelect = pEnumObjectId ? TRUE : FALSE ;
  65. if( pSakNode ) {
  66. WsbAffirmHr( SetNode( pSakNode ) );
  67. }
  68. //
  69. // Marshall ISakSnapAsk
  70. //
  71. WsbAffirmPointer( pSakSnapAsk );
  72. WsbAffirmHr ( CoMarshalInterThreadInterfaceInStream(
  73. IID_ISakSnapAsk, pSakSnapAsk, &m_pSakSnapAskStream ) );
  74. //
  75. // Store the GUIDs
  76. //
  77. if( pEnumObjectId ) {
  78. GUID objectId;
  79. while( pEnumObjectId->Next( 1, &objectId, NULL ) == S_OK) {
  80. m_ObjectIdList.Add( objectId );
  81. }
  82. }
  83. //
  84. // Store the nodes
  85. //
  86. if( pEnumUnkNode ) {
  87. CComPtr<IUnknown> pUnkNode;
  88. CComPtr<ISakNode> pNode;
  89. pEnumUnkNode->Reset( );
  90. while( pEnumUnkNode->Next( 1, &pUnkNode, NULL ) == S_OK ) {
  91. WsbAffirmHr( pUnkNode.QueryInterface( &pNode ) );
  92. m_UnkNodeList.Add( pNode );
  93. pUnkNode.Release( );
  94. pNode.Release( );
  95. }
  96. }
  97. } WsbCatch( hr );
  98. WsbTraceOut( L"CSakPropertySheet::InitSheet", L"hr = <%ls>", WsbHrAsString( hr ) );
  99. return( hr );
  100. }
  101. HRESULT
  102. CSakPropertySheet::SetNode(
  103. CSakNode* pSakNode
  104. )
  105. {
  106. WsbTraceIn( L"CSakPropertySheet::SetNode", L"" );
  107. HRESULT hr = S_OK;
  108. try {
  109. //
  110. // Marshall pHsmObj as an unknown
  111. //
  112. CComPtr <IUnknown> pHsmObj;
  113. pSakNode->GetHsmObj( &pHsmObj );
  114. if( pHsmObj ) {
  115. WsbAffirmHr ( CoMarshalInterThreadInterfaceInStream(
  116. IID_IUnknown, pHsmObj, &m_pHsmObjStream ) );
  117. }
  118. } WsbCatch( hr );
  119. WsbTraceOut( L"CSakPropertySheet::SetNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  120. return( hr );
  121. }
  122. CSakPropertySheet::~CSakPropertySheet()
  123. {
  124. WsbTraceIn( L"CSakPropertySheet::~CSakPropertySheet", L"" );
  125. MMCFreeNotifyHandle( m_Handle );
  126. WsbTraceOut( L"CSakPropertySheet::~CSakPropertySheet", L"" );
  127. }
  128. HRESULT CSakPropertySheet::GetNextObjectId( INT *pBookMark, GUID *pObjectId )
  129. {
  130. HRESULT hr = S_OK;
  131. try {
  132. WsbAffirm( *pBookMark >= 0, E_FAIL );
  133. if( *pBookMark <= m_ObjectIdList.GetUpperBound( ) ) {
  134. *pObjectId = m_ObjectIdList[ *pBookMark ];
  135. (*pBookMark)++;
  136. } else {
  137. //
  138. // We're done
  139. //
  140. WsbThrow ( S_FALSE );
  141. }
  142. } WsbCatch( hr );
  143. return( hr );
  144. }
  145. HRESULT CSakPropertySheet::GetNextNode( INT *pBookMark, ISakNode **ppNode )
  146. {
  147. HRESULT hr = S_OK;
  148. try {
  149. WsbAffirm( *pBookMark >= 0, E_FAIL );
  150. if( *pBookMark < m_UnkNodeList.length( ) ) {
  151. WsbAffirmHr( m_UnkNodeList.CopyTo( *pBookMark, ppNode ) );
  152. (*pBookMark)++;
  153. } else {
  154. //
  155. // We're done
  156. //
  157. hr = S_FALSE;
  158. }
  159. } WsbCatch( hr );
  160. return( hr );
  161. }
  162. void CSakPropertySheet::AddPageRef()
  163. {
  164. m_nPageCount++;
  165. }
  166. void CSakPropertySheet::ReleasePageRef()
  167. {
  168. m_nPageCount--;
  169. //
  170. // Check to see if this is last reference
  171. //
  172. if( m_nPageCount <= 0 ) {
  173. delete( this );
  174. }
  175. }
  176. HRESULT CSakPropertySheet::GetHsmObj( IUnknown **ppHsmObj )
  177. {
  178. HRESULT hr = S_OK;
  179. try {
  180. if( !m_pHsmObj ) {
  181. //
  182. // Unmarhsall the pointer
  183. //
  184. WsbAffirmHr( CoGetInterfaceAndReleaseStream( m_pHsmObjStream, IID_IUnknown,
  185. (void **) &m_pHsmObj ) );
  186. }
  187. m_pHsmObj.CopyTo( ppHsmObj );
  188. } WsbCatch( hr );
  189. return( hr );
  190. }
  191. HRESULT CSakPropertySheet::GetSakSnapAsk( ISakSnapAsk **ppAsk )
  192. {
  193. HRESULT hr = S_OK;
  194. try {
  195. if ( !m_pSakSnapAsk ) {
  196. //
  197. // Unmarhsall the pointer
  198. //
  199. WsbAffirmHr( CoGetInterfaceAndReleaseStream( m_pSakSnapAskStream, IID_ISakSnapAsk,
  200. (void **) &m_pSakSnapAsk ) );
  201. }
  202. m_pSakSnapAsk.CopyTo( ppAsk );
  203. } WsbCatch( hr );
  204. return( hr );
  205. }
  206. HRESULT CSakPropertySheet::GetHsmServer (IHsmServer **ppHsmServer)
  207. {
  208. HRESULT hr = S_OK;
  209. try {
  210. CComPtr<ISakSnapAsk> pAsk;
  211. WsbAffirmHr( GetSakSnapAsk( &pAsk ) );
  212. WsbAffirmHrOk( pAsk->GetHsmServer( ppHsmServer ) );
  213. } WsbCatch( hr );
  214. return( hr );
  215. }
  216. HRESULT CSakPropertySheet::GetFsaServer (IFsaServer **ppFsaServer)
  217. {
  218. HRESULT hr = S_OK;
  219. try {
  220. CComPtr<ISakSnapAsk> pAsk;
  221. WsbAffirmHr( GetSakSnapAsk( &pAsk ) );
  222. WsbAffirmHrOk( pAsk->GetFsaServer( ppFsaServer ) );
  223. } WsbCatch( hr );
  224. return( hr );
  225. }
  226. HRESULT CSakPropertySheet::GetRmsServer (IRmsServer **ppRmsServer)
  227. {
  228. HRESULT hr = S_OK;
  229. try {
  230. CComPtr<ISakSnapAsk> pAsk;
  231. WsbAffirmHr( GetSakSnapAsk( &pAsk ) );
  232. WsbAffirmHrOk( pAsk->GetRmsServer( ppRmsServer ) );
  233. } WsbCatch( hr );
  234. return( hr );
  235. }
  236. HRESULT CSakPropertySheet::IsMultiSelect ( )
  237. {
  238. return m_bMultiSelect ? S_OK : S_FALSE;
  239. }
  240. HRESULT CSakPropertySheet::OnPropertyChange( RS_NOTIFY_HANDLE hConsoleHandle, ISakNode* pNode )
  241. {
  242. //
  243. // Called by a property sheet to notify MMC
  244. //
  245. HRESULT hr = S_OK;
  246. RS_PRIVATE_DATA privData;
  247. //
  248. // Notify the console that properties have changed for the node(s)
  249. //
  250. try {
  251. if( !m_bMultiSelect ) {
  252. //
  253. // Single Select
  254. //
  255. if( ! pNode ) {
  256. pNode = m_pSakNode;
  257. }
  258. WsbAffirmHr( pNode->GetPrivateData( &privData ) );
  259. WsbAffirmHr( MMCPropertyChangeNotify( hConsoleHandle, (LPARAM)privData ) );
  260. } else {
  261. //
  262. // Multi Select
  263. //
  264. INT bookMark = 0;
  265. CComPtr<ISakNode> pNode;
  266. while( GetNextNode( &bookMark, &pNode ) == S_OK) {
  267. WsbAffirmHr( pNode->GetPrivateData( &privData ) );
  268. WsbAffirmHr( MMCPropertyChangeNotify( hConsoleHandle, (LPARAM)privData ) );
  269. pNode.Release( );
  270. }
  271. }
  272. } WsbCatch( hr );
  273. return( hr );
  274. }
  275. // This function is to be called from the page thread
  276. HRESULT CSakPropertySheet::GetFsaFilter( IFsaFilter **ppFsaFilter )
  277. {
  278. WsbTraceIn( L"CSakPropertySheet::GetFsaFilter", L"" );
  279. HRESULT hr = S_OK;
  280. try {
  281. CComPtr<IFsaServer> pFsa;
  282. WsbAffirmHr( GetFsaServer( &pFsa ) );
  283. //
  284. // Get the FsaFilter object
  285. //
  286. WsbAffirmHr( pFsa->GetFilter( ppFsaFilter ) );
  287. } WsbCatch( hr );
  288. WsbTraceOut( L"CSakPropertySheet::GetFsaFilter", L"hr = <%ls>, *ppFsaFilter = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppFsaFilter ) );
  289. return( hr );
  290. }
  291. HRESULT
  292. CSakPropertySheet::AddPage(
  293. IN CSakPropertyPage* pPage
  294. )
  295. {
  296. WsbTraceIn( L"CSakPropertySheet::AddPage", L"" );
  297. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  298. HRESULT hr = S_OK;
  299. try {
  300. //
  301. // Get the property sheet callback interface from the input param.
  302. //
  303. pPage->m_hConsoleHandle = m_Handle;
  304. pPage->m_pParent = this;
  305. WsbAffirmHr( pPage->SetMMCCallBack( ) );
  306. HPROPSHEETPAGE hPage;
  307. hPage = CreatePropertySheetPage( &( pPage->m_psp ) );
  308. WsbAffirmPointer( hPage );
  309. AddPageRef( );
  310. WsbAffirmHr( m_pPropSheetCallback->AddPage( hPage ) );
  311. } WsbCatch( hr );
  312. WsbTraceOut( L"CSakPropertySheet::AddPage", L"hr = <%ls>", WsbHrAsString( hr ) );
  313. return( hr );
  314. }
  315. CSakPropertyPage::CSakPropertyPage( UINT nIDTemplate, UINT nIDCaption ) :
  316. CRsPropertyPage( nIDTemplate, nIDCaption ),
  317. m_pParent( 0 )
  318. {
  319. }
  320. void
  321. CSakPropertyPage::OnPageRelease( )
  322. {
  323. if( m_pParent ) {
  324. m_pParent->ReleasePageRef( );
  325. }
  326. delete this;
  327. }
  328. ////////////////////////////////////////////////////////////////////////////////////////
  329. //
  330. // class CSakVolPropSheet
  331. //
  332. // Supports property sheets for Managed volume and Managed Volume List
  333. //
  334. //
  335. HRESULT CSakVolPropSheet::GetFsaResource (IFsaResource **ppFsaResource)
  336. {
  337. WsbTraceIn( L"CSakVolPropSheet::GetFsaResource", L"" );
  338. HRESULT hr = S_OK;
  339. try {
  340. //
  341. // Get the hsm object which is a CHsmManagedResource
  342. //
  343. CComPtr<IUnknown> pUnk;
  344. WsbAffirmHr( GetHsmObj( &pUnk ) );
  345. CComPtr<IHsmManagedResource> pManRes;
  346. WsbAffirmHr( pUnk.QueryInterface( &pManRes ) );
  347. //
  348. // Then Get Coresponding FSA resource
  349. //
  350. CComPtr<IUnknown> pUnkFsaRes;
  351. WsbAffirmHr( pManRes->GetFsaResource( &pUnkFsaRes ) );
  352. WsbAffirmHr( pUnkFsaRes.QueryInterface( ppFsaResource ) );
  353. } WsbCatch( hr );
  354. WsbTraceOut( L"CSakVolPropSheet::GetFsaResource", L"hr = <%ls>", WsbHrAsString( hr ) );
  355. return( hr );
  356. }
  357. HRESULT
  358. CSakVolPropSheet::AddPage(
  359. IN CSakVolPropPage* pPage
  360. )
  361. {
  362. WsbTraceIn( L"CSakVolPropSheet::AddPage", L"" );
  363. HRESULT hr = CSakPropertySheet::AddPage( pPage );
  364. if( SUCCEEDED( hr ) ) {
  365. pPage->m_pVolParent = this;
  366. }
  367. WsbTraceOut( L"CSakVolPropSheet::AddPage", L"hr = <%ls>", WsbHrAsString( hr ) );
  368. return( hr );
  369. }
  370. CSakVolPropPage::CSakVolPropPage( UINT nIDTemplate, UINT nIDCaption ) :
  371. CSakPropertyPage( nIDTemplate, nIDCaption ),
  372. m_pVolParent( 0 )
  373. {
  374. }
  375. ////////////////////////////////////////////////////////////////////////////////////////
  376. //
  377. // class CSakWizardSheet
  378. //
  379. // Supports wizards created through MMC
  380. //
  381. //
  382. CSakWizardSheet::CSakWizardSheet( ) :
  383. m_HrFinish( RS_E_CANCELLED ),
  384. m_pFirstPage( 0 )
  385. {
  386. }
  387. STDMETHODIMP
  388. CSakWizardSheet::GetWatermarks(
  389. OUT HBITMAP* pWatermark,
  390. OUT HBITMAP* pHeader,
  391. OUT HPALETTE* pPalette,
  392. OUT BOOL* pStretch
  393. )
  394. {
  395. WsbTraceIn( L"CSakWizardSheet::GetWatermarks", L"" );
  396. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  397. HRESULT hr = S_OK;
  398. try {
  399. //
  400. // Have we loaded them yet?
  401. //
  402. if( ! m_Header.GetSafeHandle( ) ) {
  403. m_Header.LoadBitmap( m_HeaderId );
  404. m_Watermark.LoadBitmap( m_WatermarkId );
  405. }
  406. *pHeader = (HBITMAP)m_Header.GetSafeHandle( );
  407. *pWatermark = (HBITMAP)m_Watermark.GetSafeHandle( );
  408. *pStretch = TRUE;
  409. *pPalette = 0;
  410. } WsbCatch( hr );
  411. WsbTraceOut( L"CSakWizardSheet::GetWatermarks", L"hr = <%ls>", WsbHrAsString( hr ) );
  412. return( hr );
  413. }
  414. STDMETHODIMP
  415. CSakWizardSheet::GetTitle(
  416. OUT OLECHAR** pTitle
  417. )
  418. {
  419. WsbTraceIn( L"CSakWizardSheet::GetTitle", L"" );
  420. HRESULT hr = S_OK;
  421. try {
  422. //
  423. // Have we loaded yet?
  424. //
  425. if( m_Title.IsEmpty( ) ) {
  426. m_Title.LoadString( m_TitleId );
  427. }
  428. //
  429. // Easiest way to CoTaskMemAlloc string
  430. //
  431. CWsbStringPtr title = m_Title;
  432. WsbAffirmHr( title.GiveTo( pTitle ) );
  433. } WsbCatch( hr );
  434. WsbTraceOut( L"CSakWizardSheet::GetTitle", L"hr = <%ls>", WsbHrAsString( hr ) );
  435. return( hr );
  436. }
  437. void CSakWizardSheet::AddPageRef()
  438. {
  439. ((ISakWizard*)this)->AddRef( );
  440. }
  441. void CSakWizardSheet::ReleasePageRef()
  442. {
  443. ((ISakWizard*)this)->Release( );
  444. }
  445. HRESULT
  446. CSakWizardSheet::AddPage(
  447. IN CSakWizardPage* pPage
  448. )
  449. {
  450. WsbTraceIn( L"CSakWizardSheet::AddPage", L"" );
  451. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  452. HRESULT hr = S_OK;
  453. try {
  454. //
  455. // Need to track first page so that we can find true HWND of sheet
  456. // in later calls
  457. //
  458. if( ! m_pFirstPage ) {
  459. m_pFirstPage = pPage;
  460. }
  461. //
  462. // Take the caption from our sheet class and put it in the page
  463. //
  464. pPage->SetCaption( CString( m_Title ) );
  465. //
  466. // Get the property sheet callback interface from the input param.
  467. //
  468. pPage->m_pSheet = this;
  469. WsbAffirmHr( pPage->SetMMCCallBack( ) );
  470. HPROPSHEETPAGE hPage;
  471. hPage = pPage->CreatePropertyPage( );
  472. WsbAffirmPointer( hPage );
  473. AddPageRef( );
  474. WsbAffirmHr( m_pPropSheetCallback->AddPage( hPage ) );
  475. } WsbCatch( hr );
  476. WsbTraceOut( L"CSakWizardSheet::AddPage", L"hr = <%ls>", WsbHrAsString( hr ) );
  477. return( hr );
  478. }
  479. void CSakWizardSheet::SetWizardButtons(
  480. DWORD Flags
  481. )
  482. {
  483. WsbTraceIn( L"CSakWizardSheet::SetWizardButtons", L"" );
  484. HRESULT hr = S_OK;
  485. try {
  486. WsbAffirmPointer( m_pFirstPage );
  487. WsbAffirmHandle( m_pFirstPage->GetSafeHwnd( ) );
  488. CPropertySheet* pSheet;
  489. pSheet = (CPropertySheet*)m_pFirstPage->GetParent( );
  490. WsbAffirmPointer( pSheet );
  491. pSheet->SetWizardButtons( Flags );
  492. } WsbCatch( hr );
  493. WsbTraceOut( L"CSakWizardSheet::SetWizardButtons", L"hr = <%ls>", WsbHrAsString( hr ) );
  494. }
  495. BOOL CSakWizardSheet::PressButton(
  496. int Button
  497. )
  498. {
  499. WsbTraceIn( L"CSakWizardSheet::PressButton", L"" );
  500. HRESULT hr = S_OK;
  501. BOOL retVal = FALSE;
  502. try {
  503. WsbAffirmPointer( m_pFirstPage );
  504. WsbAffirmHandle( m_pFirstPage->GetSafeHwnd( ) );
  505. CPropertySheet* pSheet;
  506. pSheet = (CPropertySheet*)m_pFirstPage->GetParent( );
  507. WsbAffirmPointer( pSheet );
  508. retVal = pSheet->PressButton( Button );
  509. } WsbCatch( hr );
  510. WsbTraceOut( L"CSakWizardSheet::PressButton", L"hr = <%ls>", WsbHrAsString( hr ) );
  511. return( retVal );
  512. }
  513. CSakWizardPage::CSakWizardPage( UINT nIDTemplate, BOOL bExterior, UINT nIdTitle, UINT nIdSubtitle ) :
  514. CRsWizardPage( nIDTemplate, bExterior, nIdTitle, nIdSubtitle ),
  515. m_pSheet( 0 )
  516. {
  517. }
  518. BOOL CSakWizardPage::OnWizardFinish( )
  519. {
  520. WsbTraceIn( L"CSakWizardPage::OnWizardFinish", L"" );
  521. //
  522. // Delegate the finish work to the sheet
  523. //
  524. m_pSheet->OnFinish( );
  525. BOOL retval = CRsWizardPage::OnWizardFinish( );
  526. WsbTraceOut( L"CSakWizardPage::OnWizardFinish", L"" );
  527. return( retval );
  528. }
  529. void CSakWizardPage::OnCancel( )
  530. {
  531. WsbTraceIn( L"CSakWizardPage::OnCancel", L"" );
  532. //
  533. // Since the Sheet does not receive an "OnCancel", we call it from the
  534. // page that will always exist - the intro
  535. //
  536. m_pSheet->OnCancel( );
  537. CRsWizardPage::OnCancel( );
  538. WsbTraceOut( L"CSakWizardPage::OnCancel", L"" );
  539. }
  540. void
  541. CSakWizardPage::OnPageRelease( )
  542. {
  543. if( m_pSheet ) {
  544. m_pSheet->ReleasePageRef( );
  545. }
  546. }