|
|
/*++
Copyright (c) 1994-1998 Microsoft Corporation
Module Name :
iisobj.cpp
Abstract:
IIS Objects
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "comprop.h"
#include "inetmgr.h"
#include "iisobj.h"
#include "machine.h"
#include <shlwapi.h>
#include "guids.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
//
// Static initialization
//
BOOL CIISObject::m_fIsExtension = FALSE; CString CIISObject::s_strProperties; CString CIISObject::s_strRunning; CString CIISObject::s_strPaused; CString CIISObject::s_strStopped; CString CIISObject::s_strUnknown; CString CIISObject::s_strYes; CString CIISObject::s_strNo; CString CIISObject::s_strTCPIP; CString CIISObject::s_strNetBIOS; CString CIISObject::s_strDefaultIP; CString CIISObject::s_strRedirect; time_t CIISObject::s_lExpirationTime = (5L * 60L); // 5 Minutes
LPCONSOLENAMESPACE CIISObject::s_lpcnsScopeView = NULL;
//
// Backup/restore taskpad gif resource
//
#define RES_TASKPAD_BACKUP _T("/img\\backup.gif")
LPCTSTR PrependParentPath( IN OUT CString & strPath, IN LPCTSTR lpszParent, IN TCHAR chSep ) /*++
Routine Description:
Helper function to prepend a new parent to the given path
Arguments:
CString & strPath : Current path LPCTSTR lpszParent : Parent to be prepended TCHAR chSep : Separator character
Return Value:
Pointer to the path
--*/ { if (strPath.IsEmpty()) { strPath = lpszParent; } else { CString strTail(strPath); strPath = lpszParent; strPath += chSep; strPath += strTail; }
TRACEEOLID("PrependParentPath: " << strPath);
return strPath; }
HRESULT ShellExecuteDirectory( IN LPCTSTR lpszCommand, IN LPCTSTR lpszOwner, IN LPCTSTR lpszDirectory ) /*++
Routine Description:
Shell Open or explore on a given directory path
Arguments:
LPCTSTR lpszCommand : "open" or "explore" LPCTSTR lpszOwner : Owner server LPCTSTR lpszDirectory : Directory path
Return Value:
Error return code.
--*/ { CString strDir;
if (::IsServerLocal(lpszOwner) || ::IsUNCName(lpszDirectory)) { //
// Local directory, or already a unc path
//
strDir = lpszDirectory; } else { ::MakeUNCPath(strDir, lpszOwner, lpszDirectory); }
TRACEEOLID("Attempting to " << lpszCommand << " Path: " << strDir);
CError err; { //
// AFX_MANAGE_STATE required for wait cursor
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState() ); CWaitCursor wait;
if (::ShellExecute( NULL, lpszCommand, strDir, NULL, _T(""), SW_SHOW ) <= (HINSTANCE)32) { err.GetLastWinError(); } }
return err; }
/* static */ void CIISObject::BuildResultView( IN LPHEADERCTRL pHeader, IN int cColumns, IN int * pnIDS, IN int * pnWidths ) /*++
Routine Description:
Build the result view columns
Routine Description:
LPHEADERCTRL pHeader : Header control int cColumns : Number of columns int * pnIDS : Array of column header strings int * pnWidths : Array of column widths
Routine Description:
None
--*/ { ASSERT(pHeader != NULL);
//
// Needed for loadstring
//
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString str;
for (int n = 0; n < cColumns; ++n) { VERIFY(str.LoadString(pnIDS[n])); pHeader->InsertColumn(n, str, LVCFMT_LEFT, pnWidths[n]); } }
/* static */ BOOL CIISObject::CanAddInstance( IN LPCTSTR lpszMachineName ) /*++
Routine Description:
Helper function to determine if instances may be added on this machine
Arguments:
LPCTSTR lpszMachineName : Machine name
Return Value:
TRUE if instances can be added
--*/ { //
// Assume W3svc and ftpsvc have the same capabilities.
//
CServerCapabilities * pcap; pcap = new CServerCapabilities(lpszMachineName, SZ_MBN_WEB);
if (!pcap) { return FALSE; }
if (FAILED(pcap->LoadData())) { //
// Try ftp
//
delete pcap; pcap = new CServerCapabilities(lpszMachineName, SZ_MBN_FTP); } if (!pcap || FAILED(pcap->LoadData())) { if (pcap) { delete pcap; }
return FALSE; }
BOOL fCanAdd = pcap->HasMultipleSites();
delete pcap;
return fCanAdd; }
BOOL CIISObject::IsScopeSelected() /*++
Routine Description:
Return TRUE if the scope is currently selected
Arguments:
None
Return Value:
TRUE if the item is currently selected, FALSE otherwise
--*/ { ASSERT(s_lpcnsScopeView != NULL);
HSCOPEITEM hItem = GetScopeHandle(); ASSERT(hItem != NULL);
if (hItem != NULL) { SCOPEDATAITEM item; ::ZeroMemory(&item, sizeof(SCOPEDATAITEM)); item.mask = SDI_STATE; item.nState = MMC_SCOPE_ITEM_STATE_EXPANDEDONCE; item.ID = hItem;
HRESULT hr = s_lpcnsScopeView->GetItem(&item);
if (SUCCEEDED(hr)) { return (item.nState & MMC_SCOPE_ITEM_STATE_EXPANDEDONCE) != 0; } }
return FALSE; }
void CIISObject::RefreshDisplayInfo() /*++
Routine Description:
Refresh the display info parameters in the scope view
Arguments:
None
Return Value:
None
--*/ { if (IsLeafNode()) { //
// Not supported on result items
//
return; }
ASSERT(s_lpcnsScopeView != NULL);
HSCOPEITEM hItem = GetScopeHandle(); ASSERT(hItem != NULL);
SCOPEDATAITEM item; ::ZeroMemory(&item, sizeof(SCOPEDATAITEM));
//
// Since we're using a callback, this is
// all we need to do here
//
item.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE; item.displayname = MMC_CALLBACK; item.nOpenImage = item.nImage = QueryBitmapIndex(); item.ID = hItem;
s_lpcnsScopeView->SetItem(&item); }
CIISObject::CIISObject( IN const GUID guid, IN LPCTSTR lpszNodeName, OPTIONAL IN LPCTSTR lpszPhysicalPath OPTIONAL ) /*++
Routine Description:
Constructor for CIISObject. Initialise static member functions if not yet initialized. This is a protected constructor of an abstract base class. Arguments:
const GUID guid : GUID of the object LPCTSTR lpszNodeName : Node name LPCTSTR lpszPhysicalPath : Physical path (or empty)
Return Value:
N/A
--*/ : m_hScopeItem(NULL), m_guid(guid), m_strNodeName(lpszNodeName), m_strPhysicalPath(lpszPhysicalPath), m_strRedirPath(), m_fChildOnlyRedir(FALSE), m_fIsParentScope(FALSE), m_tmChildrenExpanded(0L) { //
// Initialize static members
//
if (CIISObject::s_strRunning.IsEmpty()) { //
// AFX_MANAGE_STATE required for resource load
//
AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACEEOLID("Initializing static strings");
VERIFY(CIISObject::s_strRunning.LoadString(IDS_RUNNING)); VERIFY(CIISObject::s_strPaused.LoadString(IDS_PAUSED)); VERIFY(CIISObject::s_strStopped.LoadString(IDS_STOPPED)); VERIFY(CIISObject::s_strUnknown.LoadString(IDS_UNKNOWN)); VERIFY(CIISObject::s_strProperties.LoadString(IDS_MENU_PROPERTIES)); VERIFY(CIISObject::s_strYes.LoadString(IDS_YES)); VERIFY(CIISObject::s_strNo.LoadString(IDS_NO)); VERIFY(CIISObject::s_strTCPIP.LoadString(IDS_TCPIP)); VERIFY(CIISObject::s_strNetBIOS.LoadString(IDS_NETBIOS)); VERIFY(CIISObject::s_strDefaultIP.LoadString(IDS_DEFAULT_IP)); VERIFY(CIISObject::s_strRedirect.LoadString(IDS_REDIRECTED)); } }
BOOL CIISObject::IsValidObject() const { // CIISObject could have only one of the following GUIDs
GUID guid = QueryGUID(); if ( guid == cInternetRootNode || guid == cMachineNode || guid == cServiceCollectorNode || guid == cInstanceCollectorNode || guid == cInstanceNode || guid == cChildNode || guid == cFileNode ) return TRUE; return FALSE; }
CIISObject::operator LPCTSTR() /*++
Routine Description:
Typecast operator to call out the display text Arguments:
N/A
Return Value:
Display text
--*/ { static CString strText;
return GetDisplayText(strText); }
//
// Separator menu item definition
//
CONTEXTMENUITEM menuSep = { NULL, NULL, -1, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, CCM_SPECIAL_SEPARATOR };
//
// Menu item definition that uses resource definitions, and
// provides some additional information for taskpads.
//
typedef struct tagCONTEXTMENUITEM_RC { UINT nNameID; UINT nStatusID; UINT nDescriptionID; LONG lCmdID; LONG lInsertionPointID; LONG fSpecialFlags; LPCTSTR lpszMouseOverBitmap; LPCTSTR lpszMouseOffBitmap; } CONTEXTMENUITEM_RC;
//
// Important! The array indices below must ALWAYS be one
// less than the menu ID -- keep in sync with enumeration
// in inetmgr.h!!!!
//
static CONTEXTMENUITEM_RC menuItemDefs[] = { //
// Menu Commands in toolbar order
//
{ IDS_MENU_CONNECT, IDS_MENU_TT_CONNECT, -1, IDM_CONNECT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_DISCOVER, IDS_MENU_TT_DISCOVER, -1, IDM_DISCOVER, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_START, IDS_MENU_TT_START, -1, IDM_START, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_STOP, IDS_MENU_TT_STOP, -1, IDM_STOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_PAUSE, IDS_MENU_TT_PAUSE, -1, IDM_PAUSE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, //
// These are menu commands that do not show up in the toolbar
//
{ IDS_MENU_EXPLORE, IDS_MENU_TT_EXPLORE, -1, IDM_EXPLORE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_OPEN, IDS_MENU_TT_OPEN, -1, IDM_OPEN, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_BROWSE, IDS_MENU_TT_BROWSE, -1, IDM_BROWSE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_PROPERTIES, IDS_MENU_TT_PROPERTIES, -1, IDM_CONFIGURE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_DISCONNECT, IDS_MENU_TT_DISCONNECT, -1, IDM_DISCONNECT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_BACKUP, IDS_MENU_TT_BACKUP, IDS_MENU_TT_BACKUP, IDM_METABACKREST, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_SHUTDOWN_IIS, IDS_MENU_TT_SHUTDOWN_IIS, -1, IDM_SHUTDOWN, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, }, { IDS_MENU_NEWVROOT, IDS_MENU_TT_NEWVROOT, IDS_MENU_DS_NEWVROOT, IDM_NEW_VROOT, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWVROOT, RES_TASKPAD_NEWVROOT, }, { IDS_MENU_NEWINSTANCE, IDS_MENU_TT_NEWINSTANCE, IDS_MENU_DS_NEWINSTANCE, IDM_NEW_INSTANCE, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, }, { IDS_MENU_TASKPAD, IDS_MENU_TT_TASKPAD, -1, IDM_VIEW_TASKPAD, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, NULL, NULL, }, { IDS_MENU_SECURITY_WIZARD, IDS_MENU_TT_SECURITY_WIZARD, IDS_MENU_TT_SECURITY_WIZARD, IDM_TASK_SECURITY_WIZARD, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, RES_TASKPAD_SECWIZ, RES_TASKPAD_SECWIZ, }, };
/* static */ HRESULT CIISObject::AddMenuItemByCommand( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback, IN LONG lCmdID,
IN LONG fFlags ) /*++
Routine Description:
Add menu item by command
Arguments:
LPCONTEXTMENUCALLBACK lpContextMenuCallback : Callback pointer LONG lCmdID : Command ID LONG fFlags : Flags Return Value:
HRESULT
--*/ { ASSERT(lpContextMenuCallback != NULL);
//
// Offset 1 menu commands
//
LONG l = lCmdID -1;
CString strName; CString strStatus;
{ //
// AFX_MANAGE_STATE required for resource load
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); VERIFY(strName.LoadString(menuItemDefs[l].nNameID)); VERIFY(strStatus.LoadString(menuItemDefs[l].nStatusID)); }
CONTEXTMENUITEM cmi; cmi.strName = strName.GetBuffer(0); cmi.strStatusBarText = strStatus.GetBuffer(0); cmi.lCommandID = menuItemDefs[l].lCmdID; cmi.lInsertionPointID = menuItemDefs[l].lInsertionPointID; cmi.fFlags = fFlags; cmi.fSpecialFlags = menuItemDefs[l].fSpecialFlags;
return lpContextMenuCallback->AddItem(&cmi); }
/* static */ HRESULT CIISObject::AddTaskpadItemByInfo( OUT MMC_TASK * pTask, IN LONG lCommandID, IN LPCTSTR lpszMouseOn, IN LPCTSTR lpszMouseOff, IN LPCTSTR lpszText, IN LPCTSTR lpszHelpString ) /*++
Routine Description:
Add taskpad item from the information given
Arguments:
MMC_TASK * pTask : Task info LPCTSTR lpszMouseOn : Mouse on URL LPCTSTR lpszMouseOff : Mouse off URL LPCTSTR lpszText : Text to be displayed LPCTSTR lpszHelpString : Help string
Return Value:
HRESULT
--*/ { TRACEEOLID(lpszMouseOn); TRACEEOLID(lpszMouseOff);
pTask->sDisplayObject.eDisplayType = MMC_TASK_DISPLAY_TYPE_VANILLA_GIF;
pTask->sDisplayObject.uBitmap.szMouseOverBitmap = CoTaskDupString((LPCOLESTR)lpszMouseOn); pTask->sDisplayObject.uBitmap.szMouseOffBitmap = CoTaskDupString((LPCOLESTR)lpszMouseOff); pTask->szText = CoTaskDupString((LPCOLESTR)lpszText); pTask->szHelpString = CoTaskDupString((LPCOLESTR)lpszHelpString);
if (pTask->sDisplayObject.uBitmap.szMouseOverBitmap && pTask->sDisplayObject.uBitmap.szMouseOffBitmap && pTask->szText && pTask->szHelpString ) { //
// Add action
//
pTask->eActionType = MMC_ACTION_ID; pTask->nCommandID = lCommandID;
return S_OK; }
//
// Failed
//
CoTaskStringFree(pTask->sDisplayObject.uBitmap.szMouseOverBitmap); CoTaskStringFree(pTask->sDisplayObject.uBitmap.szMouseOffBitmap); CoTaskStringFree(pTask->szText); CoTaskStringFree(pTask->szHelpString);
return S_FALSE; }
/* static */ HRESULT CIISObject::AddTaskpadItemByCommand( IN LONG lCmdID, OUT MMC_TASK * pTask, IN HINSTANCE hInstance OPTIONAL ) /*++
Routine Description:
Add taskpad item by command
Arguments:
LONG lCmdID : Command ID CString & strResURL : Resource ID MMC_TASK * pTask : Task structure to be filled in
Return Value:
HRESULT
--*/ { ASSERT(pTask != NULL);
//
// Offset 1 menu commands
//
LONG l = lCmdID -1;
CString strName; CString strStatus;
CString strResURL; HRESULT hr = BuildResURL(strResURL, hInstance);
if (FAILED(hr)) { return hr; }
{ //
// AFX_MANAGE_STATE required for resource load
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); VERIFY(strName.LoadString(menuItemDefs[l].nStatusID)); VERIFY(strStatus.LoadString(menuItemDefs[l].nDescriptionID)); }
//
// Make sure this menu command was intended to go onto a taskpad
//
ASSERT(menuItemDefs[l].lpszMouseOverBitmap != NULL); ASSERT(menuItemDefs[l].lpszMouseOffBitmap != NULL);
//
// Fill out bitmap URL (use defaults if nothing provided)
//
CString strMouseOn(strResURL); CString strMouseOff(strResURL);
strMouseOn += menuItemDefs[l].lpszMouseOverBitmap; strMouseOff += menuItemDefs[l].lpszMouseOffBitmap;
return AddTaskpadItemByInfo( pTask, menuItemDefs[l].lCmdID, strMouseOn, strMouseOff, strName, strStatus ); }
/* virtual */ HRESULT CIISObject::AddMenuItems( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback ) /*++
Routine Description:
Add menu items to the context that are valid for this object
Arguments:
LPCONTEXTMENUCALLBACK lpContextMenuCallback : Callback
Return Value:
HRESULT
--*/ { if (IsConnectable() && !m_fIsExtension) { AddMenuItemByCommand(lpContextMenuCallback, IDM_CONNECT); AddMenuItemByCommand(lpContextMenuCallback, IDM_DISCONNECT); }
if (IsExplorable()) { lpContextMenuCallback->AddItem(&menuSep); AddMenuItemByCommand(lpContextMenuCallback, IDM_EXPLORE); } if (IsOpenable()) { AddMenuItemByCommand(lpContextMenuCallback, IDM_OPEN); }
if (IsBrowsable()) { AddMenuItemByCommand(lpContextMenuCallback, IDM_BROWSE); }
if (IsControllable()) { lpContextMenuCallback->AddItem(&menuSep);
UINT nPauseFlags = IsPausable() ? 0 : MF_GRAYED;
if (IsPaused()) { nPauseFlags |= MF_CHECKED; }
AddMenuItemByCommand(lpContextMenuCallback, IDM_START, IsStartable() ? 0 : MF_GRAYED); AddMenuItemByCommand(lpContextMenuCallback, IDM_STOP, IsStoppable() ? 0 : MF_GRAYED); AddMenuItemByCommand(lpContextMenuCallback, IDM_PAUSE, nPauseFlags); }
#ifdef MMC_PAGES
//
// Bring up private config menu item only if not
// configurable through MMC
//
if (IsConfigurable() && !IsMMCConfigurable()) { lpContextMenuCallback->AddItem(&menuSep); AddMenuItemByCommand(lpContextMenuCallback, IDM_CONFIGURE); }
#else
if (IsConfigurable()) { lpContextMenuCallback->AddItem(&menuSep); AddMenuItemByCommand(lpContextMenuCallback, IDM_CONFIGURE); }
#endif // MMC_PAGES
return S_OK; }
/* virtual */ HRESULT CIISObject::AddNextTaskpadItem( OUT MMC_TASK * pTask ) /*++
Routine Description:
Add next taskpad item
Arguments:
MMC_TASK * pTask : Task structure to fill in
Return Value:
HRESULT
--*/ { //
// CODEWORK: Because of enumeration, this isn't easy
// to handle the way menu items are handled
//
ASSERT(FALSE);
return S_FALSE; }
/* virtual */ CIISObject * CIISObject::GetParentObject() const /*++
Routine Description:
Get the parent object (in the scope view) of this object.
Arguments:
None
Return Value:
Pointer to the parent object, or NULL if not found
--*/ { MMC_COOKIE cookie; HSCOPEITEM hParent;
HRESULT hr = GetScopeView()->GetParentItem( GetScopeHandle(), &hParent, &cookie );
if (hParent == NULL || cookie == 0L || FAILED(hr)) { //
// None found
//
return NULL; }
return (CIISObject *)cookie; }
LPCTSTR CIISObject::BuildParentPath( OUT CString & strParent, IN BOOL fMetabasePath ) const /*++
Routine Description:
Walk up the parent nodes to build either a metabase path, or a physical path to the parent of this node.
Arguments:
CString & strParent : Returns the parent path BOOL fMetabasePath : If TRUE want full metabse path If FALSE, relative path from the instance only
Return Value:
Pointer to the path
--*/ { const CIISObject * pObject = this;
//
// Walk up the tree to build a proper parent path
//
for (;;) { if (pObject->IsTerminalPoint(fMetabasePath)) { break; }
pObject = pObject->GetParentObject();
if (pObject == NULL) { //
// Should have stopped before this.
//
ASSERT(FALSE); break; }
PrependParentPath( strParent, pObject->QueryNodeName(fMetabasePath), g_chSep );
//
// Keep looking
//
}
TRACEEOLID("BuildParentPath: " << strParent); return strParent; }
LPCTSTR CIISObject::BuildFullPath( OUT CString & strPath, IN BOOL fMetabasePath ) const /*++
Routine Description:
Build complete path for the current object. Either a metabase path or a directory path.
Arguments:
Return Value:
Pointer to the path
--*/ { strPath = QueryNodeName(fMetabasePath); BuildParentPath(strPath, fMetabasePath); TRACEEOLID("CIISObject::BuildFullPath:" << strPath);
return strPath; }
LPCTSTR CIISObject::BuildPhysicalPath( OUT CString & strPhysicalPath ) const /*++
Routine Description:
Build a physical path for the current node. Starting with the current node, walk up the tree appending node names until a virtual directory with a real physical path is found
Arguments:
CString & strPhysicalPath : Returns file path
Return Value:
Pointer to path
--*/ { const CIISObject * pObject = this;
//
// Walk up the tree to build a physical path
//
for (;;) { if (pObject->IsVirtualDirectory()) { //
// Path is properly terminated here
//
PrependParentPath( strPhysicalPath, pObject->QueryPhysicalPath(), _T('\\') ); break; }
PrependParentPath( strPhysicalPath, pObject->QueryNodeName(), _T('\\') );
pObject = pObject->GetParentObject();
if (pObject == NULL) { //
// Should have stopped before this.
//
ASSERT(FALSE); break; }
//
// Keep looking
//
}
TRACEEOLID("BuildPhysicalPath: " << strPhysicalPath); return strPhysicalPath; }
DWORD CIISObject::QueryInstanceID() /*++
Routine Description:
Return the ID of the owner instance
Arguments:
None
Return Value:
Owner instance ID or 0xffffffff
--*/ { CIISInstance * pInstance = FindOwnerInstance(); return pInstance ? pInstance->QueryID() : 0xffffffff; }
HRESULT CIISObject::Open() /*++
Routine Description:
Open the physical path of the current node in the explorer
Arguments:
None
Return Value:
Error return code
--*/ { CString strPath; BuildPhysicalPath(strPath);
return ShellExecuteDirectory(_T("open"), GetMachineName(), strPath); }
HRESULT CIISObject::Explore() /*++
Routine Description:
"explore" the physical path of the current node
Arguments:
None
Return Value:
Error return code
--*/ { CString strPath; BuildPhysicalPath(strPath);
return ShellExecuteDirectory(_T("explore"), GetMachineName(), strPath); }
HRESULT CIISObject::Browse() /*++
Routine Description:
Bring up the current path in the browser.
Arguments:
None
Return Value:
Error return code
--*/ { CString strPath;
BuildFullPath(strPath, FALSE);
CIISInstance * pInstance = FindOwnerInstance();
if (pInstance == NULL) { ASSERT(FALSE);
return CError::HResult(ERROR_INVALID_PARAMETER); }
return pInstance->ShellBrowsePath(strPath); }
//
// Machine pages
//
CObListPlus * CIISMachine::s_poblNewInstanceCmds = NULL; CString CIISMachine::s_strLocalMachine;
//
// Define result view for machine objects
//
int CIISMachine::rgnLabels[COL_TOTAL] = { IDS_RESULT_COMPUTER_NAME, IDS_RESULT_COMPUTER_LOCAL, IDS_RESULT_COMPUTER_CONNECTION_TYPE, IDS_RESULT_STATUS, };
int CIISMachine::rgnWidths[COL_TOTAL] = { 200, 50, 100, 200, };
/* static */ void CIISMachine::InitializeHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result view headers for a machine object
Arguments:
LPHEADERCTRL pHeader : Pointer to header control
Return Value:
None.
--*/ { CIISObject::BuildResultView(pHeader, COL_TOTAL, rgnLabels, rgnWidths); }
CIISMachine::CIISMachine( IN LPCTSTR lpszMachineName ) /*++
Routine Description:
Constructor for machine object Arguments:
LPCTSTR lpszMachineName : Machine name
Return Value:
N/A
--*/ : CIISObject(cMachineNode), m_strMachineName(lpszMachineName), m_fLocal(::IsServerLocal(lpszMachineName)) { ASSERT(lpszMachineName != NULL);
VERIFY(m_strDisplayName.LoadString(IDS_NODENAME));
//
// Initialize static members
//
if (CIISMachine::s_strLocalMachine.IsEmpty()) { //
// AFX_MANAGE_STATE required for resource load
//
AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACEEOLID("Initializing static strings"); VERIFY(CIISMachine::s_strLocalMachine.LoadString(IDS_LOCAL_COMPUTER)); } // Determine if current user is administrator
CMetaKey key(lpszMachineName); if (key.Succeeded()) { DWORD err = DetermineIfAdministrator( &key, _T("w3svc"), 0, &m_fIsAdministrator); if (err != ERROR_SUCCESS) { err = DetermineIfAdministrator( &key, _T("msftpsvc"), 0, &m_fIsAdministrator); } } }
/* virtual */ BOOL CIISMachine::IsConfigurable() const /*++
Routine Description:
Determine if the machine is configurable, that is at least one property page handler was registered for it. Arguments:
None
Return Value:
TRUE if the machine is configurable, FALSE otherwise
--*/ { //
// Codework: do a metabase check here
//
return m_fIsAdministrator; //return CIISMachine::s_poblISMMachinePages != NULL
// && CIISMachine::s_poblISMMachinePages->GetCount() > 0;
}
/* virtual */ HRESULT CIISMachine::Configure( IN CWnd * pParent OPTIONAL ) /*++
Routine Description:
Configure the machine object. In order for the machine object to be configurable, at least one property page add-on function must be defined. Arguments:
CWnd * pParent : Parent window handle
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
CError err;
/*
try { CString strTitle, str; VERIFY(str.LoadString(IDS_MACHINE_PROPERTIES));
strTitle.Format(str, GetMachineName());
PROPSHEETHEADER psh; psh.dwSize = sizeof(psh); psh.dwFlags = PSH_DEFAULT | PSH_HASHELP; psh.hwndParent = pParent ? pParent->m_hWnd : NULL; psh.hInstance = NULL; psh.pszIcon = NULL; psh.pszCaption = (LPTSTR)(LPCTSTR)strTitle; psh.nStartPage = 0; psh.nPages = 0; psh.phpage = NULL; psh.pfnCallback = NULL;
ASSERT(CIISMachine::s_poblISMMachinePages != NULL); CObListIter obli(*CIISMachine::s_poblISMMachinePages); CISMMachinePageExt * pipe; while (pipe = (CISMMachinePageExt *)obli.Next()) { DWORD errDLL = pipe->Load(); if (errDLL == ERROR_SUCCESS) { errDLL = pipe->AddPages(GetMachineName(), &psh); }
if (errDLL != ERROR_SUCCESS) { //
// Unable to load, display error message
// with the name of the DLL. This does not
// necessarily pose problems for the rest
// of the property sheet.
//
::DisplayFmtMessage( IDS_ERR_NO_LOAD, MB_OK, 0, (LPCTSTR)*pipe, ::GetSystemMessage(errDLL) ); } }
if (psh.nPages > 0) { //
// Display the property sheet
//
PropertySheet(&psh);
//
// Now clean up the property sheet structure
//
// FreeMem(psh.phpage);
}
//
// Unload the extentions
//
obli.Reset(); while (pipe = (CISMMachinePageExt *)obli.Next()) { if ((HINSTANCE)*pipe) { VERIFY(pipe->UnLoad()); } } } catch(CMemoryException * e) { err = ERROR_NOT_ENOUGH_MEMORY; e->Delete(); } */
return err; }
/* virtual */ HRESULT CIISMachine::ConfigureMMC( IN LPPROPERTYSHEETCALLBACK lpProvider, IN LPARAM param, IN LONG_PTR handle ) /*++
Routine Description:
Configure using MMC property sheets
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Prop sheet provider LPARAM param : Prop parameter LONG_PTR handle : console handle
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HINSTANCE hOld = AfxGetResourceHandle(); AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME));
HINSTANCE hInstance = AfxGetInstanceHandle(); CIISMachinePage * ppgMachine = new CIISMachinePage( GetMachineName(), hInstance );
AfxSetResourceHandle(hOld);
if (ppgMachine) { CError err(ppgMachine->QueryResult());
if (err.Failed()) { if (err == REGDB_E_CLASSNOTREG) { //
// There isn't a metabase -- fail gracefully
//
::AfxMessageBox(IDS_NO_MACHINE_PROPS); err.Reset(); }
delete ppgMachine;
return err; }
//
// Patch MFC property page class.
//
ppgMachine->m_psp.dwFlags |= PSP_HASHELP; MMCPropPageCallback(&ppgMachine->m_psp);
HPROPSHEETPAGE hPage = CreatePropertySheetPage( (LPCPROPSHEETPAGE)&ppgMachine->m_psp );
if (hPage != NULL) { lpProvider->AddPage(hPage);
return ERROR_SUCCESS; } }
return ERROR_NOT_ENOUGH_MEMORY; }
/* virtual */ HRESULT CIISMachine::AddMenuItems( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback ) /*++
Routine Description:
Add menu items for machine object
Arguments:
LPCONTEXTMENUCALLBACK pContextMenuCallback : Context menu items callback
Return Value:
HRESULT
--*/ { CIISObject::AddMenuItems(lpContextMenuCallback);
//
// Add metabase backup/restore
//
lpContextMenuCallback->AddItem(&menuSep); AddMenuItemByCommand(lpContextMenuCallback, IDM_METABACKREST);
//
// Add 'IIS shutdown' command
//
// ISSUE: Should there be a capability bit?
//
AddMenuItemByCommand(lpContextMenuCallback, IDM_SHUTDOWN);
if (!CanAddInstance(GetMachineName())) { return FALSE; }
//
// Add one 'new instance' for every service that supports
// instances
//
ASSERT(CIISMachine::s_poblNewInstanceCmds);
POSITION pos = CIISMachine::s_poblNewInstanceCmds->GetHeadPosition();
int lCommandID = IDM_NEW_EX_INSTANCE; HRESULT hr;
while(pos) { CNewInstanceCmd * pcmd = (CNewInstanceCmd *)s_poblNewInstanceCmds->GetNext(pos); ASSERT(pcmd != NULL);
CONTEXTMENUITEM cmi; cmi.strName = pcmd->GetMenuCommand().GetBuffer(0); cmi.strStatusBarText = pcmd->GetTTText().GetBuffer(0); cmi.lCommandID = lCommandID++; cmi.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_NEW; cmi.fFlags = 0; cmi.fSpecialFlags = 0;
hr = lpContextMenuCallback->AddItem(&cmi); ASSERT(SUCCEEDED(hr)); }
return S_OK; }
/* virtual */ HRESULT CIISMachine::AddNextTaskpadItem( OUT MMC_TASK * pTask ) /*++
Routine Description:
Add next taskpad item
Arguments:
MMC_TASK * pTask : Task structure to fill in
Return Value:
HRESULT
--*/ { //
// Add one 'new instance' for every service that supports
// instances
//
ASSERT(CIISMachine::s_poblNewInstanceCmds);
static POSITION pos = NULL; static BOOL fShownBackup = FALSE; static int lCommandID = -1;
HRESULT hr;
CString strName, strStatus, strMouseOn, strMouseOff; long lCmdID;
//
// Metabase backup/restore
//
if (!fShownBackup) { //
// AFX_MANAGE_STATE required for resource load
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CString strResURL; hr = BuildResURL(strResURL);
if (FAILED(hr)) { return hr; } VERIFY(strName.LoadString(IDS_MENU_BACKUP)); VERIFY(strStatus.LoadString(IDS_MENU_TT_BACKUP));
strMouseOn = strResURL + RES_TASKPAD_BACKUP; strMouseOff = strMouseOn; lCmdID = IDM_METABACKREST;
++fShownBackup; } else { //
// Display the new instance commands for each service that
// supports it.
//
if (lCommandID == -1) { //
// Initialize (use lCommandID == -1 as a flag
// to indicate we're at the beginning of the list)
//
if (CanAddInstance(GetMachineName())) { pos = CIISMachine::s_poblNewInstanceCmds->GetHeadPosition(); lCommandID = IDM_NEW_EX_INSTANCE; } else { return S_FALSE; } }
if (pos == NULL) { //
// No more items remain in the list.
//
lCommandID = -1; fShownBackup = FALSE;
return S_FALSE; }
CNewInstanceCmd * pcmd = (CNewInstanceCmd *)s_poblNewInstanceCmds->GetNext(pos); ASSERT(pcmd != NULL);
CString strResURL; hr = BuildResURL(strResURL, pcmd->QueryInstanceHandle());
if (FAILED(hr)) { return hr; }
//
// AFX_MANAGE_STATE required for resource load
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); VERIFY(strStatus.LoadString(IDS_MENU_DS_NEWINSTANCE));
strMouseOn = strResURL + RES_TASKPAD_NEWSITE; strMouseOff = strMouseOn; strName = pcmd->GetTTText();
lCmdID = lCommandID++; }
return AddTaskpadItemByInfo( pTask, lCmdID, strMouseOn, strMouseOff, strName, strStatus ); }
/* virtual */ LPCTSTR CIISMachine::GetDisplayText( OUT CString & strText ) const /*++
Routine Description:
Get the display text of this object Arguments:
CString & strText : String in which display text is to be returned
Return Value:
Pointer to the string
--*/ { try { if (m_fIsExtension) { //
// This is an extension
//
strText = m_strDisplayName; } else { if (IsLocalMachine()) { ASSERT(!s_strLocalMachine.IsEmpty()); strText.Format(s_strLocalMachine, m_strMachineName); } else { strText = m_strMachineName; } } } catch(CMemoryException * e) { TRACEEOLID("!!!exception in GetDisplayText"); e->ReportError(); e->Delete(); }
return strText; }
/* virtual */ int CIISMachine::QueryBitmapIndex() const /*++
Routine Description:
Determine the bitmap index that represents the current item
Arguments:
None
Return Value:
Index into the bitmap strip
--*/ { if (m_fIsExtension) { return BMP_INETMGR; }
return IsLocalMachine() ? BMP_LOCAL_COMPUTER : BMP_COMPUTER; }
/* virtual */ void CIISMachine::GetResultDisplayInfo( IN int nCol, OUT CString & str, OUT int & nImage ) const /*++
Routine Description:
Get result data item display information.
Arguments:
int nCol : Column number CString & str : String data int & nImage : Image number
Return Value:
None
--*/ { //
// Need different icon for extension...
//
nImage = QueryBitmapIndex();
str.Empty();
switch(nCol) { case COL_NAME: // Computer Name
GetDisplayText(str); break;
case COL_LOCAL: // Local
if (m_fIsExtension) { //
// If we're an extension, display the type
//
AFX_MANAGE_STATE(AfxGetStaticModuleState()); VERIFY(str.LoadString(IDS_SNAPIN_TYPE)); } else { //
//
str = IsLocalMachine() ? CIISObject::s_strYes : CIISObject::s_strNo; } break;
case COL_TYPE: // Connection Type
if (m_fIsExtension) { //
// If we're an extension snap-in we should display
// the snap-in description in this column
//
AFX_MANAGE_STATE(AfxGetStaticModuleState()); VERIFY(str.LoadString(IDS_SNAPIN_DESC)); } else { str = IS_NETBIOS_NAME(GetMachineName()) ? CIISObject::s_strNetBIOS : CIISObject::s_strTCPIP; } break;
case COL_STATUS: break;
default: //
// No other columns current supported
//
ASSERT(FALSE); } }
int CIISMachine::Compare( IN int nCol, IN CIISObject * pObject ) /*++
Routine Description:
Compare against another CIISObject
Arguments:
int nCol : Compare on this column CIISObject * pObject : Compare against this object
Routine Description:
Comparison Return Value
--*/ { ASSERT(QueryGUID() == pObject->QueryGUID()); if (QueryGUID() != pObject->QueryGUID()) { //
// Invalid comparison
//
return +1; }
CString str1, str2; int n1, n2;
CIISMachine * pMachine = (CIISMachine *)pObject;
switch(nCol) { case COL_NAME: // Computer Name
GetDisplayText(str1); pMachine->GetDisplayText(str2); return str1.CompareNoCase(str2);
case COL_LOCAL: // Local
n1 = IsLocalMachine(); n2 = pMachine->IsLocalMachine(); return n1 - n2;
case COL_TYPE: // Connection Type
n1 = IS_NETBIOS_NAME(GetMachineName()); n2 = IS_NETBIOS_NAME(pMachine->GetMachineName()); return n1 - n2;
case COL_STATUS: return 0;
default: //
// No other columns current supported
//
ASSERT(FALSE); }
return -1; }
void CIISMachine::InitializeChildHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Build result view underneath
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { CIISInstance::InitializeHeaders(pHeader); }
//
// Static Initialization
//
CString CIISInstance::s_strFormatState; BOOL CIISInstance::s_fServerView = TRUE; BOOL CIISInstance::s_fAppendState = TRUE;
//
// Instance Result View definition
//
int CIISInstance::rgnLabels[COL_TOTAL] = { IDS_RESULT_SERVICE_DESCRIPTION, IDS_RESULT_SERVICE_STATE, IDS_RESULT_SERVICE_DOMAIN_NAME, IDS_RESULT_SERVICE_IP_ADDRESS, IDS_RESULT_SERVICE_TCP_PORT, IDS_RESULT_STATUS, };
int CIISInstance::rgnWidths[COL_TOTAL] = { 180, 70, 120, 105, 40, 200, };
/* static */ void CIISInstance::InitializeStrings() /*++
Routine Description:
Static method to initialize the strings. Arguments:
None
Return Value:
None
--*/ { if (!IsInitialized()) { TRACEEOLID("Initializing static strings");
//
// iisui.dll is an extension DLL, and this should
// load automatically, but doesn't -- why?
//
HINSTANCE hOld = AfxGetResourceHandle(); AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME)); VERIFY(CIISInstance::s_strFormatState.LoadString(IDS_INSTANCE_STATE_FMT)); AfxSetResourceHandle(hOld); } }
/* static */ void CIISInstance::InitializeHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result headers
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { CIISObject::BuildResultView(pHeader, COL_TOTAL, rgnLabels, rgnWidths); }
CIISInstance::CIISInstance( IN CServerInfo * pServerInfo ) /*++
Routine Description:
Constructor for instance object without instance ID code. In other words, this is a wrapper for a plain-old down-level CServerInfo object. Arguments:
CServerInfo * pServerInfo : Controlling server info
Return Value:
N/A
--*/ : CIISObject(cInstanceNode), m_fDownLevel(TRUE), m_fDeletable(FALSE), m_fClusterEnabled(FALSE), m_fLocalMachine(FALSE), m_hrError(S_OK), m_sPort(0), m_dwIPAddress(0L), m_strHostHeaderName(), m_strComment(), m_strMachine(), m_pServerInfo(pServerInfo) { if (!IsInitialized()) { CIISInstance::InitializeStrings(); }
//
// Some service types do not support instances, but
// still understand the instance codes
//
ASSERT(m_pServerInfo != NULL); m_dwID = 0L; m_strMachine = m_pServerInfo->QueryServerName(); m_fLocalMachine = ::IsServerLocal(m_strMachine); }
CIISInstance::CIISInstance( IN ISMINSTANCEINFO * pii, IN CServerInfo * pServerInfo ) /*++
Routine Description:
Initialize IIS Instance from ISMINSTANCEINFO structure
Arguments:
ISMINSTANCEINFO * pii : Pointer to ISMINSTANCEINFO structure CServerInfo * pServerInfo : Server info structure
Return Value:
N/A
--*/ : CIISObject(cInstanceNode), m_fDownLevel(FALSE), m_fLocalMachine(), m_strMachine(), m_pServerInfo(pServerInfo) { InitializeFromStruct(pii);
if (!IsInitialized()) { CIISInstance::InitializeStrings(); }
ASSERT(m_pServerInfo != NULL); m_strMachine = m_pServerInfo->QueryServerName(); m_fLocalMachine = ::IsServerLocal(m_strMachine); }
void CIISInstance::InitializeFromStruct( IN ISMINSTANCEINFO * pii ) /*++
Routine Description:
Initialize data from ISMINSTANCEINFO structure
Arguments:
ISMINSTANCEINFO * pii : Pointer to ISMINSTANCEINFO structure
Return Value:
None.
--*/ { ASSERT(pii);
m_dwID = pii->dwID; m_strHostHeaderName = pii->szServerName; m_strComment = pii->szComment; m_nState = pii->nState; m_dwIPAddress = pii->dwIPAddress; m_sPort = pii->sPort; m_fDeletable = pii->fDeletable; m_fClusterEnabled = pii->fClusterEnabled; CError err(pii->dwError); m_hrError = err;
m_strRedirPath = pii->szRedirPath; m_fChildOnlyRedir = pii->fChildOnlyRedir;
//
// Home directory path should exist unless someone's been
// messing up the metabase.
//
m_strPhysicalPath = pii->szPath;
m_strNodeName.Format(_T("%s%c%s%c%ld%c%s"), g_cszMachine, g_chSep, GetServerInfo()->GetMetabaseName(), g_chSep, m_dwID, g_chSep, g_cszRoot );
TRACEEOLID(m_strNodeName); }
/* virtual */ BOOL CIISInstance::IsRunning() const /*++
Routine Description:
Check to see if this instance is currently running.
Arguments:
None.
Return Value:
TRUE if currently running
Notes:
On a down-level (v3) version, this applies to the service, not the instance
--*/ { if (IsDownLevel()) { ASSERT(m_pServerInfo != NULL); return m_pServerInfo->IsServiceRunning(); }
return m_nState == INetServiceRunning; }
/* virtual */ BOOL CIISInstance::IsStopped() const /*++
Routine Description:
Check to see if this instance is currently stopped.
Arguments:
None.
Return Value:
TRUE if currently stopped
Notes:
On a down-level (v3) version, this applies to the server, not the instance
--*/ { if (IsDownLevel()) { ASSERT(m_pServerInfo != NULL); return m_pServerInfo->IsServiceStopped(); }
return m_nState == INetServiceStopped; }
/* virtual */ BOOL CIISInstance::IsPaused() const /*++
Routine Description:
Check to see if this instance is currently paused.
Arguments:
None.
Return Value:
TRUE if currently paused
Notes:
On a down-level (v3) version, this applies to the server, not the instance
--*/ { if (IsDownLevel()) { ASSERT(m_pServerInfo != NULL);
return m_pServerInfo->IsServicePaused(); }
return m_nState == INetServicePaused; }
/* virtual */ int CIISInstance::QueryState() const /*++
Routine Description:
Get the ISM state of the instance
Arguments:
None.
Return Value:
The ISM (INet*) state of the instance
Notes:
On a down-level (v3) version, this applies to the server, not the instance
--*/ { if (IsDownLevel()) { return m_pServerInfo->QueryServiceState(); }
return m_nState; }
/* virtual */ HRESULT CIISInstance::ChangeState( IN int nNewState ) /*++
Routine Description:
Change the ISM state of the instance
Arguments:
int nNewState
Return Value:
Error Return Code
Notes:
On a down-level (v3) version, this applies to the server, not the instance
--*/ { ASSERT(m_pServerInfo != NULL);
int * pnCurrentState; DWORD dwID;
if (IsClusterEnabled()) { //
// Not supported on cluster server
//
return ERROR_BAD_DEV_TYPE; }
if (IsDownLevel()) { dwID = 0; pnCurrentState = m_pServerInfo->GetServiceStatePtr(); } else { dwID = QueryID(); pnCurrentState = &m_nState; }
return m_pServerInfo->ChangeServiceState(nNewState, pnCurrentState, dwID); }
/* virtual */ HRESULT CIISInstance::Configure( IN CWnd * pParent OPTIONAL ) /*++
Routine Description:
Configure the instance object
Arguments:
CWnd * pParent : Optional parent window
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(m_pServerInfo != NULL);
//
// Set help file
//
theApp.SetHelpPath(m_pServerInfo);
CError err(m_pServerInfo->ConfigureServer(pParent->m_hWnd, QueryID()));
//
// Restore help path
//
theApp.SetHelpPath();
if (err.Succeeded()) { RefreshData(); }
return err; }
/* virtual */ HRESULT CIISInstance::RefreshData() /*++
Routine Description:
Refresh internal data
Arguments:
None
Return Value:
Error return code.
--*/ { CError err;
if (!IsDownLevel()) { ISMINSTANCEINFO ii; err = m_pServerInfo->QueryInstanceInfo( WITHOUT_INHERITANCE, &ii, QueryID() );
if (err.Succeeded()) { InitializeFromStruct(&ii); } }
return err; }
/* virtual */ HRESULT CIISInstance::ConfigureMMC( IN LPPROPERTYSHEETCALLBACK lpProvider, IN LPARAM param, IN LONG_PTR handle ) /*++
Routine Description:
Configure using MMC property sheets
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Prop sheet provider LPARAM param : Prop parameter LONG_PTR handle : console handle
Return Value:
Error return code
--*/ { ASSERT(m_pServerInfo != NULL);
return m_pServerInfo->MMMCConfigureServer( lpProvider, param, handle, QueryID() ); }
/* virtual */ LPCTSTR CIISInstance::GetStateText() const /*++
Routine Description:
Return text representation of current state (running/paused/stopped). Arguments:
None
Return Value:
Pointer to the string
--*/ { ASSERT(!CIISObject::s_strRunning.IsEmpty());
return IsStopped() ? CIISObject::s_strStopped : IsPaused() ? CIISObject::s_strPaused : IsRunning() ? CIISObject::s_strRunning : CIISObject::s_strUnknown; }
/* virtual */ LPCTSTR CIISInstance::GetDisplayText( OUT CString & strText ) const /*++
Routine Description:
Get the display text of this object Arguments:
CString & strText : String in which display text is to be returned
Return Value:
Pointer to the string
--*/ { try { if (m_fDownLevel) { ASSERT(m_pServerInfo != NULL);
if (CIISInstance::s_fServerView) { strText = m_pServerInfo->GetServiceName(); } else { strText = m_pServerInfo->QueryServerName(); } } else { //
// GetDisplayText loads from resources
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
CIPAddress ia(m_dwIPAddress);
CInstanceProps::GetDisplayText( strText, GetComment(), GetHostHeaderName(), m_pServerInfo->GetServiceName(), ia, m_sPort, m_dwID ); }
//
// Append state (paused, etc) if not running
//
if (CIISInstance::s_fAppendState && !IsRunning()) { CString strState; strState.Format(CIISInstance::s_strFormatState, GetStateText()); strText += strState; } } catch(CMemoryException * e) { TRACEEOLID("!!!exception in GetDisplayText"); e->ReportError(); e->Delete(); }
return strText; }
/* virtual */ HRESULT CIISInstance::AddChildNode( IN OUT CIISChildNode *& pChild ) /*++
Routine Description:
Add child node under current node
Arguments:
CIISChildNode *& pChild : Child node to be added
Return Value:
Error return code.
--*/ { pChild = NULL;
ISMCHILDINFO ii; CString strParent(g_cszRoot); CError err(GetServerInfo()->AddChild( &ii, sizeof(ii), QueryID(), strParent ));
if (err.Succeeded()) { pChild = new CIISChildNode(&ii, this); }
return err; }
/* virtual */ BOOL CIISInstance::ChildrenExpanded() const /*++
Routine Description:
Determine if the child items of this node have already been expanded
Arguments:
None
Return Value:
TRUE if the items do not need expansion, FALSE if they do.
--*/ { ASSERT(m_pServerInfo != NULL);
if (m_pServerInfo->SupportsChildren()) { //
// Note: timestamps ignored, because MMC will never send me another
// expansion notification, so we can't refresh after a certain time.
//
return m_tmChildrenExpanded > 0L; }
//
// Can't drill down any lower than this.
//
return TRUE; }
/* virtual */ HRESULT CIISInstance::ExpandChildren( IN HSCOPEITEM pParent ) /*++
Routine Description:
Mark the children as being expanded.
Arguments:
HSCOPEITEM pParent : Parent scope item
Return Value:
Error return code.
--*/ { ASSERT(m_pServerInfo != NULL);
if (m_pServerInfo->SupportsChildren() ) { //
// Mark the last epxansion time as being now.
//
time(&m_tmChildrenExpanded);
return S_OK; }
//
// Can't drill down any lower than this.
//
return CError::HResult(ERROR_INVALID_FUNCTION); }
/* virtual */ int CIISInstance::QueryBitmapIndex() const /*++
Routine Description:
Get the bitmap index of the object. This varies with the state of the view Arguments:
None
Return Value:
Bitmap index
--*/ { ASSERT(m_pServerInfo != NULL);
/*
return OK() ? m_pServerInfo->QueryBitmapIndex() : BMP_ERROR; */
return m_pServerInfo->QueryBitmapIndex(); }
/* virtual */ HRESULT CIISInstance::AddMenuItems( IN LPCONTEXTMENUCALLBACK pContextMenuCallback ) /*++
Routine Description:
Add context menu items for the instance
Arguments:
LPCONTEXTMENUCALLBACK pContextMenuCallback : Context menu callback
Return Value:
HRESULT
--*/ { CIISObject::AddMenuItems(pContextMenuCallback);
if (SupportsInstances() && CanAddInstance(GetMachineName())) { AddMenuItemByCommand(pContextMenuCallback, IDM_NEW_INSTANCE); } if (SupportsChildren()) { AddMenuItemByCommand(pContextMenuCallback, IDM_NEW_VROOT); }
if (SupportsSecurityWizard()) { AddMenuItemByCommand(pContextMenuCallback, IDM_TASK_SECURITY_WIZARD); }
return S_OK; }
/* virtual */ HRESULT CIISInstance::AddNextTaskpadItem( OUT MMC_TASK * pTask ) /*++
Routine Description:
Add next taskpad item
Arguments:
MMC_TASK * pTask : Task structure to fill in
Return Value:
HRESULT
--*/ { //
// CODEWORK: Ideally I would call the base class here, but that's
// a pain with enumeration
//
static int iIndex = 0;
//
// Fall through on the switch until an applicable command is found
//
UINT nID; switch(iIndex) { case 0: if (SupportsInstances() && CanAddInstance(GetMachineName())) { nID = IDM_NEW_INSTANCE; break; }
++iIndex;
//
// Fall through
//
case 1: if (SupportsChildren()) { nID = IDM_NEW_VROOT; break; } ++iIndex;
//
// Fall through
//
case 2: if (SupportsSecurityWizard()) { nID = IDM_TASK_SECURITY_WIZARD; break; }
++iIndex;
//
// Fall through
//
default: //
// All done
//
iIndex = 0; return S_FALSE; }
HRESULT hr = AddTaskpadItemByCommand( nID, pTask, GetServerInfo()->QueryInstanceHandle() );
if (SUCCEEDED(hr)) { ++iIndex; }
return hr; }
HRESULT CIISInstance::Delete() /*++
Routine Description:
Handle deletion of the current item
Arguments:
None
Return Value:
Error return code
--*/ { ASSERT(m_pServerInfo != NULL);
return m_pServerInfo->DeleteInstance(m_dwID); }
HRESULT CIISInstance::SecurityWizard() /*++
Routine Description:
Launch the security wizard on this instance
Arguments:
None
Return Value:
Error return code
--*/ { ASSERT(m_pServerInfo != NULL); ASSERT(m_pServerInfo->SupportsSecurityWizard());
CString strPhysicalPath; BuildPhysicalPath(strPhysicalPath);
return m_pServerInfo->ISMSecurityWizard(m_dwID, _T(""), g_cszRoot); }
int CIISInstance::Compare( IN int nCol, IN CIISObject * pObject ) /*++
Routine Description:
Compare against another CIISObject
Arguments:
int nCol : Compare on this column CIISObject * pObject : Compare against this object
Routine Description:
Comparison Return Value
--*/ { ASSERT(QueryGUID() == pObject->QueryGUID());
if (QueryGUID() != pObject->QueryGUID()) { //
// Invalid comparison
//
return +1; }
CString str1, str2; CIPAddress ia1, ia2; DWORD dw1, dw2; int n1, n2; CIISInstance * pInstance = (CIISInstance *)pObject;
switch(nCol) { case COL_DESCRIPTION: // Description
GetDisplayText(str1); pInstance->GetDisplayText(str2); return str1.CompareNoCase(str2);
case COL_STATE: // State
str1 = GetStateText(); str2 = pInstance->GetStateText(); return str1.CompareNoCase(str2);
case COL_DOMAIN_NAME: // Domain name
str1 = GetHostHeaderName(); str2 = pInstance->GetHostHeaderName(); return str1.CompareNoCase(str2);
case COL_IP_ADDRESS: // IP Address
ia1 = GetIPAddress(); ia2 = pInstance->GetIPAddress(); return ia1.CompareItem(ia2);
case COL_TCP_PORT: // Port
n1 = GetPort(); n2 = pInstance->GetPort(); return n1 - n2;
case COL_STATUS: dw1 = m_hrError; dw2 = pInstance->QueryError(); return dw1 > dw2 ? +1 : dw1==dw2 ? 0 : -1;
default: //
// No other columns current supported
//
ASSERT(FALSE); return 0; }
return -1; }
/* virtual */ void CIISInstance::GetResultDisplayInfo( IN int nCol, OUT CString & str, OUT int & nImage ) const /*++
Routine Description:
Get result data item display information.
Arguments:
int nCol : Column number CString & str : String data int & nImage : Image number
Return Value:
None
--*/ { nImage = QueryBitmapIndex(); CIPAddress ia;
str.Empty(); switch(nCol) { case COL_DESCRIPTION: // Description
GetDisplayText(str); break;
case COL_STATE: // State
if (OK()) { str = GetStateText(); } break;
case COL_DOMAIN_NAME: // Domain name
if (OK()) { str = GetHostHeaderName(); } break;
case COL_IP_ADDRESS: // IP Address
if (!IsDownLevel() && OK()) { ia = GetIPAddress(); if (ia.IsZeroValue()) { str = CIISObject::s_strDefaultIP; } else { ia.QueryIPAddress(str); } } break;
case COL_TCP_PORT: // Port
if (OK()) { if (GetPort()) { str.Format(_T("%u"), GetPort()); } else { str.Empty(); } } break;
case COL_STATUS: if (!OK()) { CError::TextFromHRESULT(QueryErrorCode(), str); } break;
default: //
// No other columns current supported
//
ASSERT(FALSE); } }
/* virtual */ LPCTSTR CIISInstance::GetComment() const /*++
Routine Description:
Get the comment string
Arguments:
None
Return Value:
Pointer to the comment string
--*/ { if (IsDownLevel()) { ASSERT(m_pServerInfo != NULL); return m_pServerInfo->GetServerComment(); }
return m_strComment; }
HRESULT CIISInstance::ShellBrowsePath( IN LPCTSTR lpszPath ) /*++
Routine Description:
Generate an URL from the instance and path information given, and attempt to resolve that URL
Arguments:
IN LPCTSTR lpszPath : Path
Return Value:
Error return code
--*/ { CString strDir; CString strOwner;
ASSERT(IsBrowsable());
///////////////////////////////////////////////////////////////////////////
//
// Try to build an URL. Use in order of priority:
//
// Domain name:port/root
// ip address:port/root
// computer name:port/root
//
if (HasHostHeaderName()) { strOwner = GetHostHeaderName(); } else if (HasIPAddress()) { CIPAddress ia(GetIPAddress()); ia.QueryIPAddress(strOwner); } else { //
// Use the computer name (w/o backslashes)
//
if (IsLocalMachine()) { strOwner = _T("localhost"); } else { LPCTSTR lpOwner = GetMachineName(); strOwner = PURE_COMPUTER_NAME(lpOwner); } }
int nPort = GetPort();
LPCTSTR lpProtocol = GetServerInfo()->GetProtocol();
if (lpProtocol == NULL) { return CError::HResult(ERROR_INVALID_PARAMETER); }
//
// "Root" is a metabase concept which has no place in the
// path.
//
TRACEEOLID(lpszPath); lpszPath += lstrlen(g_cszRoot); strDir.Format( _T("%s://%s:%u%s"), lpProtocol, (LPCTSTR)strOwner, nPort, lpszPath );
TRACEEOLID("Attempting to open URL: " << strDir);
CError err; { //
// AFX_MANAGE_STATE required for wait cursor
//
AFX_MANAGE_STATE(AfxGetStaticModuleState()); CWaitCursor wait;
if (::ShellExecute( NULL, _T("open"), strDir, NULL, _T(""), SW_SHOW ) <= (HINSTANCE)32) { err.GetLastWinError(); } }
return err; }
void CIISInstance::InitializeChildHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result headers
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { CIISChildNode::InitializeHeaders(pHeader); }
int CIISChildNode::rgnLabels[COL_TOTAL] = { IDS_RESULT_VDIR_ALIAS, IDS_RESULT_PATH, IDS_RESULT_STATUS, };
int CIISChildNode::rgnWidths[COL_TOTAL] = { 120, 300, 200, };
/* static */ void CIISChildNode::InitializeHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result headers
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { CIISObject::BuildResultView(pHeader, COL_TOTAL, rgnLabels, rgnWidths); }
void CIISChildNode::InitializeChildHeaders( LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result headers for a child item
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { InitializeHeaders(pHeader); }
CIISChildNode::CIISChildNode( IN ISMCHILDINFO * pii, IN CIISInstance * pOwner ) /*++
Routine Description:
Initialize child node object from ISMCHILDINFO structure information
Arguments:
ISMCHILDINFO * pii : Pointer to ISMCHILDINFO structure CIISInstance * pOwner : Owner instance
Return Value:
N/A
--*/ : CIISObject(cChildNode), m_pOwner(pOwner) { InitializeFromStruct(pii); }
void CIISChildNode::InitializeFromStruct( IN ISMCHILDINFO * pii ) /*++
Routine Description:
Initialize data from ISMCHILDINFO structure
Arguments:
ISMCHILDINFO * pii : Pointer to ISMCHILDINFO structure
Return Value:
None.
--*/
{ ASSERT(pii); ASSERT(pii->szAlias); ASSERT(pii->szPath);
try { m_fEnabledApplication = pii->fEnabledApplication; CError err(pii->dwError); m_hrError = err; m_strRedirPath = pii->szRedirPath; m_fChildOnlyRedir = pii->fChildOnlyRedir;
//
// Initialize base objects
//
m_strNodeName = pii->szAlias; m_strPhysicalPath = pii->szPath; } catch(CMemoryException * e) { e->ReportError(); e->Delete(); } }
/* virtual */ int CIISChildNode::QueryBitmapIndex() const /*++
Routine Description:
Get the bitmap index of the object. This varies with the state of the view Arguments:
None
Return Value:
Bitmap index
--*/ { if (!OK()) { return BMP_ERROR; }
if (IsEnabledApplication()) { return BMP_APPLICATION; }
if (IsVirtualDirectory()) { ASSERT(m_pOwner != NULL);
return m_pOwner->GetServerInfo()->QueryChildBitmapIndex(); }
return BMP_DIRECTORY; }
/* virtual */ LPCTSTR CIISChildNode::GetDisplayText( OUT CString & strText ) const /*++
Routine Description:
Get the display text of this object Arguments:
CString & strText : String in which display text is to be returned
Return Value:
Pointer to the string
--*/ { strText = m_strNodeName;
return strText; }
/* virtual */ HRESULT CIISChildNode::AddMenuItems( IN LPCONTEXTMENUCALLBACK pContextMenuCallback ) /*++
Routine Description:
Add context menu items relevant to this node
Arguments:
LPCONTEXTMENUCALLBACK pContextMenuCallback
Return Value:
HRESULT
--*/ { CIISObject::AddMenuItems(pContextMenuCallback);
AddMenuItemByCommand(pContextMenuCallback, IDM_NEW_VROOT);
if (SupportsSecurityWizard()) { AddMenuItemByCommand(pContextMenuCallback, IDM_TASK_SECURITY_WIZARD); }
return S_OK; }
/* virtual */ HRESULT CIISChildNode::AddNextTaskpadItem( OUT MMC_TASK * pTask ) /*++
Routine Description:
Add next taskpad item
Arguments:
MMC_TASK * pTask : Task structure to fill in
Return Value:
HRESULT
--*/ { //
// CODEWORK: Ideally I would call the base class here, but that's
// a pain with enumeration
//
static int iIndex = 0;
//
// Fall through on the switch until an applicable command is found
//
UINT nID; switch(iIndex) { case 0: nID = IDM_NEW_VROOT; break;
case 1: if (SupportsSecurityWizard()) { nID = IDM_TASK_SECURITY_WIZARD; break; }
++iIndex;
//
// Fall through
//
default: //
// All done
//
iIndex = 0; return S_FALSE; }
HRESULT hr = AddTaskpadItemByCommand( nID, pTask, GetServerInfo()->QueryInstanceHandle() );
if (SUCCEEDED(hr)) { ++iIndex; }
return hr; }
int CIISChildNode::Compare( IN int nCol, IN CIISObject * pObject ) /*++
Routine Description:
Compare against another CIISObject
Arguments:
int nCol : Compare on this column CIISObject * pObject : Compare against this object
Routine Description:
Comparison Return Value
--*/ { ASSERT(QueryGUID() == pObject->QueryGUID()); if (QueryGUID() != pObject->QueryGUID()) { //
// Invalid comparison
//
return +1; }
DWORD dw1, dw2;
CIISChildNode * pChild = (CIISChildNode *)pObject;
switch(nCol) { case COL_ALIAS: // Alias
return m_strNodeName.CompareNoCase(pChild->m_strNodeName);
case COL_PATH: // Path
dw1 = IsRedirected(); dw2 = pChild->IsRedirected(); if (dw1 != dw2) { return dw1 > dw2 ? +1 : -1; }
return GetPhysicalPath().CompareNoCase(pChild->GetPhysicalPath());
case COL_STATUS: dw1 = m_hrError; dw2 = pChild->QueryError(); return dw1 > dw2 ? +1 : dw1==dw2 ? 0 : -1;
default: //
// No other columns current supported
//
ASSERT(FALSE); }
return -1; }
/* virtual */ void CIISChildNode::GetResultDisplayInfo( IN int nCol, OUT CString & str, OUT int & nImage ) const /*++
Routine Description:
Get result data item display information.
Arguments:
int nCol : Column number CString & str : String data int & nImage : Image number
Return Value:
None
--*/ { nImage = QueryBitmapIndex();
str.Empty(); switch(nCol) { case COL_ALIAS: // Alias
str = m_strNodeName; break;
case COL_PATH: // Path
if (IsRedirected()) { str.Format(s_strRedirect, m_strRedirPath); } else { str = m_strPhysicalPath; } break;
case COL_STATUS: if (!OK()) { CError::TextFromHRESULT(QueryErrorCode(), str); } break;
default: //
// No other columns current supported
//
ASSERT(FALSE); } }
/* virtual */ HRESULT CIISChildNode::Configure( IN CWnd * pParent ) /*++
Routine Description:
Configure the child node object Arguments:
CWnd * pParent : Parent window handle
Return Value:
Error return code
--*/
{ ASSERT(m_pOwner != NULL);
//
// Ok, build a metabase path on the fly now by getting
// the nodes of the parents up until the owning instance.
//
CString strParent; BuildParentPath(strParent, FALSE);
//
// Set help file
//
theApp.SetHelpPath(GetServerInfo());
CError err(GetServerInfo()->ConfigureChild( pParent->m_hWnd, FILE_ATTRIBUTE_VIRTUAL_DIRECTORY, m_pOwner->QueryID(), strParent, m_strNodeName ));
//
// Set help file
//
theApp.SetHelpPath();
if (err.Succeeded()) { RefreshData(); }
return err; }
/* virtual */ HRESULT CIISChildNode::RefreshData() /*++
Routine Description:
Refresh internal data
Arguments:
None
Return Value:
Error return code.
--*/ { ISMCHILDINFO ii;
CString strParent; BuildParentPath(strParent, FALSE);
CError err(GetServerInfo()->QueryChildInfo( WITH_INHERITANCE, &ii, m_pOwner->QueryID(), strParent, m_strNodeName ));
if (err.Succeeded()) { InitializeFromStruct(&ii); }
return err; }
/* virtual */ HRESULT CIISChildNode::ConfigureMMC( IN LPPROPERTYSHEETCALLBACK lpProvider, IN LPARAM param, IN LONG_PTR handle ) /*++
Routine Description:
Configure using MMC property sheets
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Prop sheet provider LPARAM param : Prop parameter LONG_PTR handle : console handle
Return Value:
Error return code
--*/ { ASSERT(m_pOwner != NULL);
CString strParent; BuildParentPath(strParent, FALSE);
return GetServerInfo()->MMCConfigureChild(lpProvider, param, handle, FILE_ATTRIBUTE_VIRTUAL_DIRECTORY, m_pOwner->QueryID(), strParent, m_strNodeName ); }
/* virtual */ HRESULT CIISChildNode::AddChildNode( CIISChildNode *& pChild ) /*++
Routine Description:
Add child node under current node
Arguments:
CIISChildNode *& pChild : Child node to be added
Return Value:
Error return code.
--*/ { ASSERT(m_pOwner != NULL); ISMCHILDINFO ii;
CString strPath; BuildFullPath(strPath, FALSE);
pChild = NULL; CError err(GetServerInfo()->AddChild( &ii, sizeof(ii), m_pOwner->QueryID(), strPath ));
if (err.Succeeded()) { pChild = new CIISChildNode(&ii, m_pOwner); }
return err; }
/* virtual */ HRESULT CIISChildNode::Rename( IN LPCTSTR lpszNewName ) /*++
Routine Description:
Rename the current node
Arguments:
LPCTSTR lpszNewName : New name
Return Value:
Error return code.
--*/ { ASSERT(m_pOwner != NULL);
CString strPath; BuildParentPath(strPath, FALSE);
CError err(GetServerInfo()->RenameChild( m_pOwner->QueryID(), strPath, m_strNodeName, lpszNewName ));
if (err.Succeeded()) { m_strNodeName = lpszNewName; }
return err; }
HRESULT CIISChildNode::Delete() /*++
Routine Description:
Delete the current node
Arguments:
None
Return Value:
Error return code.
--*/ { ASSERT(m_pOwner != NULL);
CString strParent; BuildParentPath(strParent, FALSE);
return GetServerInfo()->DeleteChild( m_pOwner->QueryID(), strParent, m_strNodeName ); }
HRESULT CIISChildNode::SecurityWizard() /*++
Routine Description:
Launch the security wizard on this child node
Arguments:
None
Return Value:
Error return code
--*/ { ASSERT(m_pOwner != NULL);
CString strParent; BuildParentPath(strParent, FALSE);
return GetServerInfo()->ISMSecurityWizard( m_pOwner->QueryID(), strParent, m_strNodeName ); }
int CIISFileNode::rgnLabels[COL_TOTAL] = { IDS_RESULT_VDIR_ALIAS, IDS_RESULT_PATH, IDS_RESULT_STATUS, };
int CIISFileNode::rgnWidths[COL_TOTAL] = { 120, 300, 200, };
/* static */ void CIISFileNode::InitializeHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result headers
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { CIISObject::BuildResultView(pHeader, COL_TOTAL, rgnLabels, rgnWidths); }
void CIISFileNode::InitializeChildHeaders( IN LPHEADERCTRL pHeader ) /*++
Routine Description:
Initialize the result headers
Arguments:
LPHEADERCTRL pHeader : Header control
Return Value:
None
--*/ { InitializeHeaders(pHeader); }
CIISFileNode::CIISFileNode( IN LPCTSTR lpszAlias, IN DWORD dwAttributes, IN CIISInstance * pOwner, IN LPCTSTR lpszRedirect, IN BOOL fDir OPTIONAL ) /*++
Routine Description:
Constructor for file object Arguments:
LPCTSTR lpszPath : Path name DWORD dwAttributes : Attributes CIISInstance * pOwner : Owner instance BOOL fDir : TRUE for directory, FALSE for file
Return Value:
N/A
--*/ : CIISObject(cFileNode, lpszAlias), m_dwAttributes(dwAttributes), m_pOwner(pOwner), m_fEnabledApplication(FALSE), m_fDir(fDir) { m_strRedirPath = lpszRedirect; }
/* virtual */ int CIISFileNode::QueryBitmapIndex() const /*++
Routine Description:
Get the bitmap index of the object. This varies with the state of the view Arguments:
None
Return Value:
Bitmap index
--*/ { if (IsEnabledApplication()) { return BMP_APPLICATION; }
return IsDirectory() ? BMP_DIRECTORY : BMP_FILE; }
/* virtual */ LPCTSTR CIISFileNode::GetDisplayText( OUT CString & strText ) const /*++
Routine Description:
Get the display text of this object Arguments:
CString & strText : String in which display text is to be returned
Return Value:
Pointer to the string
--*/ { strText = m_strNodeName;
return strText; }
int CIISFileNode::Compare( IN int nCol, IN CIISObject * pObject ) /*++
Routine Description:
Compare against another CIISObject
Arguments:
int nCol : Compare on this column CIISObject * pObject : Compare against this object
Routine Description:
Comparison Return Value
--*/ { ASSERT(QueryGUID() == pObject->QueryGUID()); if (QueryGUID() != pObject->QueryGUID()) { //
// Invalid comparison
//
return +1; }
return m_strNodeName.CompareNoCase(pObject->GetNodeName()); }
/* virtual */ void CIISFileNode::GetResultDisplayInfo( IN int nCol, OUT CString & str, OUT int & nImage ) const /*++
Routine Description:
Get result data item display information.
Arguments:
int nCol : Column number CString & str : String data int & nImage : Image number
Return Value:
None
--*/ { nImage = QueryBitmapIndex(); str.Empty();
switch(nCol) { case COL_ALIAS: str = m_strNodeName; break;
case COL_PATH: // Path
if (IsRedirected()) { str.Format(s_strRedirect, m_strRedirPath); } else { str.Empty(); } break;
case COL_STATUS: if (!OK()) { CError::TextFromHRESULT(QueryErrorCode(), str); } break;
default: //
// No other columns current supported
//
ASSERT(FALSE); } }
/* virtual */ CIISObject * CIISFileNode::GetParentObject() const /*++
Routine Description:
Get the parent object (in the scope view) of this object.
Arguments:
None
Return Value:
Pointer to the parent object, or NULL if not found
--*/ { if (!IsDir()) { //
// File nodes exist on the result side only, and the scope
// item handle they have points to their _parent_ not to
// themselves.
//
SCOPEDATAITEM sdi; sdi.mask = SDI_PARAM; sdi.ID = GetScopeHandle(); HRESULT hr = GetScopeView()->GetItem(&sdi);
return (CIISObject *)sdi.lParam; }
//
// Directory nodes work like anyone else
//
return CIISObject::GetParentObject(); }
/* virtual */ HRESULT CIISFileNode::Configure( IN CWnd * pParent ) /*++
Routine Description:
Configure using private property sheet provider
Arguments:
CWnd * pParent : Parent window
Return Value:
Error return code.
--*/ { ASSERT(m_pOwner != NULL);
CString strParent; BuildParentPath(strParent, FALSE);
//
// Set help file
//
theApp.SetHelpPath(GetServerInfo());
CError err(GetServerInfo()->ConfigureChild( pParent->m_hWnd, m_dwAttributes, m_pOwner->QueryID(), strParent, m_strNodeName ));
//
// Restore help file
//
theApp.SetHelpPath();
if (err.Succeeded()) { RefreshData(); }
return err; }
/* virtual */ HRESULT CIISFileNode::Rename( IN LPCTSTR lpszNewName ) /*++
Routine Description:
Rename the current node
Arguments:
LPCTSTR lpszNewName : New name
Return Value:
Error return code.
--*/ { ASSERT(m_pOwner != NULL); ASSERT(lpszNewName != NULL);
// We need to check if this new name is OK
LPTSTR p = (LPTSTR)lpszNewName; if (*p == 0) { AFX_MANAGE_STATE(::AfxGetStaticModuleState() ); ::AfxMessageBox(IDS_ERR_EMPTY_FILENAME, MB_ICONSTOP); return ERROR_BAD_PATHNAME; }
while (*p != 0) { UINT type = PathGetCharType(*p); if (type & (GCT_LFNCHAR | GCT_SHORTCHAR)) { p++; continue; } else { AFX_MANAGE_STATE(::AfxGetStaticModuleState() ); ::AfxMessageBox(IDS_ERR_INVALID_CHAR, MB_ICONSTOP); return ERROR_BAD_PATHNAME; } }
CString strPath, strPhysicalPath, strDir, strNewName; BuildPhysicalPath(strPhysicalPath); BuildParentPath(strPath, FALSE);
//
// First make sure there's no conflicting name in the metabase
//
ISMCHILDINFO ii; ii.dwSize = sizeof(ii);
CError err(GetServerInfo()->QueryChildInfo( WITHOUT_INHERITANCE, &ii, m_pOwner->QueryID(), strPath, lpszNewName ));
if (err.Succeeded()) { //
// That won't do -- the name already exists in the metabase
// We handle the UI for this message
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState() ); ::AfxMessageBox(IDS_ERR_DUP_METABASE);
return ERROR_ALREADY_EXISTS; }
if (IsLocalMachine() || ::IsUNCName(strPhysicalPath)) { //
// Local directory, or already a unc path
//
strDir = strPhysicalPath; } else { ::MakeUNCPath(strDir, GetMachineName(), strPhysicalPath); }
//
// Have to make a fully qualified destination name
//
strNewName = strDir; int iPos = strNewName.ReverseFind(_T('\\'));
if (iPos <= 0) { //
// Bogus file name path!
//
ASSERT(FALSE); return ERROR_INVALID_PARAMETER; }
strNewName.ReleaseBuffer(iPos + 1); strNewName += lpszNewName;
TRACEEOLID("Attempting to rename file/directory: " << strDir); TRACEEOLID("To " << strNewName);
//
// Convert to double-null terminated list of null terminated
// strings
//
TCHAR szPath[MAX_PATH + 1]; TCHAR szDest[MAX_PATH + 1]; ZeroMemory(szPath, sizeof(szPath)); ZeroMemory(szDest, sizeof(szDest)); _tcscpy(szPath, strDir); _tcscpy(szDest, strNewName);
CWnd * pWnd = AfxGetMainWnd();
//
// Attempt to delete using shell APIs
//
SHFILEOPSTRUCT sos; ZeroMemory(&sos, sizeof(sos)); sos.hwnd = pWnd ? pWnd->m_hWnd : NULL; sos.wFunc = FO_RENAME; sos.pFrom = szPath; sos.pTo = szDest; sos.fFlags = FOF_ALLOWUNDO;
int iReturn = SHFileOperation(&sos);
if (sos.fAnyOperationsAborted) { err = ERROR_CANCELLED; }
err = iReturn;
if (!iReturn && !sos.fAnyOperationsAborted) { //
// Successful rename -- now handle the metabase
// rename as well.
//
err = GetServerInfo()->RenameChild( m_pOwner->QueryID(), strPath, m_strNodeName, lpszNewName );
if (err.Win32Error() == ERROR_PATH_NOT_FOUND || err.Win32Error() == ERROR_FILE_NOT_FOUND ) { //
// Harmless
//
err.Reset(); }
if (err.Succeeded()) { m_strNodeName = lpszNewName; } }
return err; }
HRESULT CIISFileNode::Delete() /*++
Routine Description:
Delete the current node
Arguments:
None
Return Value:
Error return code.
--*/ { CString strPhysicalPath, strDir; BuildPhysicalPath(strPhysicalPath);
if (IsLocalMachine() || ::IsUNCName(strPhysicalPath)) { //
// Local directory, or already a unc path
//
strDir = strPhysicalPath; } else { ::MakeUNCPath(strDir, GetMachineName(), strPhysicalPath); }
TRACEEOLID("Attempting to remove file/directory: " << strDir);
//
// Convert to double-null terminated list of null terminated
// strings
//
TCHAR szPath[MAX_PATH + 1]; ZeroMemory(szPath, sizeof(szPath)); _tcscpy(szPath, strDir);
CWnd * pWnd = AfxGetMainWnd();
//
// Attempt to delete using shell APIs
//
SHFILEOPSTRUCT sos; ZeroMemory(&sos, sizeof(sos)); sos.hwnd = pWnd ? pWnd->m_hWnd : NULL; sos.wFunc = FO_DELETE; sos.pFrom = szPath; sos.fFlags = FOF_ALLOWUNDO;
CError err; // Use assignment to avoid conversion and wrong constructor call
err = ::SHFileOperation(&sos);
if (sos.fAnyOperationsAborted) { err = ERROR_CANCELLED; }
if (err.Succeeded()) { //
// Successful deletion -- now delete metabase properties
ASSERT(m_pOwner != NULL);
CString strParent; BuildParentPath(strParent, FALSE);
err = GetServerInfo()->DeleteChild( m_pOwner->QueryID(), strParent, m_strNodeName );
if (err.Win32Error() == ERROR_PATH_NOT_FOUND || err.Win32Error() == ERROR_FILE_NOT_FOUND ) { //
// Harmless
//
err.Reset(); } }
return err; }
HRESULT CIISFileNode::FetchMetaInformation( IN CString & strParent, OUT BOOL * pfVirtualDirectory OPTIONAL ) /*++
Routine Description: Fetch metabase information on this item.
Arguments:
CString & strParent : Parent path BOOL * pfVirtualDirectory : Directory
Return Value:
Error return code.
--*/ { ISMCHILDINFO ii;
CError err(GetServerInfo()->QueryChildInfo( WITH_INHERITANCE, &ii, m_pOwner->QueryID(), strParent, m_strNodeName ));
if (err.Succeeded()) { //
// Exists in the metabase
//
m_fEnabledApplication = ii.fEnabledApplication; m_strRedirPath = ii.szRedirPath; m_fChildOnlyRedir = ii.fChildOnlyRedir;
if (pfVirtualDirectory) { *pfVirtualDirectory = !ii.fInheritedPath; } } else { //
// No entry for this in the metabase
//
m_fEnabledApplication = FALSE; m_strRedirPath.Empty(); }
return S_OK; }
/* virtual */ HRESULT CIISFileNode::RefreshData() /*++
Routine Description:
Refresh internal data
Arguments:
None
Return Value:
Error return code.
--*/ { CString strParent; BuildParentPath(strParent, FALSE);
return FetchMetaInformation(strParent); }
/* virtual */ HRESULT CIISFileNode::ConfigureMMC( IN LPPROPERTYSHEETCALLBACK lpProvider, IN LPARAM param, IN LONG_PTR handle ) /*++
Routine Description:
Configure using MMC property sheet provider
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Property sheet provider LPARAM param : Parameter LONG_PTR handle : Handle
Return Value:
Error return code
--*/ { ASSERT(m_pOwner != NULL);
CString strParent; BuildParentPath(strParent, FALSE);
return GetServerInfo()->MMCConfigureChild( lpProvider, param, handle, m_dwAttributes, m_pOwner->QueryID(), strParent, m_strNodeName ); }
/* virtual */ HRESULT CIISFileNode::AddMenuItems( IN LPCONTEXTMENUCALLBACK pContextMenuCallback ) /*++
Routine Description:
Add context menu items relevant to this node
Arguments:
LPCONTEXTMENUCALLBACK pContextMenuCallback
Return Value:
HRESULT
--*/ { CIISObject::AddMenuItems(pContextMenuCallback);
if (IsDir()) { AddMenuItemByCommand(pContextMenuCallback, IDM_NEW_VROOT); }
if (SupportsSecurityWizard()) { AddMenuItemByCommand(pContextMenuCallback, IDM_TASK_SECURITY_WIZARD); }
return S_OK; }
/* virtual */ HRESULT CIISFileNode::AddNextTaskpadItem( OUT MMC_TASK * pTask ) /*++
Routine Description:
Add next taskpad item
Arguments:
MMC_TASK * pTask : Task structure to fill in
Return Value:
HRESULT
--*/ { //
// CODEWORK: Ideally I would call be the base class here, but that's
// a pain with enumeration
//
static int iIndex = 0;
//
// Fall through on the switch until an applicable command is found
//
UINT nID;
switch(iIndex) { case 0: if (IsDir()) { nID = IDM_NEW_VROOT; break; } default: //
// All done
//
iIndex = 0; return S_FALSE; }
HRESULT hr = AddTaskpadItemByCommand( nID, pTask, GetServerInfo()->QueryInstanceHandle() );
if (SUCCEEDED(hr)) { ++iIndex; }
return hr; }
/* virtual */ HRESULT CIISFileNode::AddChildNode( IN CIISChildNode *& pChild ) /*++
Routine Description:
Add child node under current node
Arguments:
CIISChildNode *& pChild : Child node to be added
Return Value:
Error return code.
--*/ { ASSERT(m_pOwner != NULL); ISMCHILDINFO ii;
CString strPath; BuildFullPath(strPath, FALSE);
pChild = NULL; CError err(GetServerInfo()->AddChild( &ii, sizeof(ii), m_pOwner->QueryID(), strPath ));
if (err.Succeeded()) { pChild = new CIISChildNode( &ii, m_pOwner ); }
return err; }
HRESULT CIISFileNode::SecurityWizard() /*++
Routine Description:
Launch the security wizard on this file node
Arguments:
None
Return Value:
Error return code
--*/ { ASSERT(m_pOwner != NULL); ASSERT(SupportsSecurityWizard());
CString strParent; BuildParentPath(strParent, FALSE);
return GetServerInfo()->ISMSecurityWizard( m_pOwner->QueryID(), strParent, m_strNodeName ); }
|