///////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1996-2000 Microsoft Corporation // // Module Name: // AtlExtDll.cpp // // Abstract: // Implementation of the Cluster Administrator extension classes. // // Author: // David Potter (davidp) May 31, 1996 // // Revision History: // // Notes: // This file is intended to be included in a stub file which includes // the ATL header files and defines _Module. This allos _Module to be // defined as an instance of some application-specific class. // ///////////////////////////////////////////////////////////////////////////// #include #include #include "CluAdmExHostSvr.h" #include "AtlExtDll.h" #include "AdmCommonRes.h" #include "AtlExtMenu.h" //#include "TraceTag.h" #include "ExcOper.h" #include "ClusObj.h" #include "AtlBaseSheet.h" #include "AtlBasePropSheet.h" #include "AtlBaseWiz.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Global Variables ///////////////////////////////////////////////////////////////////////////// #if DBG //CTraceTag g_tagExtDll(_T("UI"), _T("EXTENSION DLL"), 0); //CTraceTag g_tagExtDllRef(_T("UI"), _T("EXTENSION DLL References"), 0); #endif // DBG ///////////////////////////////////////////////////////////////////////////// // class CCluAdmExtensions ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::Init // // Routine Description: // Common initializer for all interfaces. // // Arguments: // rlstrExtensions [IN] List of extension CLSID strings. // pco [IN OUT] Cluster object to be administered. // hfont [IN] Font for dialog text. // hicon [IN] Icon for upper left corner. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by new. // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExtensions::Init( IN const CStringList & rlstrExtensions, IN OUT CClusterObject * pco, IN HFONT hfont, IN HICON hicon ) { ATLASSERT( rlstrExtensions.size() > 0 ); ATLASSERT( pco != NULL ); CWaitCursor wc; UnloadExtensions(); // // Save parameters. // m_plstrExtensions = &rlstrExtensions; m_pco = pco; m_hfont = hfont; m_hicon = hicon; // // Allocate a new Data Object. // m_pdoData = new CComObject< CCluAdmExDataObject >; if ( m_pdoData == NULL ) { goto MemoryError; } // if: error allocating memory m_pdoData->AddRef(); // Construct the Data Object. Pdo()->Init( pco, GetUserDefaultLCID(), hfont, hicon ); // Allocate the extension list. m_plextdll = new CCluAdmExDllList; if ( m_plextdll == NULL ) { goto MemoryError; } // if: error allocating memory ATLASSERT( Plextdll() != NULL ); // // Loop through the extensions and load each one. // { CComCluAdmExDll * pextdll = NULL; CStringList::iterator itCurrent = rlstrExtensions.begin(); CStringList::iterator itLast = rlstrExtensions.end(); CCluAdmExDllList::iterator itDll; for ( ; itCurrent != itLast ; itCurrent++ ) { // // Allocate an extension DLL object and add it to the list. // pextdll = new CComCluAdmExDll; if ( pextdll == NULL ) { goto MemoryError; } // if: error allocating memory pextdll->AddRef(); itDll = Plextdll()->insert( Plextdll()->end(), pextdll ); try { pextdll->Init( *itCurrent, this ); } // try catch ( CException * pe ) { pe->ReportError(); pe->Delete(); ATLASSERT( itDll != Plextdll()->end() ); Plextdll()->erase( itDll ); delete pextdll; } // catch: CException } // while: more items in the list } // Loop through the extensions and load each one Cleanup: return; MemoryError: CNTException nte( E_OUTOFMEMORY, ADMC_IDS_INIT_EXT_PAGES_ERROR, NULL, // pszOperArg1 NULL, // pszOperArg2 FALSE // bAutoDelete ); nte.ReportError(); goto Cleanup; } //*** CCluAdmExtensions::Init() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::UnloadExtensions // // Routine Description: // Unload the extension DLL. // // Arguments: // None. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExtensions::UnloadExtensions( void ) { // // Delete all the extension DLL objects. // if ( Plextdll() != NULL ) { CCluAdmExDllList::iterator itCurrent = Plextdll()->begin(); CCluAdmExDllList::iterator itLast = Plextdll()->end(); CComCluAdmExDll * pextdll; for ( ; itCurrent != itLast ; itCurrent++ ) { pextdll = *itCurrent; pextdll->AddRef(); // See comment below. pextdll->UnloadExtension(); if ( pextdll->m_dwRef != 2 ) { Trace( g_tagError, _T("CCluAdmExtensions::UnloadExtensions() - Extension DLL has ref count = %d"), pextdll->m_dwRef ); } // if: not last reference // We added a reference above. Combined with the reference that // was added when the object was created, we typically will need // to release two references. However, due to bogus code // generated by earlier versions of the custom AppWizard where the // extension was releasing the interface but not zeroing out its // pointer in the error case, we may not need to release the // second reference. if ( pextdll->Release() != 0 ) { pextdll->Release(); } // if: more references to release } // while: more items in the list delete m_plextdll; m_plextdll = NULL; } // if: there is a list of extensions if ( m_pdoData != NULL ) { if ( m_pdoData->m_dwRef != 1 ) { Trace( g_tagError, _T("CCluAdmExtensions::UnloadExtensions() - Data Object has ref count = %d"), m_pdoData->m_dwRef ); } // if: not last reference m_pdoData->Release(); m_pdoData = NULL; } // if: data object allocated m_pco = NULL; m_hfont = NULL; m_hicon = NULL; // // Delete all menu items. // if ( PlMenuItems() != NULL ) { CCluAdmExMenuItemList::iterator itCurrent = PlMenuItems()->begin(); CCluAdmExMenuItemList::iterator itLast = PlMenuItems()->end(); CCluAdmExMenuItem * pemi; for ( ; itCurrent != itLast ; itCurrent++ ) { pemi = *itCurrent; delete pemi; } // while: more items in the list delete m_plMenuItems; m_plMenuItems = NULL; } // if: there is a list of menu items } //*** CCluAdmExtensions::UnloadExtensions() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::PwpPageFromHpage // // Routine Description: // Get the wizard page pointer from an HPROPSHEETPAGE. // // Arguments: // hpage [IN] Page handle. // // Return Value: // pwp Pointer to wizard page object. // NULL Page not found. // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// CWizardPageWindow * CCluAdmExtensions::PwpPageFromHpage( IN HPROPSHEETPAGE hpage ) { ATLASSERT( hpage != NULL ); // // Get a pointer to the wizard object so we can traverse the page list. // CWizardWindow * pwiz = dynamic_cast< CWizardWindow * >( Psht() ); ATLASSERT( pwiz != NULL ); // // Loop through each page looking for an extension page whose // page handle matches the one specified. // CWizardPageList::iterator itCurrent = pwiz->PlwpPages()->begin(); CWizardPageList::iterator itLast = pwiz->PlwpPages()->end(); for ( ; itCurrent != itLast ; itCurrent++ ) { CCluAdmExWizPage * pewp = dynamic_cast< CCluAdmExWizPage * >( *itCurrent ); if ( pewp != NULL ) { if ( pewp->Hpage() == hpage ) { return pewp; } // if: found the matching page } // if: found an extension page } // for: each page in the list // // Look at the alternate wizard if there is one. // pwiz = pwiz->PwizAlternate(); if ( pwiz != NULL ) { itCurrent = pwiz->PlwpPages()->begin(); itLast = pwiz->PlwpPages()->end(); for ( ; itCurrent != itLast ; itCurrent++ ) { CCluAdmExWizPage * pewp = dynamic_cast< CCluAdmExWizPage * >( *itCurrent ); if ( pewp != NULL ) { if ( pewp->Hpage() == hpage ) { return pewp; } // if: found the matching page } // if: found an extension page } // for: each page in the list } // if: alternate wizard exists return NULL; } //*** CCluAdmExtensions::PwpPageFromHpage() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::CreatePropertySheetPages // // Routine Description: // Add pages to a property sheet. // // Arguments: // psht [IN OUT] Property sheet to which pages are to be added. // rlstrExtensions [IN] List of extension CLSID strings. // pco [IN OUT] Cluster object to be administered. // hfont [IN] Font for dialog text. // hicon [IN] Icon for upper left corner. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by CCluAdmExDll::AddPages(). // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExtensions::CreatePropertySheetPages( IN OUT CBasePropertySheetWindow * psht, IN const CStringList & rlstrExtensions, IN OUT CClusterObject * pco, IN HFONT hfont, IN HICON hicon ) { ATLASSERT( psht != NULL ); ATLASSERT( pco != NULL ); m_psht = psht; // // Initialize for all extensions. // Init( rlstrExtensions, pco, hfont, hicon ); ATLASSERT( Plextdll() != NULL ); // // Let each extension create property pages. // CCluAdmExDllList::iterator itCurrent = Plextdll()->begin(); CCluAdmExDllList::iterator itLast = Plextdll()->end(); CComCluAdmExDll * pextdll; for ( ; itCurrent != itLast ; itCurrent++ ) { pextdll = *itCurrent; try { pextdll->CreatePropertySheetPages(); } // try catch ( CException * pe ) { pe->ReportError(); pe->Delete(); } // catch: CException } // while: more items in the list } //*** CCluAdmExtensions::CreatePropertySheetPages() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::CreateWizardPages // // Routine Description: // Add pages to a wizard. // // Arguments: // psht [IN OUT] Property sheet to which pages are to be added. // rlstrExtensions [IN] List of extension CLSID strings. // pco [IN OUT] Cluster object to be administered. // hfont [IN] Font for dialog text. // hicon [IN] Icon for upper left corner. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by CCluAdmExDll::AddPages(). // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExtensions::CreateWizardPages( IN OUT CWizardWindow * psht, IN const CStringList & rlstrExtensions, IN OUT CClusterObject * pco, IN HFONT hfont, IN HICON hicon ) { ATLASSERT( psht != NULL ); ATLASSERT( pco != NULL ); m_psht = psht; // // Initialize for all extensions. // Init( rlstrExtensions, pco, hfont, hicon ); ATLASSERT( Plextdll() != NULL ); // // Let each extension create wizard pages. // CCluAdmExDllList::iterator itCurrent = Plextdll()->begin(); CCluAdmExDllList::iterator itLast = Plextdll()->end(); CComCluAdmExDll * pextdll; for ( ; itCurrent != itLast ; itCurrent++ ) { pextdll = *itCurrent; try { pextdll->CreateWizardPages(); } // try catch ( CException * pe ) { pe->ReportError(); pe->Delete(); } // catch: CException } // while: more items in the list } //*** CCluAdmExtensions::CreateWizardPages() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::CreateWizard97Pages // // Routine Description: // Add pages to a Wizard 97 wizard. // // Arguments: // psht [IN OUT] Property sheet to which pages are to be added. // rlstrExtensions [IN] List of extension CLSID strings. // pco [IN OUT] Cluster object to be administered. // hfont [IN] Font for dialog text. // hicon [IN] Icon for upper left corner. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by CCluAdmExDll::AddPages(). // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExtensions::CreateWizard97Pages( IN OUT CWizardWindow * psht, IN const CStringList & rlstrExtensions, IN OUT CClusterObject * pco, IN HFONT hfont, IN HICON hicon ) { ATLASSERT( psht != NULL ); ATLASSERT( pco != NULL ); m_psht = psht; // // Initialize for all extensions. // Init( rlstrExtensions, pco, hfont, hicon ); ATLASSERT( Plextdll() != NULL ); // // Let each extension create wizard pages. // CCluAdmExDllList::iterator itCurrent = Plextdll()->begin(); CCluAdmExDllList::iterator itLast = Plextdll()->end(); CComCluAdmExDll * pextdll; for ( ; itCurrent != itLast ; itCurrent++ ) { pextdll = *itCurrent; try { pextdll->CreateWizard97Pages(); } // try catch ( CException * pe ) { pe->ReportError(); pe->Delete(); } // catch: CException } // while: more items in the list } //*** CCluAdmExtensions::CreateWizard97Pages() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::AddContextMenuItems // // Routine Description: // Query the extension DLL for new menu items to be added to the context // menu. // // Arguments: // pmenu [IN OUT] Menu to which items are to be added. // rlstrExtensions [IN] List of extension CLSID strings. // pco [IN OUT] Cluster object to be administered. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by CCluAdmExDll::AddContextMenuItems() or // CExtMenuItemList::new(). // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExtensions::AddContextMenuItems( IN OUT CMenu * pmenu, IN const CStringList & rlstrExtensions, IN OUT CClusterObject * pco ) { ATLASSERT( m_pmenu == NULL ); ATLASSERT( pmenu != NULL ); // // Initialize for all extensions. // Init( rlstrExtensions, pco, NULL, NULL ); ATLASSERT( Plextdll() != NULL ); m_pmenu = pmenu; m_nFirstCommandID = CAEXT_MENU_FIRST_ID; m_nNextCommandID = m_nFirstCommandID; m_nFirstMenuID = 0; m_nNextMenuID = m_nFirstMenuID; // // Create the list of menu items. // ATLASSERT( m_plMenuItems == NULL ); m_plMenuItems = new CCluAdmExMenuItemList; if ( m_plMenuItems == NULL ) { CNTException nte( E_OUTOFMEMORY, ADMC_IDS_INIT_EXT_PAGES_ERROR, NULL, // pszOperArg1 NULL, // pszOperArg2 FALSE // bAutoDelete ); nte.ReportError(); } // if: error allocating memory else { CCluAdmExDllList::iterator itCurrent = Plextdll()->begin(); CCluAdmExDllList::iterator itLast = Plextdll()->end(); CComCluAdmExDll * pextdll; for ( ; itCurrent != itLast ; itCurrent++ ) { pextdll = *itCurrent; try { pextdll->AddContextMenuItems(); } // try catch ( CException * pe ) { pe->ReportError(); pe->Delete(); } // catch: CException } // while: more items in the list } // else: memory allocated successfully } //*** CCluAdmExtensions::AddContextMenuItems() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::BExecuteContextMenuItem // // Routine Description: // Execute a command associated with a menu item added to a context menu // by the extension DLL. // // Arguments: // nCommandID [IN] Command ID for the menu item chosen by the user. // // Return Value: // TRUE Context menu item was executed. // FALSE Context menu item was not executed. // // Exceptions Thrown: // Any exceptions thrown by CExceptionDll::BExecuteContextMenuItem(). // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CCluAdmExtensions::BExecuteContextMenuItem( IN ULONG nCommandID ) { BOOL bHandled = FALSE; HRESULT hr; CCluAdmExMenuItem * pemi; // // Find the item in our list. // pemi = PemiFromCommandID( nCommandID ); if ( pemi != NULL ) { ATLASSERT( pemi->PiCommand() != NULL ); Pdo()->AddRef(); hr = pemi->PiCommand()->InvokeCommand( pemi->NExtCommandID(), Pdo()->GetUnknown() ); if ( hr == NOERROR ) { bHandled = TRUE; } // if: no error occurred } // if: found an item for the command ID return bHandled; } //*** CCluAdmExtensions::BExecuteContextMenuItem() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::BGetCommandString // // Routine Description: // Get a command string from a menu ID. // // Arguments: // nCommandID [IN] Command ID for the menu item. // rstrMessage [OUT] String in which to return the message. // // Return Value: // TRUE String is being returned. // FALSE No string is being returned. // // Exceptions Thrown: // Any exceptions thrown by CCluAdmExDll::BGetCommandString(). // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CCluAdmExtensions::BGetCommandString( IN ULONG nCommandID, OUT CString & rstrMessage ) { BOOL bHandled = FALSE; CCluAdmExMenuItem * pemi; // // Find the item in our list. // pemi = PemiFromCommandID( nCommandID ); if ( pemi != NULL ) { rstrMessage = pemi->StrStatusBarText(); bHandled = TRUE; } // if: found an item for the command ID return bHandled; } //*** CCluAdmExtensions::BGetCommandString() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::OnUpdateCommand // // Routine Description: // Determines whether extension DLL menu items should be enabled or not. // // Arguments: // pCmdUI [IN OUT] Command routing object. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by CCluAdmExDll::BOnUpdateCommand(). // //-- ///////////////////////////////////////////////////////////////////////////// #if 0 void CCluAdmExtensions::OnUpdateCommand( CCmdUI * pCmdUI ) { CCluAdmExMenuItem * pemi; ATLASSERT( Plextdll() != NULL ); // // Find the item in our list. // // Trace( g_tagExtDll, _T("OnUpdateCommand() - ID = %d"), pCmdUI->m_nID ); pemi = PemiFromCommandID( pCmdUI->m_nID ); if ( pemi != NULL ) { // Trace( g_tagExtDll, _T("OnUpdateCommand() - Found a match with '%s' ExtID = %d"), pemi->StrName(), pemi->NExtCommandID() ); pCmdUI->Enable(); } // if: found an item for the command ID } //*** CCluAdmExtensions::OnUpdateCommand() #endif ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::OnCmdMsg // // Routine Description: // Processes command messages. Attempts to pass them on to a selected // item first. // // Arguments: // nID [IN] Command ID. // nCode [IN] Notification code. // pExtra [IN OUT] Used according to the value of nCode. // pHandlerInfo [OUT] ??? // // Return Value: // TRUE Message has been handled. // FALSE Message has NOT been handled. // //-- ///////////////////////////////////////////////////////////////////////////// #if 0 BOOL CCluAdmExtensions::OnCmdMsg( UINT nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo ) { return BExecuteContextMenuItem( nID ); } //*** CCluAdmExtensions::OnCmdMsg() #endif ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::PemiFromCommandID // // Routine Description: // Find the menu item for the specified command ID. // // Arguments: // nCommandID [IN] Command ID for the menu item. // // Return Value: // pemi Menu item or NULL if not found. // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// CCluAdmExMenuItem * CCluAdmExtensions::PemiFromCommandID( IN ULONG nCommandID ) const { CCluAdmExMenuItem * pemiReturn = NULL; if ( PlMenuItems() != NULL ) { CCluAdmExMenuItemList::iterator itCurrent = PlMenuItems()->begin(); CCluAdmExMenuItemList::iterator itLast = PlMenuItems()->end(); CCluAdmExMenuItem * pemi; for ( ; itCurrent != itLast ; itCurrent++ ) { pemi = *itCurrent; if ( pemi->NCommandID() == nCommandID ) { pemiReturn = pemi; break; } // if: match was found } // while: more items in the list } // if: item list exists return pemiReturn; } //*** CCluAdmExtensions::PemiFromCommandID() #if DBG ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExtensions::PemiFromExtCommandID // // Routine Description: // Find the menu item for the specified extension command ID. // // Arguments: // nExtCommandID [IN] Extension command ID for the menu item. // // Return Value: // pemi Menu item or NULL if not found. // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// CCluAdmExMenuItem * CCluAdmExtensions::PemiFromExtCommandID( IN ULONG nExtCommandID ) const { CCluAdmExMenuItem * pemiReturn = NULL; if ( PlMenuItems() != NULL ) { CCluAdmExMenuItemList::iterator itCurrent = PlMenuItems()->begin(); CCluAdmExMenuItemList::iterator itLast = PlMenuItems()->end(); CCluAdmExMenuItem * pemi; for ( ; itCurrent != itLast ; itCurrent++ ) { pemi = *itCurrent; if ( pemi->NExtCommandID() == nExtCommandID ) { pemiReturn = pemi; break; } // if: match was found } // while: more items in the list } // if: item list exists return pemiReturn; } //*** CCluAdmExtensions::PemiFromExtCommandID() #endif // DBG //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CComObject< CCluAdmExDll > ///////////////////////////////////////////////////////////////////////////// BEGIN_OBJECT_MAP( AtlExtDll_ObjectMap ) OBJECT_ENTRY( CLSID_CoCluAdmExHostSvr, CComCluAdmExDll ) END_OBJECT_MAP() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::Init // // Routine Description: // Initialize this class in preparation for accessing the extension. // // Arguments: // rstrCLSID [IN] CLSID of the extension in string form. // // Return Value: // None. // // Exceptions Thrown: // CNTException 0 (error converting CLSID from string) // Any exceptions thrown by CString::operater=(). // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExDll::Init( IN const CString & rstrCLSID, IN OUT CCluAdmExtensions * pext ) { ATLASSERT( pext != NULL ); HRESULT hr; CWaitCursor wc; // // Save parameters. // ATLASSERT( StrCLSID().IsEmpty() || (StrCLSID() == rstrCLSID) ); m_strCLSID = rstrCLSID; m_pext = pext; // // Convert the CLSID string to a CLSID. // hr = ::CLSIDFromString( (LPWSTR) (LPCTSTR) rstrCLSID, &m_clsid ); if ( hr != S_OK ) { ThrowStaticException( hr, ADMC_IDS_CLSIDFROMSTRING_ERROR, rstrCLSID ); } // if: error converting CLSID } //*** CCluAdmExDll::Init() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::LoadInterface // // Routine Description: // Load an extension DLL. // // Arguments: // riid [IN] Interface ID. // // Return Value: // piUnk IUnknown interface pointer for interface. // // Exceptions Thrown: // CNTException ADMC_IDS_EXT_CREATE_INSTANCE_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// IUnknown * CCluAdmExDll::LoadInterface( IN const REFIID riid ) { HRESULT hr; IUnknown * piUnk; CWaitCursor wc; // // Load the inproc server and get the specified interface pointer. // // Trace( g_tagExtDllRef, _T("LoadInterface() - Getting interface pointer") ); hr = ::CoCreateInstance( Rclsid(), NULL, CLSCTX_INPROC_SERVER, riid, (LPVOID *) &piUnk ); if ( (hr != S_OK) && (hr != REGDB_E_CLASSNOTREG) && (hr != E_NOINTERFACE) ) { ThrowStaticException( hr, ADMC_IDS_EXT_CREATE_INSTANCE_ERROR, StrCLSID() ); } // if: error creating the object instance return piUnk; } //*** CCluAdmExDll::LoadInterface() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::UnloadExtension // // Routine Description: // Unload the extension DLL. // // Arguments: // None. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExDll::UnloadExtension( void ) { // // Release the interface pointers in the opposite order in which they // // were obtained. ReleaseInterface( &m_piExtendPropSheet ); ReleaseInterface( &m_piExtendWizard ); ReleaseInterface( &m_piExtendWizard97 ); ReleaseInterface( &m_piExtendContextMenu ); ReleaseInterface( &m_piInvokeCommand ); m_strCLSID.Empty(); } //*** CCluAdmExDll::UnloadExtension() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::CreatePropertySheetPages // // Routine Description: // Add pages to a property sheet. // // Arguments: // None. // // Return Value: // None. // // Exceptions Thrown: // CNTException ADMC_IDS_EXT_ADD_PAGES_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExDll::CreatePropertySheetPages( void ) { ATLASSERT( Pext() != NULL ); ATLASSERT( Psht() != NULL ); ATLASSERT( m_piExtendPropSheet == NULL ); HRESULT hr; // // Load the interface. // m_piExtendPropSheet = reinterpret_cast< interface IWEExtendPropertySheet * >( LoadInterface( IID_IWEExtendPropertySheet ) ); if ( m_piExtendPropSheet == NULL ) { return; } // if: error loading the interface ATLASSERT( m_piExtendPropSheet != NULL ); // // Add pages from the extension. // GetUnknown()->AddRef(); // Add a reference because extension is going to release. Pdo()->AddRef(); try { hr = PiExtendPropSheet()->CreatePropertySheetPages( Pdo()->GetUnknown(), this ); } // try catch ( ... ) { hr = E_FAIL; } // catch if ( (hr != NOERROR) && (hr != E_NOTIMPL) ) { ThrowStaticException( hr, ADMC_IDS_EXT_ADD_PAGES_ERROR, StrCLSID() ); } // if: error creating property sheet pages } //*** CCluAdmExDll::CreatePropertySheetPages() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::CreateWizardPages // // Routine Description: // Add pages to a wizard. // // Arguments: // None. // // Return Value: // None. // // Exceptions Thrown: // CNTException ADMC_IDS_EXT_ADD_PAGES_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExDll::CreateWizardPages( void ) { ATLASSERT( Pext() != NULL ); ATLASSERT( Psht() != NULL ); ATLASSERT( m_piExtendWizard == NULL ); ATLASSERT( m_piExtendWizard97 == NULL ); HRESULT hr; // // Load the interface. If it can't be loaded, try to load the // Wizard97 interface so that Wizard97 pages can be added. // m_piExtendWizard = reinterpret_cast< interface IWEExtendWizard * >( LoadInterface( IID_IWEExtendWizard ) ); if ( m_piExtendWizard == NULL ) { // // Try to load the Wizard97 interface. // m_piExtendWizard97 = reinterpret_cast< interface IWEExtendWizard97 * >( LoadInterface( IID_IWEExtendWizard97 ) ); if ( m_piExtendWizard97 == NULL ) { return; } // if: error loading the non-Wizard97 interface } // if: error loading the interface ATLASSERT( (m_piExtendWizard != NULL) || (m_piExtendWizard97 != NULL) ); // // Add pages from the extension. // GetUnknown()->AddRef(); // Add a reference because extension is going to release. Pdo()->AddRef(); try { if ( PiExtendWizard() != NULL ) { hr = PiExtendWizard()->CreateWizardPages( Pdo()->GetUnknown(), this ); } // if: extension supports non-Wizard97 interface else { ATLASSERT( PiExtendWizard97() != NULL ); hr = PiExtendWizard97()->CreateWizard97Pages( Pdo()->GetUnknown(), this ); } // else: extension doesn't support non-Wizard97 interface } // try catch ( ... ) { hr = E_FAIL; } // catch if ( (hr != NOERROR) && (hr != E_NOTIMPL) ) { ThrowStaticException( hr, ADMC_IDS_EXT_ADD_PAGES_ERROR, StrCLSID() ); } // if: error creating wizard pages } //*** CCluAdmExDll::CreateWizardPages() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::CreateWizard97Pages // // Routine Description: // Add pages to a Wizard 97 wizard. // // Arguments: // None. // // Return Value: // None. // // Exceptions Thrown: // CNTException ADMC_IDS_EXT_ADD_PAGES_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExDll::CreateWizard97Pages( void ) { ATLASSERT( Pext() != NULL ); ATLASSERT( Psht() != NULL ); ATLASSERT( m_piExtendWizard == NULL ); ATLASSERT( m_piExtendWizard97 == NULL ); HRESULT hr; // // Load the interface. If it can't be loaded, try to load the non- // Wizard97 interface so that non-Wizard97 pages can be added. // m_piExtendWizard97 = reinterpret_cast< interface IWEExtendWizard97 * >( LoadInterface( IID_IWEExtendWizard97 ) ); if ( m_piExtendWizard97 == NULL ) { // // Try to load the non-Wizard97 interface. // m_piExtendWizard = reinterpret_cast< interface IWEExtendWizard * >( LoadInterface( IID_IWEExtendWizard ) ); if ( m_piExtendWizard == NULL ) { return; } // if: error loading the non-Wizard97 interface } // if: error loading the Wizard97 interface ATLASSERT( (m_piExtendWizard97 != NULL) || (m_piExtendWizard != NULL) ); // // Add pages from the extension. // GetUnknown()->AddRef(); // Add a reference because extension is going to release. Pdo()->AddRef(); try { if ( PiExtendWizard97() != NULL ) { hr = PiExtendWizard97()->CreateWizard97Pages( Pdo()->GetUnknown(), this ); } // if: extension supports Wizard97 interface else { ATLASSERT( PiExtendWizard() != NULL ); hr = PiExtendWizard()->CreateWizardPages( Pdo()->GetUnknown(), this ); } // else: extension doesn't support Wizard97 interface } // try catch ( ... ) { hr = E_FAIL; } // catch if ( (hr != NOERROR) && (hr != E_NOTIMPL) ) { ThrowStaticException( hr, ADMC_IDS_EXT_ADD_PAGES_ERROR, StrCLSID() ); } // if: error creating wizard pages } //*** CCluAdmExDll::CreateWizard97Pages() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::AddContextMenuItems // // Routine Description: // Ask the extension DLL to add items to the menu. // // Arguments: // None. // // Return Value: // None. // // Exceptions Thrown: // CNTException ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// void CCluAdmExDll::AddContextMenuItems( void ) { ATLASSERT( Pext() != NULL ); ATLASSERT( Pmenu() != NULL ); ATLASSERT( m_piExtendContextMenu == NULL ); HRESULT hr; // // Load the interfaces. // m_piExtendContextMenu = reinterpret_cast< interface IWEExtendContextMenu * >( LoadInterface( IID_IWEExtendContextMenu ) ); if ( m_piExtendContextMenu == NULL ) { return; } // if: error loading the interface ATLASSERT( m_piExtendContextMenu != NULL ); hr = PiExtendContextMenu()->QueryInterface( IID_IWEInvokeCommand, (LPVOID *) &m_piInvokeCommand ); if ( hr != NOERROR ) { PiExtendContextMenu()->Release(); m_piExtendContextMenu = NULL; ThrowStaticException( hr, ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR, StrCLSID() ); } // if: error getting the InvokeCommand interface // // Add context menu items. // GetUnknown()->AddRef(); // Add a reference because extension is going to release. Pdo()->AddRef(); // Trace( g_tagExtDll, _T("CCluAdmExDll::AddContextMenuItem() - Adding context menu items from '%s'"), StrCLSID() ); try { hr = PiExtendContextMenu()->AddContextMenuItems( Pdo()->GetUnknown(), this ); } // try catch ( ... ) { hr = E_FAIL; } // catch if ( hr != NOERROR ) { ThrowStaticException( hr, ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR, StrCLSID() ); } // if: error occurred // // Add a separator after the extension's items. // // Trace( g_tagExtDll, _T("CCluAdmExDll::AddContextMenuItem() - Adding separator") ); try { hr = AddExtensionMenuItem( NULL, NULL, (ULONG) -1, 0, MF_SEPARATOR ); } // try catch ( ... ) { hr = E_FAIL; } // catch if ( hr != NOERROR ) { ThrowStaticException( hr, ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR, StrCLSID() ); } // if: error adding a separator } //*** CCluAdmExDll::AddContextMenuItems() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::InterfaceSupportsErrorInfo [ISupportsErrorInfo] // // Routine Description: // Determines whether the interface supports error info (???). // // Arguments: // riid [IN] Reference to the interface ID. // // Return Value: // S_OK Interface supports error info. // S_FALSE Interface does not support error info. // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCluAdmExDll::InterfaceSupportsErrorInfo( REFIID riid ) { static const IID * rgiid[] = { &IID_IWCPropertySheetCallback, &IID_IWCWizardCallback, &IID_IWCWizard97Callback, &IID_IWCContextMenuCallback, }; int iiid; for ( iiid = 0 ; iiid < sizeof( rgiid ) / sizeof( rgiid[0] ) ; iiid++ ) { if ( InlineIsEqualGUID( *rgiid[iiid], riid ) ) { return S_OK; } // if: found a match } return S_FALSE; } //*** CCluAdmExDll::InterfaceSupportsErrorInfo() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::AddPropertySheetPage [IWCPropertySheetCallback] // // Routine Description: // Add a page to the property sheet. // // Arguments: // plong_hpage [IN] Page to add. // // Return Value: // NOERROR Page added successfully. // E_INVALIDARG NULL hpage. // Any hresult returned from CBasePropertySheetWindow::HrAddExtensionPage(). // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCluAdmExDll::AddPropertySheetPage( IN LONG * plong_hpage ) { ATLASSERT( plong_hpage != NULL ); ATLASSERT( Psht() != NULL ); HRESULT hr; // Loop to avoid goto's. do { // // Do this for the release build. // if ( (plong_hpage == NULL) || (Psht() == NULL) ) { hr = E_INVALIDARG; break; } // if: no page or sheet // // Allocate a new page object. // CCluAdmExPropPage * ppp = new CCluAdmExPropPage( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) ); ATLASSERT( ppp != NULL ); if ( ppp == NULL ) { hr = E_OUTOFMEMORY; break; } // if: error allocating memory // // Initialize the page object. // if ( ! ppp->BInit( Psht() ) ) { delete ppp; hr = E_FAIL; break; } // if: error initializing the page object // // Add the page to the sheet. // CBasePropertySheetWindow * psht = dynamic_cast< CBasePropertySheetWindow * >( Psht() ); ATLASSERT( psht != NULL ); hr = psht->HrAddExtensionPage( ppp ); if ( hr != NOERROR ) { delete ppp; break; } // if: error adding the extension page } while ( 0 ); return hr; } //*** CCluAdmExDll::AddPropertySheetPage() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::AddWizardPage [IWCWizardCallback] // // Routine Description: // Add a page to the wizard. // // Arguments: // plong_hpage [IN] Page to add. // // Return Value: // NOERROR Page added successfully. // E_INVALIDARG NULL hpage. // Any hresult returned from CWizardWindow::HrAddExtensionPage(). // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCluAdmExDll::AddWizardPage( IN LONG * plong_hpage ) { ATLASSERT( plong_hpage != NULL ); ATLASSERT( Psht() != NULL ); HRESULT hr; // Loop to avoid goto's. do { // // Do this for the release build. // if ( (plong_hpage == NULL) || (Psht() == NULL) ) { hr = E_INVALIDARG; break; } // if: no page or sheet // // Allocate a new page object. // CCluAdmExWizPage * pwp = new CCluAdmExWizPage( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) ); ATLASSERT( pwp != NULL ); if ( pwp == NULL ) { hr = E_OUTOFMEMORY; break; } // if: error allocating memory // // Initialize the page object. // if ( ! pwp->BInit( Psht() ) ) { delete pwp; hr = E_FAIL; break; } // if: error initializing the page object // // Set the default buttons to display. This assumes that there is // a non-extension page already in the sheet and that there will // be a page added after all extension pages have been added. // pwp->SetDefaultWizardButtons( PSWIZB_BACK | PSWIZB_NEXT ); // // Add the page to the sheet. // CWizardWindow * pwiz = dynamic_cast< CWizardWindow * >( Psht() ); ATLASSERT( pwiz != NULL ); hr = pwiz->HrAddExtensionPage( pwp ); if ( hr != NOERROR ) { delete pwp; break; } // if: error adding the extension page } while ( 0 ); return hr; } //*** CCluAdmExDll::AddWizardPage() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::AddWizard97Page [IWCWizard97Callback] // // Routine Description: // Add a page to the Wizard97 wizard. // // Arguments: // plong_hpage [IN] Page to add. // // Return Value: // NOERROR Page added successfully. // E_INVALIDARG NULL hpage. // Any hresult returned from CWizardWindow::HrAddExtensionPage(). // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCluAdmExDll::AddWizard97Page( IN LONG * plong_hpage ) { ATLASSERT( plong_hpage != NULL ); ATLASSERT( Psht() != NULL ); HRESULT hr; // Loop to avoid goto's. do { // // Do this for the release build. // if ( (plong_hpage == NULL) || (Psht() == NULL) ) { hr = E_INVALIDARG; break; } // if: no page or sheet // // Allocate a new page object. // CCluAdmExWiz97Page * pwp = new CCluAdmExWiz97Page( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) ); ATLASSERT( pwp != NULL ); if ( pwp == NULL ) { hr = E_OUTOFMEMORY; break; } // if: error allocating memory // // Initialize the page object. // if ( ! pwp->BInit( Psht() ) ) { delete pwp; hr = E_FAIL; break; } // if: error initializing the page object // // Set the default buttons to display. This assumes that there is // a non-extension page already in the sheet and that there will // be a page added after all extension pages have been added. // pwp->SetDefaultWizardButtons( PSWIZB_BACK | PSWIZB_NEXT ); // // Add the page to the sheet. // CWizardWindow * pwiz = dynamic_cast< CWizardWindow * >( Psht() ); ATLASSERT( pwiz != NULL ); hr = pwiz->HrAddExtensionPage( pwp ); if ( hr != NOERROR ) { delete pwp; break; } // if: error adding the extension page } while ( 0 ); return hr; } //*** CCluAdmExDll::AddWizard97Page() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::EnableNext [IWCWizardCallback/IWCWizard97Callback] // // Routine Description: // Enable or disable the NEXT button. If it is the last page, the // FINISH button will be enabled or disabled. // // Arguments: // hpage [IN] Page for which the button is being enabled or // disabled. // bEnable [IN] TRUE = Enable the button, FALSE = disable. // // Return Value: // NOERROR Success. // E_INVALIDARG Unknown hpage specified. // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCluAdmExDll::EnableNext( IN LONG * plong_hpage, IN BOOL bEnable ) { ATLASSERT( plong_hpage != NULL ); ATLASSERT( Psht() != NULL ); // // Find the page in the extension page list. // CWizardPageWindow * pwp = Pext()->PwpPageFromHpage( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) ); if ( pwp == NULL ) { return E_INVALIDARG; } // if: page not found // // Let the page enable/disable the Next button. // pwp->EnableNext( bEnable ); return NOERROR; } //*** CCluAdmExDll::EnableNext() ///////////////////////////////////////////////////////////////////////////// //++ // // CCluAdmExDll::AddExtensionMenuItem [IWCContextMenuCallback] // // Routine Description: // Add a page to the wizard. // // Arguments: // lpszName [IN] Name of item. // lpszStatusBarText [IN] Text to appear on the status bar when the // item is highlighted. // nCommandID [IN] ID for the command when menu item is invoked. // Must not be -1. // nSubmenuCommandID [IN] ID for a submenu. // uFlags [IN] Menu flags. The following are not supported: // MF_OWNERDRAW, MF_POPUP // // Return Value: // NOERROR Item added successfully. // E_INVALIDARG MF_OWNERDRAW or MF_POPUP were specified. // E_OUTOFMEMORY Error allocating the item. // // Exceptions Thrown: // None. // //-- ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCluAdmExDll::AddExtensionMenuItem( IN BSTR lpszName, IN BSTR lpszStatusBarText, IN ULONG nCommandID, IN ULONG nSubmenuCommandID, IN ULONG uFlags ) { ATLASSERT( Pext() != NULL ); ATLASSERT( Pmenu() != NULL ); ATLASSERT( !(uFlags & (MF_OWNERDRAW | MF_POPUP)) ); HRESULT hr = NOERROR; CCluAdmExMenuItem * pemi = NULL; // // Do this for the release build. // if ( (uFlags & (MF_OWNERDRAW | MF_POPUP)) != 0 ) { hr = E_INVALIDARG; } // if: invalid menu flags specified else { ATLASSERT( Pext()->PemiFromExtCommandID( nCommandID ) == NULL ); try { // Trace( g_tagExtDll, _T("CCluAdmExDll::AddExtensionMenuItem() - Adding menu item '%s', ExtID = %d"), lpszName, nCommandID ); // // Allocate a new item. // pemi = new CCluAdmExMenuItem( OLE2CT( lpszName ), OLE2CT( lpszStatusBarText ), nCommandID, NNextCommandID(), NNextMenuID(), uFlags, FALSE, /*bMakeDefault*/ PiInvokeCommand() ); if ( pemi == NULL ) { ThrowStaticException( E_OUTOFMEMORY, (UINT) 0 ); } // if: error allocating memory // // Insert the item in the menu. // if ( ! Pmenu()->InsertMenu( NNextMenuID(), MF_BYPOSITION | uFlags, NNextCommandID(), pemi->StrName() ) ) { ThrowStaticException( ::GetLastError(), ADMC_IDS_INSERT_MENU_ERROR, pemi->StrName() ); } // if: error inserting the menu // // Add the item to the tail of the list. // Pext()->PlMenuItems()->insert( Pext()->PlMenuItems()->end(), pemi ); pemi = NULL; // // Update the counters. // Pext()->m_nNextCommandID++; Pext()->m_nNextMenuID++; } // try catch ( CNTException * pnte ) { hr = pnte->Sc(); pnte->ReportError(); pnte->Delete(); } // catch: CNTException catch ( CException * pe ) { hr = E_OUTOFMEMORY; pe->ReportError(); pe->Delete(); } // catch: CException } // else: we can add the item delete pemi; return hr; } //*** CCluAdmExDll::AddExtensionMenuItem()