|
|
/*++
Copyright (c) 1994-1998 Microsoft Corporation
Module Name :
events.cpp
Abstract:
Handle snapin event notifications
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "inetmgr.h"
#include "cinetmgr.h"
//
// Event handlers
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
HRESULT CSnapin::OnFolder( IN MMC_COOKIE cookie, IN LPARAM arg, IN LPARAM param ) /*++
Routine Description:
'Folder change' notification handler
Arguments:
MMC_COOKIE cookie : Selected item LPARAM arg : Notification Argument LPARAM param : Notification Parameter
Return Value:
HRESULT
--*/ { ASSERT(FALSE);
return S_OK; }
HRESULT CSnapin::OnAddImages( IN MMC_COOKIE cookie, IN LPARAM arg, IN LPARAM param ) /*++
Routine Description:
'Add Image' handler
Arguments:
MMC_COOKIE cookie : Selected item LPARAM arg : Notification Argument LPARAM param : Notification Parameter
Return Value:
HRESULT
--*/ { //
// if cookie is from a different snapin
// if (IsMyCookie(cookie) == FALSE)
//
if (0) { //
// add the images for the scope tree only
//
CBitmap bmp16x16; CBitmap bmp32x32; LPIMAGELIST lpImageList = reinterpret_cast<LPIMAGELIST>(arg);
//
// Load the bitmaps from the dll
//
{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); bmp16x16.LoadBitmap(IDB_16x16); bmp32x32.LoadBitmap(IDB_32x32); }
//
// Set the images
//
lpImageList->ImageListSetStrip( reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp16x16)), reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp32x32)), 0, RGB(255, 0, 255) );
lpImageList->Release(); } else { InitializeBitmaps(cookie); }
return S_OK; }
HRESULT CSnapin::OnShow( IN MMC_COOKIE cookie, IN LPARAM arg, IN LPARAM param ) /*++
Routine Description:
'Show' notification handler
Arguments:
MMC_COOKIE cookie : Selected item LPARAM arg : Notification Argument LPARAM param : Notification Parameter
Return Value:
HRESULT
--*/ { //
// Note - arg is TRUE when it is time to enumerate
//
if (arg) { //
// Show the headers for this nodetype
//
InitializeHeaders(cookie); Enumerate(cookie, param);
if (m_pControlbar) { SetToolbarStates(cookie); } } else { //
// Free data associated with the result pane items, because
// the node is no longer being displayed.
// Note: The console will remove the items from the result pane
//
m_oblResultItems.RemoveAll(); }
return S_OK; }
HRESULT CSnapin::OnActivate( IN MMC_COOKIE cookie, IN LPARAM arg, IN LPARAM param ) /*++
Routine Description:
'Activiation' notification handler
Arguments:
MMC_COOKIE cookie : Selected item LPARAM arg : Notification Argument LPARAM param : Notification Parameter
Return Value:
HRESULT
--*/ { return S_OK; }
HRESULT CSnapin::OnResultItemClkOrDblClk( IN MMC_COOKIE cookie, IN BOOL fDblClick ) /*++
Routine Description:
Result item click/double click notification handler
Arguments:
MMC_COOKIE cookie : Selected item BOOL fDblClick : TRUE if double click, FALSE for single click
Return Value:
HRESULT
--*/ { CIISObject * pObject = (CIISObject *)cookie;
if (pObject && !pObject->IsMMCConfigurable() && pObject->IsLeafNode()) { //
// Special case: Down-level object -- not mmc configurable, but
// configuration is the default verb, so fake it.
//
if (fDblClick) { ((CComponentDataImpl *)m_pComponentData)->DoConfigure(pObject);
return S_OK; } }
//
// Use the default verb
//
return S_FALSE; }
HRESULT CSnapin::OnMinimize( IN MMC_COOKIE cookie, IN LPARAM arg, IN LPARAM param ) /*++
Routine Description:
'Minimize' handler
Arguments:
MMC_COOKIE cookie : Selected item LPARAM arg : Notification Argument LPARAM param : Notification Parameter
Return Value:
HRESULT
--*/ { return S_OK; }
HRESULT CSnapin::OnPropertyChange( IN LPDATAOBJECT lpDataObject ) /*++
Routine Description:
'Property change' notification handler
Arguments:
LPDATAOBJECT lpDataObject : Selected data object
Return Value:
HRESULT
--*/ { CIISObject * pObject = NULL; if (lpDataObject != NULL) { INTERNAL * pInternal = ExtractInternalFormat(lpDataObject); if (pInternal != NULL) { pObject = (CIISObject *)pInternal->m_cookie; SetToolbarStates((MMC_COOKIE)pObject); FREE_DATA(pInternal); } }
return S_OK; }
HRESULT CSnapin::OnUpdateView( IN LPDATAOBJECT lpDataObject ) /*++
Routine Description:
'Update View' notification handler
Arguments:
LPDATAOBJECT lpDataObject : Selected data object
Return Value:
HRESULT
--*/ { return OnPropertyChange(lpDataObject); }
void CSnapin::Enumerate( IN MMC_COOKIE cookie, IN HSCOPEITEM hParent ) /*++
Routine Description:
Scope item enumeration notification handler
Arguments:
MMC_COOKIE cookie : Selected cookie (i.e. IISObject *) HSCOPEITEM hParent : Scope item to be enumerated
Return Value:
None
--*/ { //
// Add result view items
//
EnumerateResultPane(cookie); }
void CSnapin::AddFileSystem( IN HSCOPEITEM hParent, IN LPCTSTR lpstrRoot, IN LPCTSTR lpstrMetaRoot, IN CIISInstance * pInstance, IN BOOL fGetDirs ) /*++
Routine Description:
Add file system to result view.
Arguments:
HSCOPEITEM hParent Parent scope item LPCTSTR lpstrRoot Physical path LPCTSTR lpstrMetaRoot Meta root CIISInstance * pInstance Owning instance BOOL fGetDirs TRUE for directories, FALSE for files
Return Value:
None
--*/ { //
// Save state - needed for CWaitCursor
//
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DWORD dwBufferSize = 0L; int cChildren = 0; CError err; do { CWaitCursor(); LPCTSTR lpstrOwner = pInstance->GetMachineName(); ASSERT(lpstrOwner);
CString strDir;
if (::IsServerLocal(lpstrOwner) || ::IsUNCName(lpstrRoot)) { //
// Local directory, or already a unc path
//
strDir = lpstrRoot; } else { ::MakeUNCPath(strDir, lpstrOwner, lpstrRoot); }
strDir.TrimLeft(); strDir.TrimRight();
if (strDir.IsEmpty()) { //
// Invalid path
//
break; }
strDir += _T("\\*");
WIN32_FIND_DATA w32data; HANDLE hFind = ::FindFirstFile(strDir, &w32data);
if (hFind == INVALID_HANDLE_VALUE) { err.GetLastWinError(); break; }
//
// Find metabase information to match up with
// this entry
//
CWaitCursor wait;
CString strRedirect; CString strBase; pInstance->BuildFullPath(strBase, TRUE); LPCTSTR lpPath = lpstrMetaRoot;
while (lpPath && *lpPath && *lpPath != _T('/')) ++lpPath;
if (lpPath && *lpPath) { strBase += lpPath; }
TRACEEOLID("Opening: " << strBase); TRACEEOLID(lpstrMetaRoot);
BOOL fCheckMetabase = TRUE; CMetaKey mk( lpstrOwner, METADATA_PERMISSION_READ, METADATA_MASTER_ROOT_HANDLE, strBase );
CError errMB(mk.QueryResult());
if (errMB.Win32Error() == ERROR_PATH_NOT_FOUND) { //
// Metabase path not found, not a problem.
//
TRACEEOLID("Parent node not in metabase"); fCheckMetabase = FALSE; errMB.Reset(); } else if (!errMB.MessageBoxOnFailure()) { //
// Opened successfully, read redirect string.
//
DWORD dwAttr;
errMB = mk.QueryValue( MD_HTTP_REDIRECT, strRedirect, NULL, // Inheritance override
NULL, // Path
&dwAttr );
if (errMB.Succeeded()) { if (IS_FLAG_SET(dwAttr, METADATA_INHERIT)) { int nComma = strRedirect.Find(_T(','));
if (nComma >= 0) { strRedirect.ReleaseBuffer(nComma); } } else { //
// Yes, there's a redirect on the parent, but it's
// not marked as inheritable, so it won't affect
// the children.
//
strRedirect.Empty(); } } }
//
// Loop through the file system
//
do { //
// Check to see if this is a file or directory as desired.
// Ignore anything starting with a dot.
//
TRACEEOLID(w32data.cFileName); BOOL fIsDir = ((w32data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
if (fIsDir == fGetDirs && *w32data.cFileName != _T('.')) { CIISFileNode * pNode = new CIISFileNode( w32data.cFileName, w32data.dwFileAttributes, pInstance, strRedirect, fIsDir );
if (pNode == NULL) { err = ERROR_NOT_ENOUGH_MEMORY; break; }
//
// For the result view -- only files, directories
// get added automatically
//
ASSERT(!fIsDir);
if (fCheckMetabase) { errMB = mk.DoesPathExist(w32data.cFileName);
if (errMB.Succeeded()) { //
// Match up with metabase properties. If the item
// is found in the metabase with a non-inherited vrpath,
// than a virtual root with this name exists, and this
// file/directory should not be shown.
//
BOOL fVirtualDirectory; CString strMetaRoot(lpstrMetaRoot);
errMB = pNode->FetchMetaInformation( strMetaRoot, &fVirtualDirectory );
if (errMB.Succeeded() && fVirtualDirectory) { TRACEEOLID("file/directory exists as vroot -- tossing" << w32data.cFileName); delete pNode;
continue; } } } //
// This better be unassigned -- one scope item per IISobject!
// Note that the scope handle we're setting is actually the
// _parent_'s scope handle.
//
ASSERT(pNode->GetScopeHandle() == NULL); pNode->SetScopeHandle(hParent, TRUE);
//
// Add the item
//
RESULTDATAITEM ri; ::ZeroMemory(&ri, sizeof(ri)); ri.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; ri.str = MMC_CALLBACK; ri.nImage = pNode->QueryBitmapIndex(); ri.lParam = (LPARAM)pNode; m_pResult->InsertItem(&ri);
//
// Store
//
m_oblResultItems.AddTail(pNode); } } while(err.Succeeded() && FindNextFile(hFind, &w32data));
::FindClose(hFind); } while(FALSE);
if (err.Failed()) { //
// Behaviour change: Display the errors always on the result
// enumerator, and stop displaying them on the scope side
// (this way we avoid double error messages)
//
err.MessageBoxFormat( IDS_ERR_ENUMERATE_FILES, MB_OK, NO_HELP_CONTEXT ); } }
void CSnapin::DestroyItem( IN LPDATAOBJECT lpDataObject ) /*++
Routine Description:
Delete the contents of the given data object
Arguments:
LPDATAOBJECT lpDataObject : Data object to be destroyed
Return Value:
None
--*/ { CIISObject * pObject = NULL;
if (lpDataObject) { INTERNAL * pInternal = ExtractInternalFormat(lpDataObject);
if (pInternal) { pObject = (CIISObject *)pInternal->m_cookie; delete pObject; FREE_DATA(pInternal); } } }
void CSnapin::EnumerateResultPane( IN MMC_COOKIE cookie ) /*++
Routine Description:
Enumerate the result pane
Arguments:
MMC_COOKIE cookie : Parent CIISObject (scope side)
Return Value:
None
--*/ { //
// Make sure we QI'ed for the interface
//
ASSERT(m_pResult != NULL); ASSERT(m_pComponentData != NULL);
CIISObject * pObject = (CIISObject *)cookie;
if (pObject == NULL) { //
// Static root node -- owns no leaf nodes
//
return; }
if (pObject->SupportsFileSystem()) { CString strPhysicalPath, strMetaPath; pObject->BuildPhysicalPath(strPhysicalPath); pObject->BuildFullPath(strMetaPath, FALSE);
AddFileSystem( pObject->GetScopeHandle(), strPhysicalPath, strMetaPath, pObject->FindOwnerInstance(), GET_FILES ); }
//m_pResult->Sort(0, 0, -1);
}
HSCOPEITEM CComponentDataImpl::AddIISObject( IN HSCOPEITEM hParent, IN CIISObject * pObject, IN HSCOPEITEM hSibling, OPTIONAL IN BOOL fNext OPTIONAL ) /*++
Routine Description:
Insert IIS object to the scope view
Arguments:
HSCOPEITEM hParent : Parent scope handle CIISObject * pObject : Object to be added HSCOPEITEM hSibling : NULL, or otherwise next sibling item BOOL fNext : If hSibling != NULL, this is used to indicate : Next (TRUE), or Previous (FALSE).
Return Value:
Handle to scope item of the newly added item
--*/ { ASSERT(m_pScope != NULL); ASSERT(pObject != NULL);
SCOPEDATAITEM item; ::ZeroMemory(&item, sizeof(SCOPEDATAITEM));
item.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
if (hSibling != NULL) { item.mask |= (fNext ? SDI_NEXT : SDI_PREVIOUS); item.relativeID = hSibling; } else { item.mask |= SDI_PARENT; item.relativeID = hParent; }
//
// No '+' sign if no child objects could possibly exist.
// e.g. downlevel web services, etc.
//
item.cChildren = (pObject->SupportsFileSystem() || pObject->SupportsChildren()) ? 1 : 0;
item.displayname = MMC_CALLBACK; item.nOpenImage = item.nImage = pObject->QueryBitmapIndex(); item.lParam = (LPARAM)pObject; m_pScope->InsertItem(&item);
//
// This better be unassigned -- one scope item per IISobject!
//
ASSERT(pObject->GetScopeHandle() == NULL); pObject->SetScopeHandle(item.ID);
return item.ID; }
BOOL CComponentDataImpl::KillChildren( IN HSCOPEITEM hParent, IN UINT nOpenErrorMsg, IN BOOL fFileNodesOnly, IN BOOL fContinueOnOpenSheet ) /*++
Routine Description:
Kill all children of a given parent node.
Arguments:
HSCOPEITEM hParent : The infanticidal parent handle UINT nOpenErrorMsg : Error indicating open prop sheet BOOL fFileNodesOnly : TRUE to delete only file nodes BOOL fContinueOnOpenSheet : TRUE to continue on open sheet error
Return Value:
TRUE if the nodes were deleted successfully -- FALSE if an open property sheet prevents deletions.
--*/ { ASSERT(m_pScope != NULL); ASSERT(nOpenErrorMsg > 0);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HSCOPEITEM hChildItem; MMC_COOKIE cookie;
//
// If a property sheet is open for this item, don't
// allow deletion.
//
LPPROPERTYSHEETPROVIDER piPropertySheetProvider = NULL;
CError err(m_pConsole->QueryInterface( IID_IPropertySheetProvider, (void **)&piPropertySheetProvider ));
if (err.MessageBoxOnFailure()) { return FALSE; }
CWaitCursor wait;
if (!fFileNodesOnly) { //
// Loop through and find open property sheets on the
// nodes.
//
err = m_pScope->GetChildItem(hParent, &hChildItem, &cookie);
while (err.Succeeded() && hChildItem != NULL) { CIISObject * pObject = (CIISObject *)cookie; HSCOPEITEM hTarget = NULL;
if (FindOpenPropSheetOnNodeAndDescendants( piPropertySheetProvider, cookie )) { ::AfxMessageBox(nOpenErrorMsg);
if (!fContinueOnOpenSheet) { return FALSE; } }
//
// Advance to next child of the same parent.
//
err = m_pScope->GetNextItem(hChildItem, &hChildItem, &cookie); } }
//
// Having ensured that no relevant property sheets remain open,
// we can start committing infanticide.
//
err = m_pScope->GetChildItem(hParent, &hChildItem, &cookie);
while (err.Succeeded() && hChildItem != NULL) { CIISObject * pObject = (CIISObject *)cookie; TRACEEOLID("Deleting: " << pObject->GetNodeName()); HSCOPEITEM hTarget = NULL;
if (!fFileNodesOnly || pObject->IsFileSystemNode()) { if (FindOpenPropSheetOnNodeAndDescendants( piPropertySheetProvider, cookie )) { //
// Can't kill this one then, display error, but continue
//
TRACEEOLID("Unable to kill child -- sheet open shouldn't happen!"); ASSERT(FALSE && "Should have been closed in the first pass");
//
// Message for retail. How did he do it?
//
::AfxMessageBox(nOpenErrorMsg); if (!fContinueOnOpenSheet) { return FALSE; } } else { //
// Remember that this one is to be deleted.
//
hTarget = hChildItem; } }
//
// Advance to next child of the same parent.
//
err = m_pScope->GetNextItem(hChildItem, &hChildItem, &cookie);
if (hTarget) { //
// Delete the item we remembered earlier. This has to be done
// after the GetNextItem() otherwise the hChildItem would be
// bogus
//
HRESULT hr2 = m_pScope->DeleteItem(pObject->GetScopeHandle(), TRUE); delete pObject; } }
piPropertySheetProvider->Release();
return TRUE; }
HSCOPEITEM CComponentDataImpl::FindNextInstanceSibling( IN HSCOPEITEM hParent, IN CIISObject * pObject, OUT BOOL * pfNext ) /*++
Routine Descritpion:
Find the 'next' or 'previous' instance sibling of the given object. That is, the instance we want to be inserted just in front of, or right after.
Arguments:
HSCOPEITEM hParent : Parent scope item CIISObject * pObject : IISObject to be placed BOOL * pfNext : Returns TRUE if sibling returned is Next, FALSE if sibling is previous, undetermined if sibling returned is NULL.
Return Value:
The 'next' or 'previous' sibling item (scope item handle) that the pObject is to be inserted in front of, or right after (check *pfNext), or else NULL.
--*/ { //
// Want to group by service type. Find an appropriate
// sibling. Second key is instance ID.
//
MMC_COOKIE cookie; int nResult; HSCOPEITEM hItem; HSCOPEITEM hSibling = NULL; LPCTSTR lpSvcName = pObject->GetServiceName(); DWORD dwID = pObject->QueryInstanceID(); *pfNext = TRUE;
TRACEEOLID("Service name: " << lpSvcName); TRACEEOLID("Instance ID#: " << dwID);
BOOL fFoundSvc = FALSE; HRESULT hr = m_pScope->GetChildItem(hParent, &hItem, &cookie);
while (hr == S_OK && hItem != NULL) { CIISObject * p = (CIISObject *)cookie; ASSERT(p != NULL); TRACEEOLID("Comparing against service: " << p->GetServiceName()); nResult = lstrcmpi(lpSvcName, p->GetServiceName());
if (nResult == 0) { //
// Found same service type, now sort on instance ID
//
fFoundSvc = TRUE; hSibling = hItem; *pfNext = FALSE;
DWORD dw = p->QueryInstanceID(); TRACEEOLID("Comparing against instance ID#: " << dw);
if (dwID <= dw) { *pfNext = TRUE; break; } } else if (nResult < 0) { //
// Needs to be inserted before this one.
//
if (!fFoundSvc) { hSibling = hItem; *pfNext = TRUE; }
break; }
hr = m_pScope->GetNextItem(hItem, &hItem, &cookie); }
return hSibling; }
HSCOPEITEM CComponentDataImpl::FindNextVDirSibling( IN HSCOPEITEM hParent, IN CIISObject * pObject ) /*++
Routine Descritpion:
Find the 'next' virtual directory sibling of the given object. That is, the vdir we want to be inserted just in front of.
Arguments:
HSCOPEITEM hParent : Parent scope item CIISObject * pObject : IISObject to be placed
Return Value:
The 'next' sibling item (scope item handle) that the pObject is to be inserted in front of, or else NULL
--*/ { //
// Since VDIRs always are at the top of their list, the first
// item with a different GUID is our 'next' sibling
//
HSCOPEITEM hItem; MMC_COOKIE cookie; GUID guid1 = pObject->QueryGUID();
HRESULT hr = m_pScope->GetChildItem(hParent, &hItem, &cookie);
while (hr == S_OK && hItem != NULL) { CIISObject * p = (CIISObject *)cookie; ASSERT(p != NULL); GUID guid2 = p->QueryGUID();
if (guid1 != guid2) { //
// Want to insert before this one
//
return hItem; }
hr = m_pScope->GetNextItem(hItem, &hItem, &cookie); }
//
// Nothing found
//
return NULL; }
HSCOPEITEM CComponentDataImpl::FindServerInfoParent( IN HSCOPEITEM hParent, IN CServerInfo * pServerInfo ) /*++
Routine Description:
Find server info parent object for this object. The server info parent depends on the type of view, and can be a machine node, or a service collector node.
Arguments:
HSCOPEITEM hParent : Parent scope CServerInfo * pServerInfo
Return Value:
The scope item handle of the appropriate parent object, or NULL if not found.
--*/ { ASSERT(m_pScope != NULL);
//
// Notes: The server info object parent is always a machine
// node. Find the one that maches the computer name.
//
HSCOPEITEM hItem; MMC_COOKIE cookie;
HRESULT hr = m_pScope->GetChildItem(hParent, &hItem, &cookie); while (hr == S_OK && hItem != NULL) { CIISObject * pObject = (CIISObject *)cookie;
//
// Skip objects that we don't own
//
if (pObject != NULL) { ASSERT(pObject->QueryGUID() == cMachineNode);
//
// Compare computer names
//
CIISMachine * pMachine = (CIISMachine *)pObject;
if (::lstrcmpi(pServerInfo->QueryServerName(), pMachine->GetMachineName()) == 0) { //
// Found the item
//
return hItem; } }
//
// Advance to next child of the same parent.
//
hr = m_pScope->GetNextItem(hItem, &hItem, &cookie); }
//
// Not found
//
return NULL; }
HSCOPEITEM CComponentDataImpl::ForceAddServerInfoParent( IN HSCOPEITEM hParent, IN CServerInfo * pServerInfo ) /*++
Routine Description:
Add a serverinfo object to the scope view
Arguments:
HSCOPEITEM hParent : Handle to parent scope item CServerInfo * pServerInfo : Server info object
Return Value:
Handle to the scope item of the newly inserted object
--*/ { //
// Server info parents are always machine nodes now.
//
CIISMachine * pMachine = new CIISMachine(pServerInfo->QueryServerName()); pMachine->m_fIsExtension = m_fIsExtension; return AddIISObject(hParent, pMachine); }
HSCOPEITEM CComponentDataImpl::AddServerInfoParent( IN HSCOPEITEM hRootNode, IN CServerInfo * pServerInfo ) /*++
Routine Description:
Add server info parent object appropriate for the given object. Look to see if one exists, otherwise add one. Return the handle to the parent object.
Arguments:
HSCOPEITEM hRootNode : Root of the scope view CServerInfo * pServerInfo : Server info object, whose parent we add
Return Value:
Scope view handle to a suitable server info parent object
--*/ { HSCOPEITEM hParent = FindServerInfoParent(hRootNode, pServerInfo);
if (hParent == NULL) { //
// Parent doesn't exist, add it
//
hParent = ForceAddServerInfoParent(hRootNode, pServerInfo); }
return hParent; }
HSCOPEITEM CComponentDataImpl::AddServerInfo( IN HSCOPEITEM hRootNode, IN CServerInfo * pServerInfo, IN BOOL fAddParent ) /*++
Routine Description:
Add a serverinfo object to the scope view. Find suitable parent object, and attach to it.
Arguments:
HSCOPEITEM hRootNode : Parent scope item handle CServerInfo * pServerInfo : Server info object to be added. BOOL fAddParent : TRUE to add parent item, FALSE to add to the given parent scope item
Return Value:
Handle to the newly added object.
--*/ { HSCOPEITEM hItem = NULL; HSCOPEITEM hParent = fAddParent ? AddServerInfoParent(hRootNode, pServerInfo) : hRootNode;
CError err;
ASSERT(hParent != NULL);
try { //
// Add it underneath the parent
//
if (!pServerInfo->SupportsInstances()) { //
// No instance support for this service
// type. Add a single down-level instance
//
CIISInstance * pInstance = new CIISInstance(pServerInfo); BOOL fNext; HSCOPEITEM hSibling = FindNextInstanceSibling( hParent, pInstance, &fNext );
hItem = AddIISObject(hParent, pInstance, hSibling, fNext); } else { //
// Add all virtual hosts (instances) at the same level
// as a single instance item. Temporarily wrap this
// in a down-level instance.
//
CIISInstance inst(pServerInfo); hItem = AddInstances(hParent, &inst); } } catch(CMemoryException * e) { hItem = NULL; err = ERROR_NOT_ENOUGH_MEMORY; e->Delete(); }
if (err.Failed()) { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); err.MessageBox(); }
return hItem; }
//
// CODEWORK: Mess, should merge with AddFileSystem in results
//
HSCOPEITEM CComponentDataImpl::AddFileSystem( IN HSCOPEITEM hParent, IN LPCTSTR lpstrRoot, IN LPCTSTR lpstrMetaRoot, IN CIISInstance * pInstance, IN BOOL fGetDirs, IN BOOL fDeleteCurrentFileSystem ) /*++
Routine Description:
Add file system objects on the scope side
Arguments:
HSCOPEITEM hParent : Parent scope item LPCTSTR lpstrRoot : Phsysical root path LPCTSTR lpstrMetaRoot : Meta root path CIISInstance * pInstance : Owner instance BOOL fGetDirs : TRUE to get directories, FALSE for files BOOL fDeleteCurrentFileSystem : TRUE to remove the current file/dir tree first
Return Value:
Handle to the last scope item added.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
ASSERT(hParent != NULL);
CError err; HSCOPEITEM hItem = NULL; DWORD dwBufferSize = 0L; int cChildren = 0;
do { if (fDeleteCurrentFileSystem) { TRACEEOLID("Deleting current file enumeration");
if (!KillChildren( hParent, IDS_PROP_OPEN_CONTINUE, DELETE_FILES_ONLY, CONTINUE_ON_OPEN_SHEET )) { //
// Failed to remove the file system that was already enumerated
// here. An error message will already have been displayed, so
// quit gracefully here.
//
break; } }
LPCTSTR lpstrOwner = pInstance->GetMachineName(); ASSERT(lpstrOwner);
//
// Turn the path into a UNC path
//
CString strDir;
if (::IsServerLocal(lpstrOwner) || ::IsUNCName(lpstrRoot)) { //
// Local directory, or already a unc path
//
strDir = lpstrRoot; } else { ::MakeUNCPath(strDir, lpstrOwner, lpstrRoot); }
strDir.TrimLeft(); strDir.TrimRight();
if (strDir.IsEmpty()) { //
// Invalid path
//
break; }
strDir += _T("\\*"); WIN32_FIND_DATA w32data; HANDLE hFind = ::FindFirstFile(strDir, &w32data);
if (hFind == INVALID_HANDLE_VALUE) { err.GetLastWinError(); break; }
//
// See if the parent has a redirect on it
//
CWaitCursor wait; CString strRedirect; CString strBase; pInstance->BuildFullPath(strBase, TRUE); LPCTSTR lpPath = lpstrMetaRoot;
while (lpPath && *lpPath && *lpPath != _T('/')) ++lpPath;
if (lpPath && *lpPath) { strBase += lpPath; }
TRACEEOLID("Opening: " << strBase); TRACEEOLID(lpstrMetaRoot);
BOOL fCheckMetabase = TRUE; CMetaKey mk( lpstrOwner, METADATA_PERMISSION_READ, METADATA_MASTER_ROOT_HANDLE, strBase ); CError errMB(mk.QueryResult());
if (errMB.Win32Error() == ERROR_PATH_NOT_FOUND) { //
// Metabase path not found, not a problem.
//
TRACEEOLID("Parent node not in metabase"); fCheckMetabase = FALSE; errMB.Reset(); } else if (!errMB.MessageBoxOnFailure()) { //
// Opened successfully, read redirect string.
//
DWORD dwAttr;
errMB = mk.QueryValue( MD_HTTP_REDIRECT, strRedirect, NULL, // Inheritance override
NULL, // Path
&dwAttr );
if (errMB.Succeeded()) { if (IS_FLAG_SET(dwAttr, METADATA_INHERIT)) { int nComma = strRedirect.Find(_T(','));
if (nComma >= 0) { strRedirect.ReleaseBuffer(nComma); } } else { //
// Yes, there's a redirect on the parent, but it's
// not marked as inheritable, so it won't affect
// the children.
//
strRedirect.Empty(); } } }
//
// Loop through the file system
//
do { //
// Check to see if this is a file or directory/
// Ignore anything starting with a dot.
//
TRACEEOLID(w32data.cFileName); BOOL fIsDir = ((w32data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
if (fIsDir == fGetDirs && *w32data.cFileName != _T('.')) { CIISFileNode * pNode = new CIISFileNode( w32data.cFileName, w32data.dwFileAttributes, pInstance, strRedirect, fIsDir );
if (pNode == NULL) { err = ERROR_NOT_ENOUGH_MEMORY; break; }
if (fCheckMetabase) { errMB = mk.DoesPathExist(w32data.cFileName);
ASSERT(errMB.Succeeded() || errMB.Win32Error() == ERROR_PATH_NOT_FOUND);
if (errMB.Succeeded()) { //
// Match up with metabase properties. If the item
// is found in the metabase with a non-inherited vrpath,
// than a virtual root with this name exists, and this
// file/directory should not be shown.
//
BOOL fVirtualDirectory; CString strMetaRoot(lpstrMetaRoot);
if (pNode->FetchMetaInformation( strMetaRoot, &fVirtualDirectory ) == ERROR_SUCCESS && fVirtualDirectory) { TRACEEOLID( "file/directory exists as vroot -- tossing" << w32data.cFileName ); delete pNode;
continue; } } }
//
// Always added on at the end
//
hItem = AddIISObject(hParent, pNode); } } while(err.Succeeded() && FindNextFile(hFind, &w32data));
::FindClose(hFind); } while(FALSE);
if (err.Failed()) { //
// Don't display file system errors -- leave those to result side
// enumeration.
//
TRACEEOLID("Ate error message: " << err); }
return hItem; }
HSCOPEITEM CComponentDataImpl::AddVirtualRoots( IN HSCOPEITEM hParent, IN LPCTSTR lpstrParentPath, IN CIISInstance * pInstance ) /*++
Routine Description:
Add virtual roots to the scope view
Arguments:
HSCOPEITEM hParent : Handle to parent scope item LPCTSTR lpstrParentPath : Parent metabase path CIISInstance * pInstance : Owner instance
Return Value:
Handle to the newly added scope item
--*/ { ASSERT(hParent != NULL); CServerInfo * pServerInfo = pInstance->GetServerInfo(); ASSERT(pServerInfo != NULL);
ISMCHILDINFO ii; HSCOPEITEM hItem = NULL; DWORD dwIndex = 0L; CError err;
ZeroMemory(&ii, sizeof(ii)); ii.dwSize = sizeof(ii); HANDLE hEnum = NULL;
FOREVER { DWORD dwID = pInstance->QueryID(); err = pServerInfo->ISMEnumerateChildren( &ii, &hEnum, dwID, lpstrParentPath );
if (err.Failed()) { break; }
TRACEEOLID("Alias: " << ii.szAlias); TRACEEOLID("Path : " << ii.szPath); TRACEEOLID("Redir: " << ii.szRedirPath);
if (*ii.szPath) { CIISChildNode * pChild = new CIISChildNode(&ii, pInstance); if (pChild == NULL) { err = ERROR_NOT_ENOUGH_MEMORY; break; }
//
// Always added on at the end
//
hItem = AddIISObject(hParent, pChild); } else { TRACEEOLID("Tossing child without vrpath"); } }
if (err.Win32Error() == ERROR_NO_MORE_ITEMS) { //
// This is the normal way to end this
//
err.Reset(); }
if (err.Failed()) { //
// Display error
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
err.MessageBoxFormat( IDS_ERR_ENUMERATE_CHILD, MB_OK, NO_HELP_CONTEXT, (LPCTSTR)pServerInfo->GetServiceInfo()->GetShortName() ); }
return hItem; }
HSCOPEITEM CComponentDataImpl::AddInstances( IN HSCOPEITEM hParent, IN CIISObject * pObject ) /*++
Routine Description:
Add instances to the treeview
Arguments:
HSCOPEITEM hParent : Parent scope item handle CIISObject * pObject : Owning object
Return Value:
Handle to the last instance added
--*/ { ASSERT(hParent != NULL); CServerInfo * pServerInfo = pObject->GetServerInfo(); ASSERT(pServerInfo != NULL);
ISMINSTANCEINFO ii; HSCOPEITEM hItem = NULL; DWORD dwIndex = 0L; CError err;
ZeroMemory(&ii, sizeof(ii)); ii.dwSize = sizeof(ii); HANDLE hEnum = NULL;
HSCOPEITEM hSibling = NULL;
FOREVER { //
// Loop through...
//
err = pServerInfo->ISMEnumerateInstances(&ii, &hEnum);
if (err.Failed()) { break; }
if (ii.dwError == ERROR_ACCESS_DENIED) { //
// No point in listing this one
//
continue; }
CIISInstance * pInstance = new CIISInstance(&ii, pServerInfo); if (pInstance == NULL) { err = ERROR_NOT_ENOUGH_MEMORY; break; }
//
// Add grouped by service type
//
BOOL fNext;
if (hSibling == NULL) { hSibling = FindNextInstanceSibling( hParent, pInstance, &fNext ); } else { //
// Keep appending
//
fNext = FALSE; }
hSibling = hItem = AddIISObject( hParent, pInstance, hSibling, fNext ); } if (err.Win32Error() == ERROR_NO_MORE_ITEMS) { //
// This is the normal way to end this
//
err.Reset(); }
if (err.Failed()) { //
// Display error message
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
switch(err.Win32Error()) { //
// Non-fatal errors
//
case ERROR_PATH_NOT_FOUND: case ERROR_NOT_ENOUGH_MEMORY: case ERROR_FILE_NOT_FOUND: ::AfxMessageBox(IDS_NON_FATAL_ERROR_INSTANCES); err.Reset(); break; default: err.MessageBoxFormat( IDS_ERR_ENUMERATE_INST, MB_OK, NO_HELP_CONTEXT, (LPCTSTR)pServerInfo->GetServiceInfo()->GetShortName() ); } }
return hItem; }
|