|
|
// cmponent.cpp : Implementation of CFileMgmtComponent
#include "stdafx.h"
#include "cookie.h"
#include "safetemp.h"
#include "macros.h"
USE_HANDLE_MACROS("FILEMGMT(cmponent.cpp)")
#include "ShrProp.h" // Share Properties Pages
#include "FileSvc.h" // FileServiceProvider
#include "smb.h"
#include "sfm.h"
#include "dataobj.h"
#include "cmponent.h" // CFileMgmtComponent
#include "compdata.h" // CFileMgmtComponentData
#include "stdutils.h" // SynchronousCreateProcess
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#include "stdcmpnt.cpp" // CComponent
UINT g_aColumns0[2] = {IDS_ROOT_NAME, 0}; UINT g_aColumns1[6] = {IDS_SHARES_SHARED_FOLDER, IDS_SHARES_SHARED_PATH, IDS_SHARES_TRANSPORT, IDS_SHARES_NUM_SESSIONS, IDS_SHARES_COMMENT, 0}; UINT g_aColumns2[8] = {IDS_CONN_USERNAME, IDS_CONN_COMPUTERNAME, IDS_CONN_TRANSPORT, IDS_CONN_NUM_FILES, IDS_CONN_CONNECTED_TIME, IDS_CONN_IDLE_TIME, IDS_CONN_IS_GUEST, 0}; UINT g_aColumns3[6] = {IDS_FILE_FILENAME, IDS_FILE_USERNAME, IDS_FILE_TRANSPORT, IDS_FILE_NUM_LOCKS, IDS_FILE_OPEN_MODE, 0}; UINT g_aColumns4[6] = { IDS_SERVICE_SERVICENAME, IDS_SERVICE_DESCRIPTION, IDS_SERVICE_STATUS, IDS_SERVICE_STARTUPTYPE, IDS_SERVICE_SECURITYCONTEXT, 0};
UINT* g_Columns[FILEMGMT_NUMTYPES] = { g_aColumns0, // FILEMGMT_ROOT
g_aColumns1, // FILEMGMT_SHARES
g_aColumns2, // FILEMGMT_SESSIONS
g_aColumns3, // FILEMGMT_RESOURCES
g_aColumns4, // FILEMGMT_SERVICES
NULL, // FILEMGMT_SHARE
NULL, // FILEMGMT_SESSION
NULL, // FILEMGMT_RESOURCE
NULL // FILEMGMT_SERVICE
};
UINT** g_aColumns = g_Columns; /*
const UINT aColumns[STD_NODETYPE_NUMTYPES][STD_MAX_COLUMNS] = { {IDS_ROOT_NAME, 0,0,0,0,0,0}, {IDS_SHARES_SHARED_FOLDER, IDS_SHARES_SHARED_PATH, IDS_SHARES_TRANSPORT, IDS_SHARES_NUM_SESSIONS, IDS_SHARES_COMMENT, 0,0}, {IDS_CONN_USERNAME, IDS_CONN_COMPUTERNAME, IDS_CONN_TRANSPORT, IDS_CONN_NUM_FILES, IDS_CONN_CONNECTED_TIME, IDS_CONN_IDLE_TIME, IDS_CONN_IS_GUEST}, {IDS_FILE_FILENAME, IDS_FILE_USERNAME, IDS_FILE_TRANSPORT, IDS_FILE_NUM_LOCKS, IDS_FILE_OPEN_MODE, 0,0}, { IDS_SERVICE_SERVICENAME, IDS_SERVICE_DESCRIPTION, IDS_SERVICE_STATUS, IDS_SERVICE_STARTUPTYPE, IDS_SERVICE_SECURITYCONTEXT, 0,0 }, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0} }; */
//
// CODEWORK this should be in a resource, for example code on loading data resources see
// D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
// JonN 10/11/96
//
int g_aColumnWidths0[1] = {150}; int g_aColumnWidths1[5] = {AUTO_WIDTH,120 ,90 ,AUTO_WIDTH,150}; int g_aColumnWidths2[7] = {100 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}; int g_aColumnWidths3[5] = {120 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH}; int g_aColumnWidths4[5] = {130 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}; int* g_ColumnWidths[FILEMGMT_NUMTYPES] = { g_aColumnWidths0, // FILEMGMT_ROOT
g_aColumnWidths1, // FILEMGMT_SHARES
g_aColumnWidths2, // FILEMGMT_SESSIONS
g_aColumnWidths3, // FILEMGMT_RESOURCES
g_aColumnWidths4, // FILEMGMT_SERVICES
NULL, // FILEMGMT_SHARE
NULL, // FILEMGMT_SESSION
NULL, // FILEMGMT_RESOURCE
NULL // FILEMGMT_SERVICE
}; int** g_aColumnWidths = g_ColumnWidths; /*
const int aColumnWidths[STD_NODETYPE_NUMTYPES][STD_MAX_COLUMNS] = { {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_ROOT
{AUTO_WIDTH,120 ,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SHARES
{100 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SESSIONS
{120 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_RESOURCES
{130 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SERVICES
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SHARE
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SESSION
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_RESOURCE
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH} // FILEMGMT_SERVICE
}; */
CString g_cstrClientName; CString g_cstrGuest; CString g_cstrYes; CString g_cstrNo;
// Note that m_pFileMgmtData is still NULL during construction
CFileMgmtComponent::CFileMgmtComponent() : m_pControlbar( NULL ) , m_pSvcMgmtToolbar( NULL ) , m_pFileMgmtToolbar( NULL ) , m_pViewedCookie( NULL ) , m_pSelectedCookie( NULL ) , m_iSortColumn(0) , m_dwSortFlags(0) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); }
CFileMgmtComponent::~CFileMgmtComponent() { TRACE_METHOD(CFileMgmtComponent,ReleaseAll); /* now in CFileMgmtComponentData
if (m_hScManager != NULL) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); // required for CWaitCursor
CWaitCursor wait; // Close the service control manager
(void)::CloseServiceHandle(m_hScManager); } // if
*/ VERIFY( SUCCEEDED(ReleaseAll()) ); }
HRESULT CFileMgmtComponent::ReleaseAll() { MFC_TRY;
TRACE_METHOD(CFileMgmtComponent,ReleaseAll);
if ( NULL != m_pViewedCookie ) { // We did not get an equal number of MMCN_SHOW(1) and
// MMCN_SHOW(0) notifications
// CODEWORK should assert here but MMC is currently broken
// ASSERT(FALSE);
m_pViewedCookie->ReleaseResultChildren(); m_pViewedCookie->Release(); // JonN 10/1/01 465507
m_pViewedCookie = NULL; }
// We should get an equal number of MMCN_SELECT(1) and MMCN_SELECT(0) notifications
// CODEWORK should assert this but MMC is broken ASSERT( NULL == m_pSelectedCookie );
SAFE_RELEASE(m_pSvcMgmtToolbar); SAFE_RELEASE(m_pFileMgmtToolbar); SAFE_RELEASE(m_pControlbar);
return CComponent::ReleaseAll();
MFC_CATCH; }
FileServiceProvider* CFileMgmtComponent::GetFileServiceProvider( FILEMGMT_TRANSPORT transport ) { return QueryComponentDataRef().GetFileServiceProvider(transport); }
BOOL CFileMgmtComponent::IsServiceSnapin() { return QueryComponentDataRef().IsServiceSnapin(); }
/////////////////////////////////////////////////////////////////////////////
// IComponent Implementation
HRESULT CFileMgmtComponent::LoadStrings() { Service_LoadResourceStrings(); return S_OK; }
HRESULT CFileMgmtComponent::LoadColumns( CFileMgmtCookie* pcookie ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); // 2002/03/22-JonN 572859
TEST_NONNULL_PTR_PARAM(pcookie); ASSERT(m_pHeader != NULL);
#ifdef SNAPIN_PROTOTYPER
(void)Prototyper_FInsertColumns(pcookie); return S_OK; #endif
if (g_cstrGuest.IsEmpty()) VERIFY(g_cstrGuest.LoadString(IDS_GUEST)); if (g_cstrYes.IsEmpty()) VERIFY(g_cstrYes.LoadString(IDS_YES)); if (g_cstrNo.IsEmpty()) VERIFY(g_cstrNo.LoadString(IDS_NO));
return LoadColumnsFromArrays( pcookie->QueryObjectType() ); }
// OnPropertyChange() is generated by MMCPropertyChangeNotify( param )
HRESULT CFileMgmtComponent::OnPropertyChange( LPARAM param ) { LPDATAOBJECT pdataobject = reinterpret_cast<LPDATAOBJECT> (param); (void) RefreshAllViews(pdataobject);
// The recipient of this notification is required to release the data object
(void) pdataobject->Release();
return S_OK; } // CFileMgmtComponent::OnPropertyChange()
//
// In case of multiselect, piDataObject may point to a composite data object (MMC_MS_DO).
// RefreshAllViewsOnSelectedObject will crack down MMC_MS_DO to retrieve SI_MS_DO, then call
// RefreshAllViews on one of the selected objects in the internal list.
//
HRESULT CFileMgmtComponent::RefreshAllViewsOnSelectedObject(LPDATAOBJECT piDataObject) { BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject); if (!bMultiSelectObject) return RefreshAllViews(piDataObject);
//
// piDataObject is the composite data object (MMC_MS_DO) created by MMC.
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
// we provided to MMC in QueryDataObject().
//
IDataObject *piSIMSDO = NULL; HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO); if (SUCCEEDED(hr)) { CFileMgmtDataObject *pDataObj = NULL; hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj)); if (SUCCEEDED(hr)) { //
// get the internal list of data objects of selected items, operate on one of them.
//
CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList(); ASSERT(!pMultiSelectObjList->empty()); hr = RefreshAllViews(*(pMultiSelectObjList->begin())); }
piSIMSDO->Release(); }
return hr; }
// Forces all views of the specified data object to refresh
HRESULT CFileMgmtComponent::RefreshAllViews( LPDATAOBJECT pDataObject ) { if ( NULL == pDataObject || NULL == m_pConsole ) { // JonN 465022 9/26/01
// This can happen if the view for this property page
// has already been released
// ASSERT(FALSE);
return ERROR_INVALID_PARAMETER; }
// This is new code for updating the Service list using a mark-and-sweep algorithm.
// Eventually this should be applied to all result cookies.
CCookie* pbasecookie = NULL; HRESULT hr = ExtractData( pDataObject, CDataObject::m_CFRawCookie, &pbasecookie, sizeof(pbasecookie) ); RETURN_HR_IF_FAIL; // MMC shouldn't have given me someone else's cookie
pbasecookie = QueryBaseComponentDataRef().ActiveBaseCookie( pbasecookie ); CFileMgmtCookie* pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie); RETURN_E_FAIL_IF_NULL(pUpdatedCookie); FileMgmtObjectType objTypeForUpdatedCookie = pUpdatedCookie->QueryObjectType(); if ( FILEMGMT_SERVICE == objTypeForUpdatedCookie ) { if ( NULL == m_pViewedCookie || FILEMGMT_SERVICES != m_pViewedCookie->QueryObjectType() ) { return S_OK; // not a service cookie update
} pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(m_pViewedCookie); RETURN_E_FAIL_IF_NULL(pUpdatedCookie); objTypeForUpdatedCookie = FILEMGMT_SERVICES; } if ( FILEMGMT_SERVICES == objTypeForUpdatedCookie ) { CFileMgmtScopeCookie* pScopeCookie = dynamic_cast<CFileMgmtScopeCookie*>(pUpdatedCookie); RETURN_E_FAIL_IF_NULL(pScopeCookie);
// "Mark" -- Mark all existing list elements as "delete"
pScopeCookie->MarkResultChildren( NEWRESULTCOOKIE_DELETE );
// "Sweep" -- Read the new list. When a new element is the same object
// as an existing element not yet seen, mark the old element as "old"
// and update its fields. Otherwise, add it as a "new" element.
hr = QueryComponentDataRef().Service_PopulateServices(m_pResultData, pScopeCookie); RETURN_HR_IF_FAIL;
// Refresh all views to conform with the new list.
hr = m_pConsole->UpdateAllViews( pDataObject, 2L, 0L ); RETURN_HR_IF_FAIL;
// UpdateToolbar if selected
hr = m_pConsole->UpdateAllViews( pDataObject, 3L, 0L ); RETURN_HR_IF_FAIL;
// Remove items which are still marked "delete".
pScopeCookie->RemoveMarkedChildren();
pScopeCookie->MarkResultChildren( NEWRESULTCOOKIE_OLD );
return S_OK; }
//
// JonN 1/27/00: WinSE 5875: The refresh action is liable to delete pDataObject
// unless we keep an extra refcount. In practice, this only appears to happen
// when we delete a share in taskpad view.
//
CComPtr<IDataObject> spDataObject = pDataObject;
// clear all views of this data
hr = m_pConsole->UpdateAllViews( pDataObject, 0L, 0L ); RETURN_HR_IF_FAIL;
// reread all views of this data
hr = m_pConsole->UpdateAllViews( pDataObject, 1L, 0L ); RETURN_HR_IF_FAIL;
// UpdateToolbar if selected
hr = m_pConsole->UpdateAllViews( pDataObject, 3L, 0L ); return hr; } // CFileMgmtComponent::RefreshAllViews()
// OnViewChange is generated by UpdateAllViews( lpDataObject, data, hint )
HRESULT CFileMgmtComponent::OnViewChange( LPDATAOBJECT lpDataObject, LPARAM data, LPARAM /*hint*/ ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CWaitCursor wait;
ASSERT( NULL != lpDataObject );
if (NULL == m_pViewedCookie) // skip this component if not being viewed
return S_OK;
CCookie* pbasecookie = NULL; HRESULT hr = ExtractData( lpDataObject, CDataObject::m_CFRawCookie, &pbasecookie, sizeof(pbasecookie) );
RETURN_HR_IF_FAIL; // MMC shouldn't have given me someone else's cookie
pbasecookie = QueryBaseComponentDataRef().ActiveBaseCookie( pbasecookie ); CFileMgmtCookie* pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie); RETURN_E_FAIL_IF_NULL(pUpdatedCookie); FileMgmtObjectType objTypeForUpdatedCookie = pUpdatedCookie->QueryObjectType();
switch (m_pViewedCookie->QueryObjectType()) { case FILEMGMT_ROOT: return S_OK; // there is never any need to refresh this
case FILEMGMT_RESOURCES: if ( FILEMGMT_RESOURCE == objTypeForUpdatedCookie || FILEMGMT_RESOURCES == objTypeForUpdatedCookie) break; // fall through
case FILEMGMT_SESSIONS: if ( FILEMGMT_SESSION == objTypeForUpdatedCookie || FILEMGMT_SESSIONS == objTypeForUpdatedCookie) break; // fall through
case FILEMGMT_SHARES: if ( FILEMGMT_SHARE == objTypeForUpdatedCookie || FILEMGMT_SHARES == objTypeForUpdatedCookie) break; return S_OK; case FILEMGMT_SERVICES: if ( FILEMGMT_SERVICE == objTypeForUpdatedCookie || FILEMGMT_SERVICES == objTypeForUpdatedCookie) break; return S_OK; case FILEMGMT_SHARE: case FILEMGMT_SESSION: case FILEMGMT_RESOURCE: case FILEMGMT_SERVICE: default: ASSERT(FALSE); // this shouldn't be possible
return S_OK; }
// There should be no need to compare machine name, since these are both from the
// same instance.
if ( 0L == data ) { ASSERT( NULL != m_pResultData ); VERIFY( SUCCEEDED(m_pResultData->DeleteAllRsltItems()) ); m_pViewedCookie->ReleaseResultChildren(); //
// At this point, m_pViewedCookie is still the viewed cookie for this IComponent
// but (once this has happened to all of the views) its list of result children
// is empty and its m_nResultCookiesRefcount is zero. This must be followed
// promptly with PopulateListbox calls for these views since this is not a good
// state for the cookie.
//
} else if ( 1L == data ) { // 2002/02/26-JonN overactive assertion
(void) PopulateListbox( m_pViewedCookie ); } else if ( 2L == data ) { VERIFY( SUCCEEDED(RefreshNewResultCookies( *m_pViewedCookie )) ); } else if ( 3L == data ) { if (m_pSelectedCookie == pbasecookie) UpdateToolbar(lpDataObject, TRUE); } else { ASSERT(FALSE); }
return S_OK; } // CFileMgmtComponent::OnViewChange()
/////////////////////////////////////////////////////////////////////
// CFileMgmtComponent::CComponent::OnNotifyRefresh()
//
// Virtual function called by CComponent::IComponent::Notify(MMCN_REFRESH)
// OnNotifyRefresh is generated by enabling the verb MMC_VERB_REFRESH.
HRESULT CFileMgmtComponent::OnNotifyRefresh( LPDATAOBJECT lpDataObject ) { TRACE0("CFileMgmtComponent::OnNotifyRefresh()\n"); ASSERT(m_pResultData != NULL); if ( !m_pResultData ) return E_POINTER; if ( !m_pViewedCookie ) { ASSERT(FALSE); return S_OK; }
// We used to use the cookie here from lpDataObject. However, if one node
// is selected and the user right clicks on a different one we an
// lpDataObject for a node that is not enumerated in the result pane.
// It results in bizarre behavior. So use the m_pViewedCookie, instead.
HRESULT hr = S_OK; switch (m_pViewedCookie->QueryObjectType()) { case FILEMGMT_SHARES: case FILEMGMT_SESSIONS: case FILEMGMT_RESOURCES: case FILEMGMT_SERVICES: (void) RefreshAllViews( lpDataObject ); break;
case FILEMGMT_ROOT: case FILEMGMT_SERVICE: // Service was selected
case FILEMGMT_SHARE: // Share was selected
case FILEMGMT_SESSION: // Session was selected
case FILEMGMT_RESOURCE: // Open file was selected
default: // This can happen if you select Shares, then select Shared Folders,
// then right-click Shares and choose Refresh. JonN 12/7/98
break; // no need to refresh
}
return S_OK; }
/////////////////////////////////////////////////////////////////////
// CFileMgmtComponent::RefreshNewResultCookies()
// 12/03/98 JonN Created
// In the mark-and-sweep refresh algorithm, we have already marked all cookies
// as "old", "new" or "delete". The view must now be made to conform with the list.
HRESULT CFileMgmtComponent::RefreshNewResultCookies( CCookie& refparentcookie ) { ASSERT( NULL != m_pResultData );
RESULTDATAITEM tRDItem; ::ZeroMemory( &tRDItem, sizeof(tRDItem) ); tRDItem.nCol = 0; tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; tRDItem.str = MMC_CALLBACK; // CODEWORK should use MMC_ICON_CALLBACK here
HRESULT hr = S_OK; POSITION pos = refparentcookie.m_listResultCookieBlocks.GetHeadPosition(); while (NULL != pos) { CBaseCookieBlock* pblock = refparentcookie.m_listResultCookieBlocks.GetNext( pos ); ASSERT( NULL != pblock && 1 == pblock->QueryNumCookies() ); CCookie* pbasecookie = pblock->QueryBaseCookie(0); CNewResultCookie* pcookie = dynamic_cast<CNewResultCookie*>(pbasecookie); RETURN_E_FAIL_IF_NULL(pcookie); if ( pcookie->IsMarkedOld() ) { continue; // Leave this one alone
} else if ( pcookie->IsMarkedNew() ) { // This one was just added to the list, add it to the view
tRDItem.nImage = QueryBaseComponentDataRef().QueryImage( *pbasecookie, FALSE ); // WARNING cookie cast
tRDItem.lParam = reinterpret_cast<LPARAM>(pbasecookie); hr = m_pResultData->InsertItem(&tRDItem); if ( FAILED(hr) ) { ASSERT(FALSE); break; } } else if ( pcookie->IsMarkedChanged() ) { // This one was already in the list but its fields were altered, update
HRESULTITEM hItem = 0; hr = m_pResultData->FindItemByLParam( reinterpret_cast<LPARAM>(pbasecookie), &hItem ); if ( FAILED(hr) || 0 == hItem ) { ASSERT(FALSE); continue; } VERIFY( SUCCEEDED(m_pResultData->UpdateItem( hItem )) ); } else { // This one was just marked for deletion, remove it from the view
// CODEWORK This may be a performance problem when the list is long
// CODEWORK BryanWal doesn't trust FindItemByLParam! Test carefully!
ASSERT( pcookie->IsMarkedForDeletion() ); HRESULTITEM hItem = 0; hr = m_pResultData->FindItemByLParam( reinterpret_cast<LPARAM>(pbasecookie), &hItem ); if ( FAILED(hr) || 0 == hItem ) { ASSERT(FALSE); continue; } VERIFY( SUCCEEDED(m_pResultData->DeleteItem( hItem, 0 )) ); } } VERIFY( SUCCEEDED(m_pResultData->Sort( m_iSortColumn , m_dwSortFlags, 0 )) ); return hr; }
HRESULT CFileMgmtComponent::OnNotifySelect( LPDATAOBJECT lpDataObject, BOOL fSelected ) { HRESULT hr = S_OK; BOOL bMultiSelectObject = FALSE;
//
// MMC passes in SI_MS_DO in MMCN_SELECT in case of multiselection.
//
CFileMgmtDataObject *pDataObj = NULL; hr = ExtractData(lpDataObject, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj)); if (SUCCEEDED(hr)) { CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList(); bMultiSelectObject = !(pMultiSelectObjList->empty()); }
//
// no verbs to add for multi-selected SharedFolders items
//
if (!bMultiSelectObject) { CCookie* pbasecookie = NULL; hr = ExtractData( lpDataObject, CDataObject::m_CFRawCookie, &pbasecookie, sizeof(pbasecookie) ); RETURN_HR_IF_FAIL; // MMC shouldn't have given me someone else's cookie
pbasecookie = QueryBaseComponentDataRef().ActiveBaseCookie( pbasecookie ); CFileMgmtCookie* pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie); RETURN_E_FAIL_IF_NULL(pUpdatedCookie);
m_pSelectedCookie = (fSelected) ? pUpdatedCookie : NULL;
UpdateDefaultVerbs(); }
return S_OK; }
void CFileMgmtComponent::UpdateDefaultVerbs() { if (NULL == m_pSelectedCookie) return;
FileMgmtObjectType objtypeSelected = m_pSelectedCookie->QueryObjectType();
if (NULL != m_pViewedCookie) { BOOL fEnableRefresh = FALSE; FileMgmtObjectType objtypeViewed = m_pViewedCookie->QueryObjectType();
switch (objtypeViewed) { case FILEMGMT_SHARES: if (FILEMGMT_SHARES == objtypeSelected || FILEMGMT_SHARE == objtypeSelected) fEnableRefresh = TRUE; break; case FILEMGMT_SESSIONS: if (FILEMGMT_SESSIONS == objtypeSelected || FILEMGMT_SESSION == objtypeSelected) fEnableRefresh = TRUE; break; case FILEMGMT_RESOURCES: if (FILEMGMT_RESOURCES == objtypeSelected || FILEMGMT_RESOURCE == objtypeSelected) fEnableRefresh = TRUE; break; case FILEMGMT_SERVICES: if (FILEMGMT_SERVICES == objtypeSelected || FILEMGMT_SERVICE == objtypeSelected) fEnableRefresh = TRUE; break; } if (fEnableRefresh) { // Enable the refresh menuitem
VERIFY( SUCCEEDED(m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE)) ); } }
switch (objtypeSelected) { case FILEMGMT_SHARE: // Share was selected
//
// don't enable Properties on the menu whenever SimpleSharingUI appears in NT Explorer
//
if (QueryComponentDataRef().GetIsSimpleUI()) { VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_NONE)) ); break; } // fall through
case FILEMGMT_SERVICE: // Service was selected
// Set the default verb to display the properties of the selected object
VERIFY( SUCCEEDED(m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE)) ); VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES)) ); break;
case FILEMGMT_SESSION: // Session was selected
case FILEMGMT_RESOURCE: // Open file was selected
VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_NONE)) ); break;
case FILEMGMT_SHARES: case FILEMGMT_SESSIONS: case FILEMGMT_RESOURCES: case FILEMGMT_SERVICES: case FILEMGMT_ROOT: // Root node was selected
// set the default verb to open/expand the folder
VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN)) ); break;
default: // shouldn't happen
ASSERT(FALSE); break;
} // switch
} // CFileMgmtComponent::OnNotifySelect()
STDMETHODIMP CFileMgmtComponent::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject) { HRESULT hr = S_OK;
MFC_TRY;
//
// MMC queries us for a multiselect data object (SI_MS_DO) by
// passing the special cookie in this QueryDataObject call.
//
if (IS_SPECIAL_COOKIE(cookie) && MMC_MULTI_SELECT_COOKIE == cookie) { CComObject<CFileMgmtDataObject>* pDataObject = NULL; hr = CComObject<CFileMgmtDataObject>::CreateInstance(&pDataObject);
if (SUCCEEDED(hr)) hr = pDataObject->InitMultiSelectDataObjects(QueryComponentDataRef());
if (SUCCEEDED(hr)) { //
// We create a multiselect data object (SI_MS_DO), which contains
// an internal list of data objects of selected items.
//
RESULTDATAITEM rdi = {0}; int nIndex = -1; do { ZeroMemory(&rdi, sizeof(RESULTDATAITEM)); rdi.mask = RDI_STATE; rdi.nCol = 0; rdi.nIndex = nIndex; // nIndex == -1 to start at first item
rdi.nState = LVIS_SELECTED; // only interested in selected items
hr = m_pResultData->GetNextItem(&rdi); if (FAILED(hr)) break;
if (rdi.nIndex != -1) { //
// rdi is the RESULTDATAITEM of a selected item. its lParam contains the cookie.
// Add it to the internal data object list.
//
CCookie* pbasecookie = reinterpret_cast<CCookie*>(rdi.lParam); CFileMgmtCookie* pUseThisCookie = QueryComponentDataRef().ActiveCookie((CFileMgmtCookie*)pbasecookie); pDataObject->AddMultiSelectDataObjects(pUseThisCookie, type); }
nIndex = rdi.nIndex;
} while (-1 != nIndex); }
//
// return this SI_MS_DO to MMC
//
if (SUCCEEDED(hr)) hr = pDataObject->QueryInterface(IID_IDataObject, (void **)ppDataObject); if (FAILED(hr)) delete pDataObject; } else { // Delegate it to the IComponentData
hr = QueryBaseComponentDataRef().QueryDataObject(cookie, type, ppDataObject); }
MFC_CATCH;
return hr; }
STDMETHODIMP CFileMgmtComponent::GetResultViewType(MMC_COOKIE cookie, BSTR* ppViewType, long* pViewOptions) { *ppViewType = NULL;
//
// we support multiselection in SharedFolders snapin
//
CCookie* pbasecookie = reinterpret_cast<CCookie*>(cookie); CFileMgmtCookie* pUseThisCookie = QueryComponentDataRef().ActiveCookie((CFileMgmtCookie*)pbasecookie); FileMgmtObjectType objecttype = pUseThisCookie->QueryObjectType(); if ( FILEMGMT_SHARES == objecttype || FILEMGMT_SESSIONS == objecttype || FILEMGMT_RESOURCES == objecttype ) { *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT; } else { *pViewOptions = MMC_VIEW_OPTIONS_NONE; }
return S_FALSE; }
HRESULT CFileMgmtComponent::Show( CCookie* pcookie, LPARAM arg, HSCOPEITEM /*hScopeItem*/ ) { TEST_NONNULL_PTR_PARAM(pcookie);
#ifndef SNAPIN_PROTOTYPER
if ( 0 == arg ) { //
// This is a Hide notification
//
if ( NULL == m_pResultData ) { ASSERT( FALSE ); return E_UNEXPECTED; }
// We should not get a Hide notification if we are not currently showing
// CODEWORK see 287399: MMC: two MMCN_SHOW(0) notifications
// ASSERT( (CFileMgmtCookie*)pcookie == m_pViewedCookie );
if ( (CFileMgmtScopeCookie*)pcookie == m_pViewedCookie ) { //
// Only delete the cookies if no other views are using them
//
pcookie->ReleaseResultChildren();
m_pViewedCookie->Release(); // JonN 10/1/01 465507
m_pViewedCookie = NULL;
UpdateDefaultVerbs(); } return S_OK; } // if
#else
CPrototyperScopeCookie* pScopeCookie = (CPrototyperScopeCookie*) pcookie; if (pScopeCookie->m_ScopeType == HTML) return S_OK; #endif // SNAPIN_PROTOTYPER
// We should not get a Show notification if we are already showing
if ( NULL != m_pViewedCookie ) { ASSERT(FALSE); return S_OK; }
//
// This is a Show notification
// Build new cookies and insert them into the cookie and the view
//
ASSERT( IsAutonomousObjectType( ((CFileMgmtCookie*)pcookie)->QueryObjectType() ) );
m_pViewedCookie = (CFileMgmtScopeCookie*)pcookie; m_pViewedCookie->AddRef(); // JonN 10/1/01 465507
LoadColumns( m_pViewedCookie );
UpdateDefaultVerbs();
return PopulateListbox( m_pViewedCookie ); } // CFileMgmtComponent::Show()
HRESULT CFileMgmtComponent::OnNotifyAddImages( LPDATAOBJECT /*lpDataObject*/, LPIMAGELIST lpImageList, HSCOPEITEM /*hSelectedItem*/ ) { return QueryComponentDataRef().LoadIcons(lpImageList,TRUE); }
HRESULT CFileMgmtComponent::PopulateListbox(CFileMgmtScopeCookie* pcookie) { TEST_NONNULL_PTR_PARAM(pcookie);
CWaitCursor cwait;
HRESULT hr = S_OK; //
// If this is the second view on the same data, just insert the same cookies
// which are in the other views
//
if ( 1 < pcookie->AddRefResultChildren() ) { hr = InsertResultCookies( *pcookie ); if ( SUCCEEDED(hr) ) hr = m_pResultData->Sort( m_iSortColumn , m_dwSortFlags, 0 ); return hr; }
INT iTransport; switch ( pcookie->QueryObjectType() ) { case FILEMGMT_SHARES: for (iTransport = FILEMGMT_FIRST_TRANSPORT; iTransport < FILEMGMT_NUM_TRANSPORTS; iTransport++) { hr = GetFileServiceProvider(iTransport)->PopulateShares(m_pResultData,pcookie); if( FAILED(hr) ) return hr; } break;
case FILEMGMT_SESSIONS: for (iTransport = FILEMGMT_FIRST_TRANSPORT; iTransport < FILEMGMT_NUM_TRANSPORTS; iTransport++) { ASSERT( NULL != m_pResultData ); // otherwise we close all sessions
hr = GetFileServiceProvider(iTransport)->EnumerateSessions ( m_pResultData, pcookie, true); if( FAILED(hr) ) return hr; } break; case FILEMGMT_RESOURCES: for (iTransport = FILEMGMT_FIRST_TRANSPORT; iTransport < FILEMGMT_NUM_TRANSPORTS; iTransport++) { ASSERT( NULL != m_pResultData ); // otherwise we close all sessions
hr = GetFileServiceProvider(iTransport)->EnumerateResources(m_pResultData,pcookie); if( FAILED(hr) ) return hr; } break;
case FILEMGMT_SERVICES: //
// JonN 12/03/98 Service_PopulateServices no longer inserts items into the list
//
hr = QueryComponentDataRef().Service_PopulateServices(m_pResultData, pcookie); if ( SUCCEEDED(hr) ) hr = InsertResultCookies( *pcookie ); if( FAILED(hr) ) return hr;
#ifdef SNAPIN_PROTOTYPER
case FILEMGMT_PROTOTYPER: return Prototyper_HrPopulateResultPane(pcookie); #endif
case FILEMGMT_ROOT: // We no longer need to explicitly insert these
break;
default: ASSERT( FALSE ); // fall through
}
return m_pResultData->Sort( m_iSortColumn , m_dwSortFlags, 0 ); } // CFileMgmtComponent::PopulateListbox()
HRESULT CFileMgmtComponent::GetSnapinMultiSelectDataObject( LPDATAOBJECT i_pMMCMultiSelectDataObject, LPDATAOBJECT *o_ppSnapinMultiSelectDataObject ) { if (!i_pMMCMultiSelectDataObject || !o_ppSnapinMultiSelectDataObject) return E_INVALIDARG;
*o_ppSnapinMultiSelectDataObject = NULL;
//
// i_pMMCMultiSelectDataObject is the composite data object (MMC_MS_DO) created by MMC.
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
// we provided to MMC in QueryDataObject().
//
STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL}; FORMATETC formatetc = {CFileMgmtDataObject::m_CFMultiSelectSnapins, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; HRESULT hr = i_pMMCMultiSelectDataObject->GetData(&formatetc, &stgmedium);
if (SUCCEEDED(hr)) { if (!stgmedium.hGlobal) return E_FAIL;
//
// Locate the SI_MS_DO we have provided to MMC in QueryDataObject().
//
SMMCDataObjects *pMMCDO = (SMMCDataObjects*)::GlobalLock(stgmedium.hGlobal);
GUID guidSnapin = GUID_NULL; VERIFY( SUCCEEDED(QueryComponentDataRef().GetClassID(&guidSnapin)) );
for (int i = 0; i < pMMCDO->count; i++) { GUID guid = GUID_NULL; hr = ExtractData(pMMCDO->lpDataObject[i], CFileMgmtDataObject::m_CFSnapInCLSID, &guid, sizeof(GUID)); if (SUCCEEDED(hr) && guid == guidSnapin) { //
// pMMCDO->lpDataObject[i] is the SI_MS_DO we have provided to MMC in QueryDataObject().
//
*o_ppSnapinMultiSelectDataObject = pMMCDO->lpDataObject[i]; (*o_ppSnapinMultiSelectDataObject)->AddRef();
break; } }
::GlobalUnlock(stgmedium.hGlobal); ::GlobalFree(stgmedium.hGlobal); }
return hr; }
/////////////////////////////////////////////////////////////////////////////
// IExtendContextMenu Implementation
STDMETHODIMP CFileMgmtComponent::AddMenuItems( IDataObject* piDataObject, IContextMenuCallback* piCallback, long* pInsertionAllowed) { MFC_TRY;
TRACE_METHOD(CFileMgmtComponent,AddMenuItems); TEST_NONNULL_PTR_PARAM(piDataObject); TEST_NONNULL_PTR_PARAM(piCallback); TEST_NONNULL_PTR_PARAM(pInsertionAllowed); TRACE( "FileMgmt snapin: extending menu\n" );
HRESULT hr = S_OK;
FileMgmtObjectType objecttype = FILEMGMT_NUMTYPES;
//
// need to find out the object type in case of multiselection
//
BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject); if (!bMultiSelectObject) { objecttype = FileMgmtObjectTypeFromIDataObject(piDataObject); } else { //
// piDataObject is the composite data object (MMC_MS_DO) created by MMC.
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
// we provided to MMC in QueryDataObject().
//
IDataObject *piSIMSDO = NULL; hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO); if (SUCCEEDED(hr)) { //
// Note: we assume all multiselected items are of the same type.
//
// Now retrieve data type of the currently selected items
//
STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL}; FORMATETC formatetc = {CFileMgmtDataObject::m_CFObjectTypesInMultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; hr = piSIMSDO->GetData(&formatetc, &stgmedium); if (SUCCEEDED(hr) && stgmedium.hGlobal) { BYTE* pb = (BYTE*)::GlobalLock(stgmedium.hGlobal);
GUID* pguid = (GUID*)(pb + sizeof(DWORD)); // skip the 1st DWORD - count
objecttype = (FileMgmtObjectType)CheckObjectTypeGUID(pguid);
::GlobalUnlock(stgmedium.hGlobal); ::GlobalFree(stgmedium.hGlobal); }
piSIMSDO->Release(); } }
switch (objecttype) { case FILEMGMT_SHARE: if (FALSE == IsMultiSelectObject(piDataObject)) { FILEMGMT_TRANSPORT transport = FILEMGMT_SFM; ExtractData( piDataObject, CFileMgmtDataObject::m_CFTransport, &transport, sizeof(DWORD) );
if (FILEMGMT_SMB == transport) { CString strShareName; ExtractString( piDataObject, CFileMgmtDataObject::m_CFShareName, &strShareName, MAX_PATH );
if (0 != strShareName.CompareNoCase(_T("IPC$"))) { if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_OPEN_SHARE_TOP, IDS_OPEN_SHARE_TOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle(), _T("OpenShareTop") ); ASSERT( SUCCEEDED(hr) ); } if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_OPEN_SHARE_TASK, IDS_OPEN_SHARE_TASK, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle(), _T("OpenShareTask") ); ASSERT( SUCCEEDED(hr) ); } } } }
//
// don't add acl-related menu items whenever SimpleSharingUI appears in NT Explorer
//
if (QueryComponentDataRef().GetIsSimpleUI()) break;
if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_DELETE_SHARE_TOP, IDS_DELETE_SHARE_TOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle(), _T("DeleteShareTop") ); ASSERT( SUCCEEDED(hr) ); } if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_DELETE_SHARE_TASK, IDS_DELETE_SHARE_TASK, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle(), _T("DeleteShareTask") ); ASSERT( SUCCEEDED(hr) ); } if ( CCM_INSERTIONALLOWED_NEW & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_NEW_SHARE_NEW, IDS_NEW_SHARE_NEW, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, AfxGetInstanceHandle(), _T("NewShareNew") ); ASSERT( SUCCEEDED(hr) ); } break;
case FILEMGMT_SESSION: if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_SESSION_TOP, IDS_CLOSE_SESSION_TOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle(), _T("CloseSessionTop") ); ASSERT( SUCCEEDED(hr) ); } if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_SESSION_TASK, IDS_CLOSE_SESSION_TASK, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle(), _T("CloseSessionTask") ); ASSERT( SUCCEEDED(hr) ); } break;
case FILEMGMT_RESOURCE: if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_RESOURCE_TOP, IDS_CLOSE_RESOURCE_TOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle(), _T("CloseResourceTop") ); ASSERT( SUCCEEDED(hr) ); } if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) ) { hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_RESOURCE_TASK, IDS_CLOSE_RESOURCE_TASK, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle(), _T("CloseResourceTask") ); ASSERT( SUCCEEDED(hr) ); } break;
case FILEMGMT_SERVICE: QueryComponentDataRef().Service_FAddMenuItems(piCallback, piDataObject); break;
#ifdef SNAPIN_PROTOTYPER
case FILEMGMT_PROTOTYPER_LEAF: Prototyper_AddMenuItems(piCallback, piDataObject); break; #endif // SNAPIN_PROTOTYPER
default: { DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE; hr = ExtractData( piDataObject, CFileMgmtDataObject::m_CFDataObjectType, &dataobjecttype, sizeof(dataobjecttype) ); ASSERT( SUCCEEDED(hr) );
// perhaps this is a scope node in the result pane
hr = QueryComponentDataRef().DoAddMenuItems( piCallback, objecttype, dataobjecttype, pInsertionAllowed, piDataObject ); } break; } // switch
return hr;
MFC_CATCH;
} // CFileMgmtComponent::AddMenuItems()
STDMETHODIMP CFileMgmtComponent::Command( LONG lCommandID, IDataObject* piDataObject ) { MFC_TRY;
TRACE_METHOD(CFileMgmtComponent,Command); TEST_NONNULL_PTR_PARAM(piDataObject); TRACE( "CFileMgmtComponent::Command: command %ld selected\n", lCommandID );
#ifdef SNAPIN_PROTOTYPER
Prototyper_ContextMenuCommand(lCommandID, piDataObject); return S_OK; #endif
BOOL fFSMRefresh = FALSE; BOOL fSVCRefresh = FALSE; switch (lCommandID) { case IDS_OPEN_SHARE_TASK: case IDS_OPEN_SHARE_TOP: OpenShare( piDataObject ); break; case IDS_DELETE_SHARE_TASK: case IDS_DELETE_SHARE_TOP: fFSMRefresh = DeleteShare( piDataObject ); break; case IDS_CLOSE_SESSION_TASK: case IDS_CLOSE_SESSION_TOP: fFSMRefresh = CloseSession( piDataObject ); break; case IDS_CLOSE_RESOURCE_TASK: case IDS_CLOSE_RESOURCE_TOP: fFSMRefresh = CloseResource( piDataObject ); break;
case cmServiceStart: case cmServiceStop: case cmServicePause: case cmServiceResume: case cmServiceRestart: case cmServiceStartTask: case cmServiceStopTask: case cmServicePauseTask: case cmServiceResumeTask: case cmServiceRestartTask: fSVCRefresh = QueryComponentDataRef().Service_FDispatchMenuCommand(lCommandID, piDataObject); break;
default: return QueryComponentDataRef().Command(lCommandID, piDataObject); } // switch
if (fFSMRefresh) { //
// In case of multiselect, piDataObject may point to a composite data object (MMC_MS_DO).
// RefreshAllViewsOnSelectedObject will crack down MMC_MS_DO to retrieve SI_MS_DO, then call
// RefreshAllViews on one of the selected objects in the internal list.
//
(void) RefreshAllViewsOnSelectedObject(piDataObject); }
if (fSVCRefresh) { (void) RefreshAllViews( piDataObject ); }
return S_OK; MFC_CATCH; } // CFileMgmtComponent::Command()
BOOL CFileMgmtComponent::OpenShare(LPDATAOBJECT piDataObject) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); ASSERT( piDataObject != NULL ); #ifdef DEBUG
{ FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(piDataObject); ASSERT(FILEMGMT_SHARE == objecttype); } #endif
CString strServerName; HRESULT hr = ExtractString( piDataObject, CFileMgmtDataObject::m_CFMachineName, &strServerName, MAX_PATH ); if (FAILED(hr)) return TRUE; // something is wrong, refresh
CString strShareName; hr = ExtractString( piDataObject, CFileMgmtDataObject::m_CFShareName, &strShareName, MAX_PATH ); if (FAILED(hr)) return TRUE; // something is wrong, refresh
FILEMGMT_TRANSPORT transport; hr = ExtractData( piDataObject, CFileMgmtDataObject::m_CFTransport, &transport, sizeof(DWORD) ); if (FAILED(hr)) return TRUE; // something is wrong, refresh
DWORD retval = 0L; switch (transport) { case FILEMGMT_SMB: { CWaitCursor wait; retval = GetFileServiceProvider(transport)->OpenShare(strServerName, strShareName); } break; case FILEMGMT_SFM: default: ASSERT(FALSE); break; }
if (NERR_Success == retval) { return FALSE; // no need to refresh
}
return TRUE; }
BOOL CFileMgmtComponent::DeleteShare(LPDATAOBJECT piDataObject) { ASSERT( piDataObject != NULL );
BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject); if (!bMultiSelectObject) return DeleteThisOneShare(piDataObject, FALSE);
BOOL bRefresh = FALSE; if (IDYES == DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_s_CONFIRM_DELETEMULTISHARES)) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CWaitCursor wait;
//
// piDataObject is the composite data object (MMC_MS_DO) created by MMC.
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
// we provided to MMC in QueryDataObject().
//
IDataObject *piSIMSDO = NULL; HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO); if (SUCCEEDED(hr)) { CFileMgmtDataObject *pDataObj = NULL; hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj)); if (SUCCEEDED(hr)) { //
// get the internal list of data objects of selected items, operate on each one of them.
//
CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList(); for (CDataObjectList::iterator i = pMultiSelectObjList->begin(); i != pMultiSelectObjList->end(); i++) { BOOL bDeleted = DeleteThisOneShare(*i, TRUE); if (bDeleted) bRefresh = TRUE; } }
piSIMSDO->Release(); } }
return bRefresh; }
BOOL CFileMgmtComponent::DeleteThisOneShare(LPDATAOBJECT piDataObject, BOOL bQuietMode) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); ASSERT( piDataObject != NULL ); #ifdef DEBUG
{ FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(piDataObject); ASSERT(FILEMGMT_SHARE == objecttype); } #endif
CString strServerName; HRESULT hr = ExtractString( piDataObject, CFileMgmtDataObject::m_CFMachineName, &strServerName, MAX_PATH ); RETURN_FALSE_IF_FAIL;
CString strShareName; hr = ExtractString( piDataObject, CFileMgmtDataObject::m_CFShareName, &strShareName, MAX_PATH ); RETURN_FALSE_IF_FAIL;
FILEMGMT_TRANSPORT transport; hr = ExtractData( piDataObject, CFileMgmtDataObject::m_CFTransport, &transport, sizeof(DWORD) ); RETURN_FALSE_IF_FAIL;
BOOL fNetLogonShare = (!lstrcmpi(strShareName, _T("SYSVOL")) || !lstrcmpi(strShareName, _T("NETLOGON"))); BOOL fIPC = FALSE; BOOL fAdminShare = FALSE;
if (!fNetLogonShare && transport == FILEMGMT_SMB) { DWORD dwShareType = 0; GetFileServiceProvider(transport)->ReadShareType(strServerName, strShareName, &dwShareType); fAdminShare = (dwShareType & STYPE_SPECIAL); fIPC = (STYPE_IPC == (dwShareType & STYPE_IPC)); }
if (fIPC) { DoErrMsgBox( GetActiveWindow(), MB_OK | MB_ICONEXCLAMATION, 0, IDS_s_DELETE_IPCSHARE ); return FALSE; }
if ((fNetLogonShare || fAdminShare) && IDYES != DoErrMsgBox( GetActiveWindow(), MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2, 0, (fAdminShare ? IDS_s_CONFIRM_DELETE_ADMINSHARE : IDS_s_CONFIRM_DELETE_NETLOGONSHARE), strShareName) ) { return FALSE; }
DWORD retval = 0L; switch (transport) { case FILEMGMT_SMB: case FILEMGMT_SFM: { if (!bQuietMode) { hr = GetFileServiceProvider(transport)->ConfirmDeleteShare(strServerName, strShareName); if (S_FALSE == hr) return FALSE; // user cancels the operation and keep the share
else if (S_OK != hr) return TRUE; // share may not exist, refresh
}
CWaitCursor wait; retval = GetFileServiceProvider(transport)->DeleteShare(strServerName, strShareName); } break; default: ASSERT(FALSE); break; } if (0L != retval) { (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_DELETE_SHARE, strShareName); return FALSE; } return TRUE; }
BOOL CFileMgmtComponent::CloseSession(LPDATAOBJECT piDataObject) { ASSERT( piDataObject != NULL );
BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject); if (!bMultiSelectObject) return CloseThisOneSession(piDataObject, FALSE);
BOOL bRefresh = FALSE; if (IDYES == DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSEMULTISESSIONS)) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CWaitCursor wait;
//
// piDataObject is the composite data object (MMC_MS_DO) created by MMC.
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
// we provided to MMC in QueryDataObject().
//
IDataObject *piSIMSDO = NULL; HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO); if (SUCCEEDED(hr)) { CFileMgmtDataObject *pDataObj = NULL; hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj)); if (SUCCEEDED(hr)) { //
// get the internal list of data objects of selected items, operate on each one of them.
//
CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList(); for (CDataObjectList::iterator i = pMultiSelectObjList->begin(); i != pMultiSelectObjList->end(); i++) { BOOL bDeleted = CloseThisOneSession(*i, TRUE); if (bDeleted) bRefresh = TRUE; } }
piSIMSDO->Release(); } }
return bRefresh; }
BOOL CFileMgmtComponent::CloseThisOneSession(LPDATAOBJECT piDataObject, BOOL bQuietMode) { AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
ASSERT( piDataObject != NULL );
CCookie* pbasecookie = NULL; FileMgmtObjectType objecttype = FILEMGMT_ROOT; HRESULT hr = ExtractBaseCookie( piDataObject, &pbasecookie, &objecttype ); ASSERT( SUCCEEDED(hr) && NULL != pbasecookie && FILEMGMT_SESSION == objecttype ); CFileMgmtResultCookie* pcookie = (CFileMgmtResultCookie*)pbasecookie;
if ( !bQuietMode && IDYES != DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSESESSION) ) { return FALSE; }
FILEMGMT_TRANSPORT transport = FILEMGMT_SMB; VERIFY( SUCCEEDED( pcookie->GetTransport( &transport ) ) ); DWORD retval = 0;
if (bQuietMode) { retval = GetFileServiceProvider(transport)->CloseSession( pcookie ); } else { CWaitCursor wait; retval = GetFileServiceProvider(transport)->CloseSession( pcookie ); }
if (0L != retval) { (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_CLOSE_SESSION); return FALSE; } return TRUE; }
BOOL CFileMgmtComponent::CloseResource(LPDATAOBJECT piDataObject) { ASSERT( piDataObject != NULL );
BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject); if (!bMultiSelectObject) return CloseThisOneResource(piDataObject, FALSE);
BOOL bRefresh = FALSE; if (IDYES == DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSEMULTIRESOURCES)) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CWaitCursor wait;
//
// piDataObject is the composite data object (MMC_MS_DO) created by MMC.
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
// we provided to MMC in QueryDataObject().
//
IDataObject *piSIMSDO = NULL; HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO); if (SUCCEEDED(hr)) { CFileMgmtDataObject *pDataObj = NULL; hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj)); if (SUCCEEDED(hr)) { //
// get the internal list of data objects of selected items, operate on each one of them.
//
CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList(); for (CDataObjectList::iterator i = pMultiSelectObjList->begin(); i != pMultiSelectObjList->end(); i++) { BOOL bDeleted = CloseThisOneResource(*i, TRUE); if (bDeleted) bRefresh = TRUE; } }
piSIMSDO->Release(); } }
return bRefresh; }
BOOL CFileMgmtComponent::CloseThisOneResource(LPDATAOBJECT piDataObject, BOOL bQuietMode) { AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
ASSERT( piDataObject != NULL );
CCookie* pbasecookie = NULL; FileMgmtObjectType objecttype; HRESULT hr = ExtractBaseCookie( piDataObject, &pbasecookie, &objecttype ); ASSERT( SUCCEEDED(hr) && NULL != pbasecookie && FILEMGMT_RESOURCE == objecttype ); CFileMgmtResultCookie* pcookie = (CFileMgmtResultCookie*)pbasecookie;
if ( !bQuietMode && IDYES != DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSERESOURCE) ) { return FALSE; }
FILEMGMT_TRANSPORT transport = FILEMGMT_SMB; VERIFY( SUCCEEDED( pcookie->GetTransport( &transport ) ) ); DWORD retval = 0;
if (bQuietMode) { retval = GetFileServiceProvider(transport)->CloseResource( pcookie ); } else { CWaitCursor wait; retval = GetFileServiceProvider(transport)->CloseResource( pcookie ); }
if (0L != retval) { (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_CLOSE_RESOURCE); return FALSE; } return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
/// IExtendPropertySheet
STDMETHODIMP CFileMgmtComponent::QueryPagesFor(LPDATAOBJECT pDataObject) { MFC_TRY;
if (NULL == pDataObject) { ASSERT(FALSE); return E_POINTER; }
HRESULT hr = S_OK; DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE; // extract data from data object
FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(pDataObject); hr = ExtractData( pDataObject, CFileMgmtDataObject::m_CFDataObjectType, &dataobjecttype, sizeof(dataobjecttype) ); ASSERT( SUCCEEDED(hr) ); ASSERT( CCT_SCOPE == dataobjecttype || CCT_RESULT == dataobjecttype || CCT_SNAPIN_MANAGER == dataobjecttype );
// determine if it needs property pages
switch (objecttype) { case FILEMGMT_SESSION: case FILEMGMT_RESOURCE: ASSERT(CCT_SNAPIN_MANAGER != dataobjecttype); return S_FALSE; case FILEMGMT_SHARE: // now has a property page
{ CString strServerName; CString strShareName; FILEMGMT_TRANSPORT transport; hr = ExtractString(pDataObject, CFileMgmtDataObject::m_CFMachineName, &strServerName, MAX_PATH);
if (SUCCEEDED(hr)) hr = ExtractString(pDataObject, CFileMgmtDataObject::m_CFShareName, &strShareName, MAX_PATH);
if (SUCCEEDED(hr)) hr = ExtractData(pDataObject, CFileMgmtDataObject::m_CFTransport, &transport, sizeof(DWORD));
if (SUCCEEDED(hr)) { CString strDescription; CString strPath; DWORD dwRet = GetFileServiceProvider(transport)->ReadShareProperties( strServerName, strShareName, NULL, // ppvPropertyBlock
strDescription, strPath, NULL, // pfEditDescription
NULL, // pfEditPath
NULL // pdwShareType
); if (NERR_Success == dwRet) { return S_OK; // yes, we have a property page to display
} else { DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, dwRet, IDS_POPUP_QUERY_SHARE, strShareName); if ((FILEMGMT_SMB == transport) && (NERR_NetNameNotFound == dwRet) || (FILEMGMT_SFM == transport) && (AFPERR_VolumeNonExist == dwRet)) { RefreshAllViews(pDataObject); } } }
return S_FALSE; } case FILEMGMT_SERVICE: ASSERT(CCT_SNAPIN_MANAGER != dataobjecttype); return S_OK; #ifdef SNAPIN_PROTOTYPER
case FILEMGMT_PROTOTYPER_LEAF: return S_OK; #endif
default: break; } ASSERT(FALSE); return S_FALSE;
MFC_CATCH; }
STDMETHODIMP CFileMgmtComponent::CreatePropertyPages( LPPROPERTYSHEETCALLBACK pCallBack, LONG_PTR handle, // This handle must be saved in the property page object to notify the parent when modified
LPDATAOBJECT pDataObject) { AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
if (NULL == pCallBack || NULL == pDataObject) { ASSERT(FALSE); return E_POINTER; } HRESULT hr; // extract data from data object
FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(pDataObject); DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE; hr = ExtractData( pDataObject, CFileMgmtDataObject::m_CFDataObjectType, &dataobjecttype, sizeof(dataobjecttype) ); ASSERT( SUCCEEDED(hr) ); ASSERT( CCT_SCOPE == dataobjecttype || CCT_RESULT == dataobjecttype || CCT_SNAPIN_MANAGER == dataobjecttype );
// determine if it needs property pages
switch (objecttype) { case FILEMGMT_SHARE: { CWaitCursor cwait;
if (CCT_SNAPIN_MANAGER == dataobjecttype) { ASSERT(FALSE); return E_UNEXPECTED; }
FILEMGMT_TRANSPORT transport; hr = ExtractData( pDataObject, CFileMgmtDataObject::m_CFTransport, &transport, sizeof(DWORD) ); if ( FAILED(hr) ) { ASSERT( FALSE ); return E_UNEXPECTED; }
// CODEWORK probably not necessary to split off transport at this point
GetFileServiceProvider(transport)->DisplayShareProperties(pCallBack, pDataObject, handle); return S_OK; } case FILEMGMT_SESSION: case FILEMGMT_RESOURCE: ASSERT(FALSE); return E_UNEXPECTED; case FILEMGMT_SERVICE: if (CCT_RESULT != dataobjecttype) { ASSERT(FALSE); return E_UNEXPECTED; }
if (!QueryComponentDataRef().Service_FInsertPropertyPages(OUT pCallBack, IN pDataObject, handle)) { // Unable to open the service and query service info
return S_FALSE; } return S_OK; default: break; } ASSERT(FALSE); return S_FALSE; }
STDMETHODIMP CFileMgmtComponent::Compare( LPARAM /*lUserParam*/, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int* pnResult) { ASSERT(NULL != pnResult); // WARNING cookie cast
CCookie* pBaseCookieA = reinterpret_cast<CCookie*>(cookieA); CCookie* pBaseCookieB = reinterpret_cast<CCookie*>(cookieB); ASSERT( NULL != pBaseCookieA && NULL != pBaseCookieB ); CFileMgmtCookie* pCookieA = QueryComponentDataRef().ActiveCookie( (CFileMgmtCookie*)pBaseCookieA); CFileMgmtCookie* pCookieB = QueryComponentDataRef().ActiveCookie( (CFileMgmtCookie*)pBaseCookieB); ASSERT( NULL != pCookieA && NULL != pCookieB ); FileMgmtObjectType objecttypeA = pCookieA->QueryObjectType(); FileMgmtObjectType objecttypeB = pCookieB->QueryObjectType(); ASSERT( IsValidObjectType(objecttypeA) && IsValidObjectType(objecttypeB) ); if (objecttypeA != objecttypeB) { // assign an arbitrary ordering to cookies with different nodetypes
*pnResult = ((int)objecttypeA) - ((int)objecttypeB); return S_OK; }
return pCookieA->CompareSimilarCookies( pBaseCookieB, pnResult); }
STDMETHODIMP CFileMgmtComponent::GetProperty( /* [in] */ LPDATAOBJECT pDataObject, /* [in] */ BSTR szPropertyName, /* [out] */ BSTR* pbstrProperty) { if ( IsBadReadPtr(pDataObject,sizeof(*pDataObject)) || IsBadStringPtr(szPropertyName,0x7FFFFFFF) || IsBadWritePtr(pbstrProperty,sizeof(*pbstrProperty)) ) { ASSERT(FALSE); return E_POINTER; }
CCookie* pbasecookie = NULL; HRESULT hr = ExtractBaseCookie( pDataObject, &pbasecookie ); RETURN_HR_IF_FAIL; ASSERT(NULL != pbasecookie); CFileMgmtCookie* pcookie = (CFileMgmtCookie*)pbasecookie;
CString strProperty; if (!_wcsicmp(L"CCF_HTML_DETAILS",szPropertyName)) { if (FILEMGMT_SERVICE != pcookie->QueryObjectType()) return S_FALSE;
if (NULL == QueryComponentDataRef().m_hScManager) { ASSERT(FALSE); return S_FALSE; }
CString strServiceName; if (!QueryComponentDataRef().Service_FGetServiceInfoFromIDataObject( pDataObject, NULL, OUT &strServiceName, NULL)) { ASSERT(FALSE); return S_FALSE; }
BOOL rgfMenuFlags[iServiceActionMax]; ::ZeroMemory(rgfMenuFlags,sizeof(rgfMenuFlags));
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // required for CWaitCursor
CWaitCursor wait; if (!Service_FGetServiceButtonStatus( // this will report errors itself
QueryComponentDataRef().m_hScManager, strServiceName, OUT rgfMenuFlags, NULL, // pdwCurrentState
TRUE)) // fSilentError
{ return S_FALSE; }
for (INT i = 0; i < iServiceActionMax; i++) { if (rgfMenuFlags[i]) { CString strTemp; VERIFY(strTemp.LoadString(IDS_HTML_DETAILS_START+i)); strProperty += strTemp; } } } else if (!_wcsicmp(L"CCF_DESCRIPTION",szPropertyName)) { hr = pcookie->GetExplorerViewDescription( strProperty ); } else { return S_FALSE; // unknown strPropertyName
}
*pbstrProperty = ::SysAllocString(strProperty);
return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_COLUMN_CLICK)
HRESULT CFileMgmtComponent::OnNotifyColumnClick( LPDATAOBJECT /*lpDataObject*/, LPARAM iColumn, LPARAM uFlags ) { m_iSortColumn = (int)iColumn; m_dwSortFlags = (DWORD) uFlags; return m_pResultData->Sort ((int)iColumn, (DWORD)uFlags, 0); }
HRESULT CFileMgmtComponent::OnNotifySnapinHelp (LPDATAOBJECT /*pDataObject*/) { return ShowHelpTopic( IsServiceSnapin() ? L"sys_srv_overview.htm" : L"file_srv_overview.htm" ); }
|