|
|
/*++
Copyright (c) 1994-2000 Microsoft Corporation
Module Name : websvcext.cpp
Abstract: IIS RestrictionList
Author: Aaron Lee (aaronl)
Project: Internet Services Manager
Revision History: 03/19/2002 aaronl Initial creation
--*/ #include "stdafx.h"
#include "common.h"
#include "inetprop.h"
#include "InetMgrApp.h"
#include "iisobj.h"
#include "util.h"
#include "shts.h"
#include "websvcext_sheet.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
#define new DEBUG_NEW
extern CInetmgrApp theApp; extern int g_IISMMCInstanceCount; #if defined(_DEBUG) || DBG
extern CDebug_IISObject g_Debug_IISObject; CDebug_RestrictList g_Debug_RestrictList; #endif
#define HIDD_WEBSVCEXT_PROHIBIT_ALL 0x101
#define HIDD_WEBSVCEXT_UNKNOWN_ISAPI 0x102
#define HIDD_WEBSVCEXT_UNKNOWN_CGI 0x103
#define WEBSVCEXT_RESULTS_COL_WIDTH_0 20 // icon
#define WEBSVCEXT_RESULTS_COL_WIDTH_1 180 // description
#define WEBSVCEXT_RESULTS_COL_WIDTH_2 70 // status
#define BAD_CHARS_FOR_HTML_PANE _T("&")
#define WEBSVCEXT_HELP_PATH _T("::/htm/ca_enabledynamiccontent.htm")
CWebServiceExtensionContainer * g_pCurrentlyDisplayedContainer = NULL;
// ==========================================
CWebServiceExtensionContainer::CWebServiceExtensionContainer( CIISMachine * pOwner, CIISService * pService ) : CIISMBNode(pOwner, SZ_MBN_WEB), m_pWebService(pService), m_pResultData(NULL), m_dwResultDataCachedSignature(0) { VERIFY(m_bstrDisplayName.LoadString(IDS_WEBSVCEXT_CONTAINER)); m_strLastResultSelectionID = _T(""); m_iResultPaneCount = 0; #if defined(_DEBUG) || DBG
g_Debug_RestrictList.Init(); #endif
}
CWebServiceExtensionContainer::~CWebServiceExtensionContainer() { m_strLastResultSelectionID = _T(""); m_iResultPaneCount = 0;
// Erase all of the extensions that are under us...
if (!m_WebSvcExtensionList.IsEmpty()) { CWebServiceExtension * pItem = NULL; POSITION pos = m_WebSvcExtensionList.GetHeadPosition(); while (pos) { pItem = m_WebSvcExtensionList.GetNext(pos); if (pItem) { delete pItem;pItem = NULL; } } m_WebSvcExtensionList.RemoveAll(); }
#if defined(_DEBUG) || DBG
// see if we leaked anything
g_Debug_RestrictList.Dump(TRUE); #endif
}
HRESULT CWebServiceExtensionContainer::GetContextHelp(CString& strHtmlPage) { strHtmlPage = WEBSVCEXT_HELP_PATH; return S_OK; }
/* virtual */ void CWebServiceExtensionContainer::InitializeChildHeaders(LPHEADERCTRL lpHeader) { CWebServiceExtension::InitializeHeaders(lpHeader); }
/* virtual */ HRESULT CWebServiceExtensionContainer::ForceReportMode(IResultData * pResult) const { LONG lViewMode = 0;
if (SUCCEEDED(pResult->GetViewMode(&lViewMode))) { if (MMCLV_VIEWSTYLE_REPORT != lViewMode) { // whoops, bad mode.
// user can only see icon with no description.
// set it to a better one.
pResult->SetViewMode(MMCLV_VIEWSTYLE_REPORT); } } return S_OK; }
/* virtual */ HRESULT CWebServiceExtensionContainer::GetResultViewType( LPOLESTR * lplpViewType, long * lpViewOptions ) { *lplpViewType = NULL; *lpViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
// S_FALSE to use default view type, S_OK indicates the
// view type is returned in *ppViewType
return S_OK; }
HRESULT CWebServiceExtensionContainer::SelectResultPaneSelectionID(IResultData * pResultData,CString strSelectionID) { HRESULT hr; CIISObject * pItem = NULL; CWebServiceExtension * pItemFromMMC = NULL;
if (!pResultData) { return E_POINTER; } if (strSelectionID.IsEmpty()) { return S_OK; }
//
// loop thru all the result items and clean then out.
//
RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STATE; rdi.nIndex = -1; // -1 to start at first item
do { rdi.lParam = 0; hr = pResultData->GetNextItem(&rdi); if (hr != S_OK){break;} //
// The cookie is really the IISObject, which is what we stuff
// in the lparam.
//
pItem = (CIISObject *)rdi.lParam; ASSERT_PTR(pItem);
if (IsEqualGUID(* (GUID *) pItem->GetNodeType(),cWebServiceExtension)) { pItemFromMMC = (CWebServiceExtension *)rdi.lParam;
// Get the ID
if (pItemFromMMC->QueryContainer() == this) { if (0 == strSelectionID.CompareNoCase(pItemFromMMC->m_RestrictionUIEntry.strGroupID)) { pItemFromMMC->UpdateResultItem(pResultData,TRUE); } } }
} while (SUCCEEDED(hr) && -1 != rdi.nIndex);
return S_OK; }
HRESULT CWebServiceExtensionContainer::QueryResultPaneSelectionID(IResultData * pResultData,CString &strLastResultSelectionID) { HRESULT hr; CIISObject * pItem = NULL; CWebServiceExtension * pItemFromMMC = NULL;
if (!pResultData) { return E_POINTER; }
//
// loop thru all the result items and clean then out.
//
RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STATE; rdi.nIndex = -1; // -1 to start at first item
rdi.nState = LVIS_SELECTED | LVIS_FOCUSED; // only interested in selected items
do { rdi.lParam = 0; hr = pResultData->GetNextItem(&rdi); if (hr != S_OK){break;} //
// The cookie is really the IISObject, which is what we stuff
// in the lparam.
//
pItem = (CIISObject *)rdi.lParam; ASSERT_PTR(pItem);
if (IsEqualGUID(* (GUID *) pItem->GetNodeType(),cWebServiceExtension)) { pItemFromMMC = (CWebServiceExtension *)rdi.lParam;
// Get the ID
// and return that back.
if (pItemFromMMC->QueryContainer() == this) { strLastResultSelectionID = pItemFromMMC->m_RestrictionUIEntry.strGroupID; } }
} while (SUCCEEDED(hr) && -1 != rdi.nIndex);
return S_OK; }
/* virtual */ HRESULT CWebServiceExtensionContainer::EnumerateResultPane(BOOL fExpand, IHeaderCtrl * lpHeader, IResultData * lpResultData, BOOL fForRefresh) { if (lpResultData) { m_pResultData = lpResultData;
DWORD * pdwOneDword = (DWORD*) lpResultData; m_dwResultDataCachedSignature = *pdwOneDword; } m_iResultPaneCount = 0; BOOL bUseCached = FALSE;
CError err = CIISObject::EnumerateResultPane(fExpand, lpHeader, lpResultData, fForRefresh); if (err.Succeeded()) { if (m_WebSvcExtensionList.IsEmpty()) {
#if defined(_DEBUG) || DBG
// see if we leaked anything
g_Debug_RestrictList.Dump(TRUE); #endif
err = EnumerateWebServiceExtensions(&m_WebSvcExtensionList); } else { bUseCached = TRUE; } if (err.Succeeded()) { if (fExpand) { if (bUseCached) { TRACEEOL(_T("Read from Cache...")); } else { TRACEEOL(_T("Read from Metabase (not cache)...")); }
CWebServiceExtension * pItem = NULL; POSITION pos = m_WebSvcExtensionList.GetHeadPosition(); int iSelectItem = TRUE; BOOL bSomethingWasSelected = FALSE; void ** ppParam = NULL; while (pos) { pItem = m_WebSvcExtensionList.GetNext(pos); ppParam = (void **) pItem; if (IsValidAddress( (const void*) *ppParam,sizeof(void*),FALSE)) { // Select the 1st item in the list...
if (!bSomethingWasSelected) { if (!m_strLastResultSelectionID.IsEmpty()) { if (0 == pItem->m_RestrictionUIEntry.strGroupID.CompareNoCase(m_strLastResultSelectionID)) { iSelectItem = TRUE; bSomethingWasSelected = TRUE; } } }
if (bUseCached) { // then don't addref, since we already did it once...
err = pItem->AddToResultPaneSorted(lpResultData,iSelectItem,FALSE); } else { err = pItem->AddToResultPaneSorted(lpResultData,iSelectItem,TRUE); } }
m_iResultPaneCount++;
// make sure no other entires are selected.
iSelectItem = FALSE; }
if (lpResultData) { lpResultData->ModifyViewStyle(MMC_SHOWSELALWAYS, (MMC_RESULT_VIEW_STYLE)0); }
// if we used the stuff from the Cache,
// then reload from metabase. since we'll only have
// really one entry in this list....(Whatever entry that the user had a property page open on)
if (bUseCached) { this->RefreshData(); }
g_pCurrentlyDisplayedContainer = this; } else { // user clicked away from this container node...
// Save whatever the user had selected...
QueryResultPaneSelectionID(lpResultData,m_strLastResultSelectionID); if (lpResultData) { // Clean everything and cache stuff that's not cleaned.
// Cache any entries that were not cleaned.
err = CacheResult(lpResultData); }
// User is not selected on this one anymore
g_pCurrentlyDisplayedContainer = NULL; } }
DisplayError(err); return err; }
return err; }
HRESULT CWebServiceExtensionContainer::EnumerateWebServiceExtensions(CExtensionList * pList) { ASSERT(pList != NULL); CError err;
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { CRestrictionUIList MyMetabaseRestrictionUIList; err = LoadMasterUIWithoutOldEntry(QueryInterface(),&MyMetabaseRestrictionUIList,NULL); if (err.Succeeded()) { POSITION pos = NULL; CString TheKey;
// Loop thru the ui list and display those...
CRestrictionUIEntry * pOneEntry = NULL; for(pos = MyMetabaseRestrictionUIList.GetStartPosition();pos != NULL;) { MyMetabaseRestrictionUIList.GetNextAssoc(pos, TheKey, (CRestrictionUIEntry *&) pOneEntry); if (pOneEntry) { CWebServiceExtension * pItem = NULL;
// creating this CWebServiceExtension makes a copy
// of the data in pOneEntry. so after we're done
// make sure to delete the MyMetabaseRestrictionUIList list
// and all it's objects...
if (NULL == (pItem = new CWebServiceExtension(m_pOwner, pOneEntry, m_pWebService))) { err = ERROR_NOT_ENOUGH_MEMORY; break; } pList->AddTail(pItem); } } // delete the list and delete all it's objects too.
CleanRestrictionUIList(&MyMetabaseRestrictionUIList); } } return err; }
/* virtual */ HRESULT CWebServiceExtensionContainer::AddMenuItems( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback, IN OUT long * pInsertionAllowed, IN DATA_OBJECT_TYPES type ) { ASSERT_READ_PTR(lpContextMenuCallback);
//
// Add base menu items
//
HRESULT hr = CIISObject::AddMenuItems( lpContextMenuCallback, pInsertionAllowed, type );
if (SUCCEEDED(hr)) { ASSERT(pInsertionAllowed != NULL); if (IsAdministrator()) { if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0) { AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_CONTAINER_ADD1); AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_CONTAINER_ADD2); AddMenuSeparator(lpContextMenuCallback); AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_CONTAINER_PROHIBIT_ALL); } } }
return hr; }
/* virtual */ LPOLESTR CWebServiceExtensionContainer::GetResultPaneColInfo(int nCol) { if (nCol == 0) { return QueryDisplayName(); } return OLESTR(""); }
HRESULT CWebServiceExtensionContainer::Command( long lCommandID, CSnapInObjectRootBase * pObj, DATA_OBJECT_TYPES type ) { HRESULT hr = S_OK; IConsole * pConsole = (IConsole *)GetConsole();
switch (lCommandID) { case IDM_WEBEXT_CONTAINER_ADD1: { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { CRestrictionUIEntry * pNewEntry = NULL;
// ensure the dialog gets themed
CThemeContextActivator activator(theApp.GetFusionInitHandle()); if (TRUE == StartAddNewDialog(GetMainWindow(pConsole),QueryInterface(),IsLocal(),&pNewEntry)) { // Update the UI
if (pNewEntry) { InsertNewExtension(pNewEntry); // InsertNewExtension will call RefreshData()
// so we don't have to do it out here...
// refresh after insertion...
//if (SUCCEEDED(RefreshData())){RefreshDisplay();}
} } } } break; case IDM_WEBEXT_CONTAINER_ADD2: { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { // ensure the dialog gets themed
CThemeContextActivator activator(theApp.GetFusionInitHandle()); if (TRUE == StartAddNewByAppDialog(GetMainWindow(pConsole),QueryInterface(),IsLocal())) { // refresh all of the UI..
if (SUCCEEDED(RefreshData())) { RefreshDisplay(); } } } } break; case IDM_WEBEXT_CONTAINER_PROHIBIT_ALL: { CError err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { CComBSTR strMsg; strMsg.LoadString(IDS_PROHIBIT_ALL_EXTENSIONS_MSG);
UINT iHelpID = HIDD_WEBSVCEXT_PROHIBIT_ALL; if (IDYES == DoHelpMessageBox(NULL,strMsg,MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2 | MB_HELP, iHelpID)) { hr = ChangeStateOfEntry(QueryInterface(),WEBSVCEXT_STATUS_PROHIBITED,NULL); if (SUCCEEDED(hr) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { if (SUCCEEDED(hr = RefreshData())) { RefreshDisplay(); } } } } } break;
//
// Pass on to base class
//
default: hr = CIISMBNode::Command(lCommandID, pObj, type); }
return hr; }
HRESULT CWebServiceExtensionContainer::CacheResult(IResultData * pResultData) { HRESULT hr; CIISObject * pItem = NULL; CWebServiceExtension * pItemFromMMC = NULL; CExtensionList MyDeleteList;
if (!pResultData) { return E_POINTER; }
m_WebSvcExtensionList.RemoveAll(); m_iResultPaneCount=0;
// Loop thru all the result items and add it to our
// List of extensions....
RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STATE; rdi.nIndex = -1; // -1 to start at first item
do { rdi.lParam = 0; hr = pResultData->GetNextItem(&rdi); if (hr != S_OK){break;} //
// The cookie is really the IISObject, which is what we stuff
// in the lparam.
//
pItem = (CIISObject *)rdi.lParam; ASSERT_PTR(pItem);
if (pItem) { if (IsEqualGUID(* (GUID *) pItem->GetNodeType(),cWebServiceExtension)) { pItemFromMMC = (CWebServiceExtension *)rdi.lParam;
// Check if it points to this container!
if (pItemFromMMC->QueryContainer() == this) { // add it to our "cache" list if it has a property window open
m_WebSvcExtensionList.AddTail(pItemFromMMC); m_iResultPaneCount++; } } }
} while (SUCCEEDED(hr) && -1 != rdi.nIndex);
// loop thru the list of objects
// that we need to delete
if (!MyDeleteList.IsEmpty()) { POSITION pos = MyDeleteList.GetHeadPosition(); while (pos) { pItemFromMMC = MyDeleteList.GetNext(pos); if (pItemFromMMC) { // remove it from the UI
if (FAILED(pItemFromMMC->FindMyResultItem(pResultData,TRUE))) { pResultData->DeleteItem(pItemFromMMC->QueryResultItem(), 0); } // clean data
CleanRestrictionUIEntry(&pItemFromMMC->m_RestrictionUIEntry);
// mark it for deletion.
pItemFromMMC->m_fFlaggedForDeletion = TRUE; // delete the object
// Don't delete the result item if another window has it open!
// (if there are other console's open
// then they are also displaying these result objects
// don't delete these objects if there are other consoles open...)
if (g_IISMMCInstanceCount <= 1) { pItemFromMMC->Release(); } } } }
return S_OK; }
/*virtual*/ HRESULT CWebServiceExtensionContainer::CleanResult(IResultData * pResultData) { HRESULT hr; CIISObject * pItem = NULL; CWebServiceExtension * pItemFromMMC = NULL; CExtensionList MyDeleteList;
if (!pResultData) { return E_POINTER; }
// only cleanresults if
// there is only 1 instance of the console
//if (g_IISMMCInstanceCount > 1){return S_OK;}
// Clean our Cached list of objects...
m_WebSvcExtensionList.RemoveAll(); m_iResultPaneCount=0;
//
// loop thru all the result items and clean them out.
//
RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_PARAM | RDI_STATE; rdi.nIndex = -1; // -1 to start at first item
do { rdi.lParam = 0; hr = pResultData->GetNextItem(&rdi); if (hr != S_OK){break;} //
// The cookie is really the IISObject, which is what we stuff
// in the lparam.
//
pItem = (CIISObject *)rdi.lParam; ASSERT_PTR(pItem);
if (IsEqualGUID(* (GUID *) pItem->GetNodeType(),cWebServiceExtension)) { pItemFromMMC = (CWebServiceExtension *)rdi.lParam;
// delete the object by adding it to the delete list
// so that we can delete them later
//
// we can't delete items from the result pane while we enum thru the result pane
// things will be messed up in the result pane list....
// and you will end up only deleteing half of what you wanted to delete!
// Only delete an item if there is no property page open on it!
if (pItemFromMMC->QueryContainer() == this) { if (pItemFromMMC->IsMyPropertySheetOpen()) { // add it to our "cache" list if it has a property window open
m_WebSvcExtensionList.AddTail(pItemFromMMC); m_iResultPaneCount++; } else { MyDeleteList.AddTail(pItemFromMMC); } } }
} while (SUCCEEDED(hr) && -1 != rdi.nIndex);
// loop thru the list of objects
// that we need to delete
POSITION pos = MyDeleteList.GetHeadPosition(); while (pos) { pItemFromMMC = MyDeleteList.GetNext(pos); if (pItemFromMMC) { // remove it from the UI
if (FAILED(pItemFromMMC->FindMyResultItem(pResultData,TRUE))) { pResultData->DeleteItem(pItemFromMMC->QueryResultItem(), 0); }
// clean data
CleanRestrictionUIEntry(&pItemFromMMC->m_RestrictionUIEntry);
// mark it for deletion.
pItemFromMMC->m_fFlaggedForDeletion = TRUE;
// delete the object
// Don't delete the result item if another window has it open!
// (if there are other console's open
// then they are also displaying these result objects
// don't delete these objects if there are other consoles open...)
if (g_IISMMCInstanceCount <= 1) { pItemFromMMC->Release(); } } }
// don't do this since we could be cleaning out
// other result items which we don't own
//pResultData->DeleteAllRsltItems();
return S_OK; }
HRESULT CWebServiceExtensionContainer::InsertNewExtension(CRestrictionUIEntry * pNewEntry) { CError err;
IConsole * pConsole = (IConsole *)GetConsole();
CString strNewEntryID; if (-1 == pNewEntry->strGroupID.Find(EMPTY_GROUPID_KEY)) { m_strLastResultSelectionID = EMPTY_GROUPID_KEY + pNewEntry->strGroupID; strNewEntryID = EMPTY_GROUPID_KEY + pNewEntry->strGroupID; } else { m_strLastResultSelectionID = pNewEntry->strGroupID; strNewEntryID = pNewEntry->strGroupID; }
if (!IsExpanded() || NULL == g_pCurrentlyDisplayedContainer) { // make sure we are select first.
if (NULL != QueryScopeItem()) { pConsole->SelectScopeItem(QueryScopeItem()); }
// the above code will read the newly created item from the metabase
// we just need to find it now, and highlight it
SelectResultPaneSelectionID(m_pResultData,strNewEntryID);
if (SUCCEEDED(RefreshData())){RefreshDisplay();} } else { // insertion code can only be used
// for the currently selected container
// warning: you might be able to add remote computer items
// into the local result view, if you don't check this
if (this == g_pCurrentlyDisplayedContainer) { if (SUCCEEDED(RefreshData())){RefreshDisplay();} // Select the new entry...
SelectResultPaneSelectionID(m_pResultData,strNewEntryID);
// don't do all of this code below...
// since it will add a new entry to the results pane...
// however if we refresh, it could have a possibility to have duplicates...
/*
// Insert and select this new entry
CWebServiceExtension * pItem = new CWebServiceExtension(m_pOwner, this, pNewEntry, m_pWebService); if (pItem != NULL) { // don't call RefreshData, uless you want 2 of these new entries in the list...
//err = pItem->RefreshData();
if (err.Succeeded()) { // Get the pointer to ResultData from when we did the Enum
err = pItem->AddToResultPaneSorted(m_pResultData,TRUE); } } else { err = ERROR_NOT_ENOUGH_MEMORY; } */ } } return err; }
/*virtual*/ HRESULT CWebServiceExtensionContainer::RefreshData() { CError err; IResultData *pResultData = NULL; pResultData = m_pResultData;
if (!pResultData) { return S_OK; }
// Check validity of the IResultData Pointer!
if (m_dwResultDataCachedSignature) { DWORD * pdwOneDword = (DWORD*) pResultData; if (pdwOneDword) { if (m_dwResultDataCachedSignature != *pdwOneDword) { TRACEEOLID("Bad Signature:" << m_dwResultDataCachedSignature << " != " << *pdwOneDword); // This is an invalid signature!
return S_OK; } } }
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { HRESULT hr = E_FAIL; POSITION pos = NULL; CIISObject * pItem = NULL; CWebServiceExtension * pItemFromMMC = NULL; CRestrictionUIList MyMetabaseRestrictionUIList; CRestrictionUIList MyPrunedList; CExtensionList MyDeleteList;
BOOL bProceed = FALSE; BOOL bAddToRunningList = FALSE;
// Sync the stuff in our results list
// with the items that are in the metabase
// ----------------------------------------------------------
// 1st pass -- loop thru all the stuff in our list
// and make sure they have all the most
// updated info. removing same entry from metabase list.
// if entry is in UI but not in metabase, then
// remove the metabase entry.
// 2nd pass -- loop thru the left over metabase list entries.
// these are metabase items which are not in the UI.
// ----------------------------------------------------------
// Get the stuff from the metabase
err = LoadMasterUIWithoutOldEntry(QueryInterface(),&MyMetabaseRestrictionUIList,NULL); if (err.Failed()) { goto CWebServiceExtensionContainer_RefreshData_Exit; }
// ==============================
// 1st pass
// Loop through the result list
// ==============================
bProceed = FALSE;
RESULTDATAITEM rdi; ZeroMemory(&rdi, sizeof(rdi));
rdi.mask = RDI_PARAM | RDI_STATE; rdi.nIndex = -1; // -1 to start at first item
//rdi.nState = LVIS_SELECTED; // only interested in selected items
do { bAddToRunningList = FALSE; rdi.lParam = 0;
// this could AV right here if pResultData is invalid
hr = pResultData->GetNextItem(&rdi); if (hr != S_OK) { break; }
//
// The cookie is really the IISObject, which is what we stuff
// in the lparam.
//
pItem = (CIISObject *)rdi.lParam; ASSERT_PTR(pItem);
if (IsEqualGUID(* (GUID *) pItem->GetNodeType(),cWebServiceExtension)) { pItemFromMMC = (CWebServiceExtension *)rdi.lParam;
// check if it's for this container!
if (pItemFromMMC->QueryContainer() == this) { // check if our item is in the metabase list
// if it is then update it, if not then delete it
int iRet = UpdateItemFromItemInList(&pItemFromMMC->m_RestrictionUIEntry,&MyMetabaseRestrictionUIList); if (0 == iRet) { // no change
bAddToRunningList = TRUE; } else if (2 == iRet) { // This means that the item was not in the list
// so let's delete it, or mark it for deletion
// seem like we can't delete this item from within this loop
// so let's add it to a list of items to be deleted
MyDeleteList.AddTail(pItemFromMMC); bAddToRunningList = FALSE; } else { // the item was updated...
// so let's delete it from the Metabase List
DeleteItemFromList(&pItemFromMMC->m_RestrictionUIEntry,&MyMetabaseRestrictionUIList); bAddToRunningList = TRUE; }
bProceed = TRUE; } }
if (bAddToRunningList) { // add this RestrictionUI item to our running
// list of UI items that are in the UI
AddRestrictUIEntryToRestrictUIList(&MyPrunedList,&pItemFromMMC->m_RestrictionUIEntry);
// update the result panes icon,description,status...
pItemFromMMC->UpdateResultItem(pResultData,FALSE); }
//
// Advance to next child of same parent
//
} while (SUCCEEDED(hr) && -1 != rdi.nIndex);
// ==============================
// 2nd pass
// Loop through the metabase list
// ==============================
if (bProceed) { CRestrictionUIEntry * pOneEntry = NULL; CString strKey; CString strKey2;
for(pos = MyMetabaseRestrictionUIList.GetStartPosition();pos != NULL;) { MyMetabaseRestrictionUIList.GetNextAssoc(pos, strKey2, (CRestrictionUIEntry *&) pOneEntry); if (pOneEntry) { // see if this entry exists in the UI list
CRestrictionUIEntry * pItemExists = NULL; // THE KEY IS ALWAYS UPPERASE -- REMEMBER THIS!!!!!!!
strKey=pOneEntry->strGroupID;strKey.MakeUpper();
MyPrunedList.Lookup(strKey,pItemExists); if (!pItemExists) { // we expected that it would not be in the UI list
// so let's create a new entry and add it.
CWebServiceExtension * pNewExtension = NULL; if (NULL == (pNewExtension = new CWebServiceExtension(m_pOwner, pOneEntry, m_pWebService))) { err = ERROR_NOT_ENOUGH_MEMORY; break; } else { //add to results pane
err = pNewExtension->AddToResultPaneSorted(pResultData,TRUE); } } } }
// this one just points to entries that are still existing
// so just erase this list
MyPrunedList.RemoveAll(); }
// this one needs to be erased -- the list and all of it's data items...
CleanRestrictionUIList(&MyMetabaseRestrictionUIList);
// Loop thru the saved list of mmc entries
// we are supposed to delete, and remove them
pItemFromMMC = NULL; pos = MyDeleteList.GetHeadPosition(); BOOL bDeletedSomethingThatWasSelected = FALSE; while (pos) { pItemFromMMC = MyDeleteList.GetNext(pos); if (pItemFromMMC) { // check if this item is currently selected!
ZeroMemory(&rdi, sizeof(rdi)); rdi.mask = RDI_STATE; rdi.itemID = pItemFromMMC->QueryResultItem(); if (SUCCEEDED(pResultData->GetItem(&rdi))) { if (rdi.nState & LVIS_SELECTED) { bDeletedSomethingThatWasSelected = TRUE; } }
// mark it as going to be deleted
pItemFromMMC->m_fFlaggedForDeletion = TRUE; // remove from results pane!
if (FAILED(pItemFromMMC->FindMyResultItem(pResultData,TRUE))) { pResultData->DeleteItem(pItemFromMMC->QueryResultItem(), 0); } } }
if (bDeletedSomethingThatWasSelected) { // select something else (i guess we'll select the 1st item)
pResultData->ModifyItemState(0,0,LVIS_SELECTED | LVIS_FOCUSED,0); } }
CWebServiceExtensionContainer_RefreshData_Exit: return err; }
////////////////////////////////////////////////////////////////////////////////
// CWebServiceExtension implementation
//
// Result View definition
//
/* static */ int CWebServiceExtension::_rgnLabels[COL_TOTAL] = { IDS_RESULT_SERVICE_ICON, IDS_RESULT_SERVICE_WEBSVCEXT, IDS_RESULT_STATUS };
/* static */ int CWebServiceExtension::_rgnWidths[COL_TOTAL] = { WEBSVCEXT_RESULTS_COL_WIDTH_0, WEBSVCEXT_RESULTS_COL_WIDTH_1, WEBSVCEXT_RESULTS_COL_WIDTH_2 };
/* static */ CComBSTR CWebServiceExtension::_bstrStatusAllowed; /* static */ CComBSTR CWebServiceExtension::_bstrStatusProhibited; /* static */ CComBSTR CWebServiceExtension::_bstrStatusCustom; /* static */ CComBSTR CWebServiceExtension::_bstrStatusInUse; /* static */ CComBSTR CWebServiceExtension::_bstrStatusNotInUse; /* static */ CString CWebServiceExtension::_bstrMenuAllowOn; /* static */ CString CWebServiceExtension::_bstrMenuAllowOff; /* static */ CString CWebServiceExtension::_bstrMenuProhibitOn; /* static */ CString CWebServiceExtension::_bstrMenuProhibitOff; /* static */ CString CWebServiceExtension::_bstrMenuPropertiesOn; /* static */ CString CWebServiceExtension::_bstrMenuPropertiesOff; /* static */ CString CWebServiceExtension::_bstrMenuTasks; /* static */ CString CWebServiceExtension::_bstrMenuTask1; /* static */ CString CWebServiceExtension::_bstrMenuTask2; /* static */ CString CWebServiceExtension::_bstrMenuTask3; /* static */ CString CWebServiceExtension::_bstrMenuTask4; /* static */ CString CWebServiceExtension::_bstrMenuIconBullet; /* static */ CString CWebServiceExtension::_bstrMenuIconHelp; /* static */ BOOL CWebServiceExtension::_fStaticsLoaded = FALSE; /* static */ BOOL CWebServiceExtension::_fStaticsLoaded2 = FALSE;
CWebServiceExtension::CWebServiceExtension( CIISMachine * pOwner, CRestrictionUIEntry * pRestrictionUIEntry, CIISService * pService ) : CIISMBNode(pOwner, SZ_MBN_WEB), m_pWebService(pService) { m_hwnd = 0; m_fFlaggedForDeletion = FALSE; RestrictionUIEntryCopy(&m_RestrictionUIEntry,pRestrictionUIEntry); }
CWebServiceExtension::~CWebServiceExtension() { // Delete all objects associated with this object..
CleanRestrictionUIEntry(&m_RestrictionUIEntry); }
HRESULT CWebServiceExtension::GetContextHelp(CString& strHtmlPage) { strHtmlPage = WEBSVCEXT_HELP_PATH; return S_OK; }
/* static */ void CWebServiceExtension::InitializeHeaders(LPHEADERCTRL lpHeader) { CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths); if (!_fStaticsLoaded) { _fStaticsLoaded = _bstrStatusAllowed.LoadString(IDS_ALLOWED) && _bstrStatusProhibited.LoadString(IDS_PROHIBITED) && _bstrStatusCustom.LoadString(IDS_CUSTOM) && _bstrStatusInUse.LoadString(IDS_INUSE) && _bstrStatusNotInUse.LoadString(IDS_NOTINUSE); } }
/* virtual */ void CWebServiceExtension::InitializeChildHeaders(LPHEADERCTRL lpHeader) { CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths); }
/* virtual */ HRESULT CWebServiceExtension::GetResultViewType( LPOLESTR * lplpViewType, long * lpViewOptions ) { *lplpViewType = NULL; *lpViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
// S_FALSE to use default view type, S_OK indicates the
// view type is returned in *ppViewType
return S_OK; }
/* virtual */ HRESULT CWebServiceExtension::BuildMetaPath(CComBSTR & bstrPath) const { HRESULT hr = S_OK; ASSERT(m_pWebService != NULL); hr = m_pWebService->BuildMetaPath(bstrPath); return hr; }
/*virtual*/ BOOL CWebServiceExtension::IsConfigurable() const { // is not configurable if it's one of the "special ones...
if (WEBSVCEXT_TYPE_ALL_UNKNOWN_ISAPI == m_RestrictionUIEntry.iType || WEBSVCEXT_TYPE_ALL_UNKNOWN_CGI == m_RestrictionUIEntry.iType) { return FALSE; } else { // WEBSVCEXT_TYPE_REGULAR
// WEBSVCEXT_TYPE_FILENAME_EXTENSIONS_FILTER
return TRUE; } }
/*virtual*/ BOOL CWebServiceExtension::IsDeletable() const { BOOL bRet = FALSE;
// if there is a property dialog
// open on this item, then don't let them
// delete the item.
// Don't hide the option to delete
// this confuses users and
// also it won't always be hidden.
// kind of wacky, so just show it always
// and pop an error if they try to delete it.
//if (IsMyPropertySheetOpen()){return FALSE;}
// loop thru the list to see if anyone of the entries
// is not deleteable -- if it's not deletable...
// then the whole thing is not deletable
CString TheKey; POSITION pos = NULL; CRestrictionEntry * pOneEntry = NULL; for(pos = m_RestrictionUIEntry.strlstRestrictionEntries.GetStartPosition();pos != NULL;) { m_RestrictionUIEntry.strlstRestrictionEntries.GetNextAssoc(pos, TheKey, (CRestrictionEntry *&) pOneEntry); if (pOneEntry) { if (WEBSVCEXT_TYPE_REGULAR == pOneEntry->iType) { if (0 != pOneEntry->iDeletable) { bRet = TRUE; goto CWebServiceExtension_IsDeletable_Exit; } } } }
CWebServiceExtension_IsDeletable_Exit: return bRet; }
/* virtual */ LPOLESTR CWebServiceExtension::GetResultPaneColInfo( IN int nCol ) { switch(nCol) { case COL_ICON: return _T("");
case COL_WEBSVCEXT: return QueryDisplayName();
case COL_STATUS: { switch(GetState()) { case WEBSVCEXT_STATUS_ALLOWED: return _bstrStatusAllowed; case WEBSVCEXT_STATUS_PROHIBITED: return _bstrStatusProhibited; case WEBSVCEXT_STATUS_CUSTOM: return _bstrStatusCustom; case WEBSVCEXT_STATUS_INUSE: return _bstrStatusInUse; case WEBSVCEXT_STATUS_NOTINUSE: return _bstrStatusNotInUse; default: return OLESTR(""); } } } ASSERT_MSG("Bad column number"); return OLESTR(""); }
/* virtual */ LPOLESTR CWebServiceExtension::QueryDisplayName() { if (m_RestrictionUIEntry.strGroupDescription.IsEmpty()) { // no need to call refresh for this.
//RefreshData();
m_RestrictionUIEntry.strGroupDescription = QueryNodeName(); }
return (LPTSTR)(LPCTSTR)m_RestrictionUIEntry.strGroupDescription; }
/* virtual */ int CWebServiceExtension::QueryImage() const { // Check if it's one of our "special ones"
switch(GetState()) { case WEBSVCEXT_STATUS_ALLOWED: if (WEBSVCEXT_TYPE_REGULAR != m_RestrictionUIEntry.iType) { // should be an icon that is emphasized for
// the "allowed" mode -- since that is dangerous
return iWebSvcFilterPlus; } else { return iWebSvcGearPlus; } case WEBSVCEXT_STATUS_PROHIBITED: if (WEBSVCEXT_TYPE_REGULAR != m_RestrictionUIEntry.iType) { return iWebSvcFilter; } else { return iWebSvcGear; } case WEBSVCEXT_STATUS_CUSTOM: if (WEBSVCEXT_TYPE_REGULAR != m_RestrictionUIEntry.iType) { return iWebSvcFilterPlus; } else { return iWebSvcGearPlus; } case WEBSVCEXT_STATUS_INUSE: return iWebSvcGear; case WEBSVCEXT_STATUS_NOTINUSE: return iWebSvcGear; default: return iWebSvcGear; }
return iWebSvcGear; }
int CWebServiceExtension::QueryImageForPropertyPage() const { switch(GetState()) { case WEBSVCEXT_STATUS_ALLOWED: case WEBSVCEXT_STATUS_PROHIBITED: case WEBSVCEXT_STATUS_CUSTOM: if (WEBSVCEXT_TYPE_REGULAR != m_RestrictionUIEntry.iType) { return iWebSvcFilter; } else { return iWebSvcGear; } case WEBSVCEXT_STATUS_INUSE: case WEBSVCEXT_STATUS_NOTINUSE: return iWebSvcGear; default: return iWebSvcGear; }
return iApplication; }
/* virtual */ HRESULT CWebServiceExtension::RefreshData() { // the user clicked on the refresh menu bar or something
// so let's make sure the item gets reselected
return RefreshData(TRUE); }
HRESULT CWebServiceExtension::RefreshData(BOOL bReselect) { // since refreshing just one of these items
// means that we must read the metabase value
// which contains all of the items, we might as
// well update them all.
//
// just call the RefreshData for our container...
IConsole * pConsole = (IConsole *)GetConsole(); CWebServiceExtensionContainer * pContainer = m_pOwner->QueryWebSvcExtContainer(); if (pContainer) { if (bReselect) { if (SUCCEEDED(CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST))) { // If we are selected, then
// make sure we are select first.
// this so that we get the StandardVerbs!
if (pContainer == g_pCurrentlyDisplayedContainer) { if (NULL != QueryScopeItem()) { pConsole->SelectScopeItem(QueryScopeItem()); } } } }
return pContainer->RefreshData(); } else { return S_OK; } }
/* virtual */ int CWebServiceExtension::CompareResultPaneItem( CIISObject * pObject, int nCol ) /*++
Routine Description:
Compare two CIISObjects on sort item criteria
Arguments:
CIISObject * pObject : Object to compare against int nCol : Column number to sort on
Return Value:
0 if the two objects are identical <0 if this object is less than pObject >0 if this object is greater than pObject
--*/ { ASSERT_READ_PTR(pObject);
//
// First criteria is object type
//
int n1 = QuerySortWeight(); int n2 = pObject->QuerySortWeight();
if (n1 != n2) { return n1 - n2; }
//
// Both are CWebServiceExtension objects
//
CWebServiceExtension * pMyObject = (CWebServiceExtension *)pObject; int MyType = 0; int YourType = 0;
switch(nCol) { case COL_ICON: // Sort on the type of icon.
MyType = m_RestrictionUIEntry.iType;; YourType = pMyObject->m_RestrictionUIEntry.iType;
// 1st sort criteria -- type
if (MyType == YourType) { // secondary sort criteria -- name
//return ::lstrcmpi(GetResultPaneColInfo(COL_WEBSVCEXT), pObject->GetResultPaneColInfo(COL_WEBSVCEXT));
// this should be faster, GetResultPaneColInfo just calls this anyways.
return ::lstrcmpi(QueryDisplayName(), pObject->QueryDisplayName()); }
// 1st sort criteria -- type
if (MyType == WEBSVCEXT_TYPE_ALL_UNKNOWN_ISAPI || MyType == WEBSVCEXT_TYPE_ALL_UNKNOWN_CGI) { return -1; } else { // WEBSVCEXT_TYPE_FILENAME_EXTENSIONS_FILTER
// WEBSVCEXT_TYPE_REGULAR
return 1; } break; case COL_WEBSVCEXT: case COL_STATUS: default: //
// Lexical sort
//
return ::lstrcmpi( GetResultPaneColInfo(nCol), pObject->GetResultPaneColInfo(nCol) ); } }
/* virtual */ HRESULT CWebServiceExtension::CreatePropertyPages( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, IUnknown * pUnk, DATA_OBJECT_TYPES type ) { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err; IConsole * pConsole = (IConsole *)GetConsole();
if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type))) { return S_OK; } if (ERROR_ALREADY_EXISTS == err.Win32Error()) { return S_FALSE; }
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { //
// If there's already a property sheet open on this item
// then make it the foreground window and bail.
HWND MyPropWindow = IsMyPropertySheetOpen(); if (MyPropWindow && (MyPropWindow != (HWND) 1)) { if (SetForegroundWindow(MyPropWindow)) { if (handle) { MMCFreeNotifyHandle(handle); handle = 0; } return S_FALSE; } else { // wasn't able to bring this property sheet to
// the foreground, the propertysheet must not
// exist anymore. let's just clean the hwnd
// so that the user will be able to open propertysheet
SetMyPropertySheetOpen(0); } }
// if the entry doesn't have any files
// then don't let them open it.
if (!m_RestrictionUIEntry.strlstRestrictionEntries.IsEmpty()) { // we need to refresh ourself from the metabase
// before grabbing this data.
// need to get the most up to date info...
RefreshData(FALSE); if (TRUE == m_fFlaggedForDeletion) { // this item was marked for deletion during the RefreshData
// so don't display it's property page.
// instead popup an error.
err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } else { // Create a copy of the particular entry we want to modify....
CRestrictionUIEntry * pCopyOfRestrictionUIEntry = RestrictionUIEntryMakeCopy(&m_RestrictionUIEntry); if (pCopyOfRestrictionUIEntry) { CWebServiceExtensionSheet * pSheet = new CWebServiceExtensionSheet( QueryAuthInfo(), METABASE_PATH_FOR_RESTRICT_LIST, GetMainWindow(pConsole), (LPARAM) this, (LPARAM) GetParentNode(), (LPARAM) pCopyOfRestrictionUIEntry ); if (pSheet != NULL) { // cache handle for user in MMCPropertyChangeNotify
m_ppHandle = handle;
pSheet->SetModeless();
err = AddMMCPage(lpProvider, new CWebServiceExtensionGeneral(pSheet,QueryImageForPropertyPage(),pCopyOfRestrictionUIEntry)); err = AddMMCPage(lpProvider, new CWebServiceExtensionRequiredFiles(pSheet,QueryAuthInfo(),pCopyOfRestrictionUIEntry)); // send a notify to MMC to
// let it refresh the HTML GetProperty buttons
// don't do this, since it will send the property page to the background!
//MMCPropertyChangeNotify(handle, (LPARAM) this);
} } } }
err.MessageBoxOnFailure(); } else { return S_FALSE; } return err; }
/* virtual */ HRESULT CWebServiceExtension::AddMenuItems( IN LPCONTEXTMENUCALLBACK lpContextMenuCallback, IN OUT long * pInsertionAllowed, IN DATA_OBJECT_TYPES type ) { ASSERT_READ_PTR(lpContextMenuCallback);
//
// Add base menu items
//
HRESULT hr = CIISObject::AddMenuItems( lpContextMenuCallback, pInsertionAllowed, type );
ASSERT(pInsertionAllowed != NULL); if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) != 0) { AddMenuSeparator(lpContextMenuCallback);
/*
// if there is a property dialog
// open on this item, then don't let them
// Do stuff with it.
if (IsMyPropertySheetOpen()) { AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_ALLOW, MF_GRAYED); AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_PROHIBIT, MF_GRAYED); } else */ { INT iState = GetState(); if (WEBSVCEXT_STATUS_ALLOWED == iState || WEBSVCEXT_STATUS_PROHIBITED == iState || WEBSVCEXT_STATUS_CUSTOM == iState) { AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_ALLOW, iState != WEBSVCEXT_STATUS_ALLOWED ? 0 : MF_GRAYED); AddMenuItemByCommand(lpContextMenuCallback, IDM_WEBEXT_PROHIBIT, iState != WEBSVCEXT_STATUS_PROHIBITED ? 0 : MF_GRAYED); } } }
return hr; }
/* virtual */ HRESULT CWebServiceExtension::Command( IN long lCommandID, IN CSnapInObjectRootBase * pObj, IN DATA_OBJECT_TYPES type ) { HRESULT hr = S_OK; CString name; INT iCommand = 9999;
switch (lCommandID) {
case IDM_WEBEXT_ALLOW: iCommand = WEBSVCEXT_STATUS_ALLOWED; break; case IDM_WEBEXT_PROHIBIT: iCommand = WEBSVCEXT_STATUS_PROHIBITED; break;
//
// Pass on to base class
//
default: hr = CIISMBNode::Command(lCommandID, pObj, type); }
if (iCommand != 9999) { hr = ChangeState(iCommand); }
return hr; }
/*virtual*/ HRESULT CWebServiceExtension::DeleteNode(IResultData * pResult) { CError err;
// check if they have the property sheet open on it.
if (IsMyPropertySheetOpen()) { ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET_WEBSVCEXT); return S_OK; } // Check if it's even deletable...
if (!IsDeletable()) { ::AfxMessageBox(IDS_ITEM_NOT_REMOVABLE); } else { if (!NoYesMessageBox(IDS_CONFIRM_DELETE)) { return err; }
err == RemoveRestrictionUIEntry(QueryInterface(),&m_RestrictionUIEntry); if (err.Succeeded()) { // remove result item
if (FAILED(err = FindMyResultItem(pResult,TRUE))) { err = pResult->DeleteItem(m_hResultItem, 0); } if (err.Succeeded()) { RefreshData(FALSE); } } err.MessageBoxOnFailure(); } return err; }
/* virtual */ HRESULT CWebServiceExtension::OnDblClick(IComponentData * pcd, IComponent * pc) { CComQIPtr<IPropertySheetProvider, &IID_IPropertySheetProvider> spProvider(GetConsole()); IDataObject * pdo = NULL; GetDataObject(&pdo, CCT_RESULT); CError err = spProvider->FindPropertySheet(reinterpret_cast<MMC_COOKIE>(this), 0, pdo); if (err != S_OK) { err = spProvider->CreatePropertySheet(_T(""), TRUE, (MMC_COOKIE)this, pdo, MMC_PSO_HASHELP); if (err.Succeeded()) { err = spProvider->AddPrimaryPages( pc, TRUE, // we may want to get property change notifications
NULL, // according to docs
FALSE // for result item only
); if (err.Succeeded()) { err = spProvider->AddExtensionPages(); } } if (err.Succeeded()) { HWND hWnd = NULL; VERIFY(SUCCEEDED(GetConsole()->GetMainWindow(&hWnd))); VERIFY(SUCCEEDED(spProvider->Show((LONG_PTR)hWnd, 0))); } else { spProvider->Show(-1, 0); } } return err; }
//
// Procedure removes all characters in the second string from the first one.
//
INT RemoveChars(LPTSTR pszStr,LPTSTR pszRemoved) { BOOL bRemovedSomething = FALSE; INT iCharsRemovedCount = 0; INT iOrgStringLength = _tcslen(pszStr); INT cbRemoved = _tcslen(pszRemoved); INT iSrc, iDest; for (iSrc = iDest = 0; pszStr[iSrc]; iSrc++, iDest++) { // Check if this char is the in the list of stuf
// we are supposed to remove.
// if it is then just set iSrc to iSrc +1
#ifdef UNICODE
while (wmemchr(pszRemoved, pszStr[iSrc], cbRemoved)) #else
while (memchr(pszRemoved, pszStr[iSrc], cbRemoved)) #endif
{ iCharsRemovedCount++; iSrc++; }
// copy the character to itself
pszStr[iDest] = pszStr[iSrc]; }
// Cut off the left over strings
// which we didn't erase. but need to.
if (iCharsRemovedCount >= 0){pszStr[iOrgStringLength - iCharsRemovedCount]= '\0';}
return iDest - 1; }
/* virtual */ HRESULT CWebServiceExtension::GetProperty( LPDATAOBJECT pDataObject, BSTR szPropertyName, BSTR* pbstrProperty) { CString strProperty;
if (!_wcsicmp(L"CCF_HTML_DETAILS",szPropertyName)) { if (!_fStaticsLoaded2) { CComBSTR strTempFormat; CComBSTR strTempString1,strTempString2,strTempString3; CString csTempPath1; CString csTempPath2;
// point this to a hard coded file, if the file exists...
if (_MAX_PATH >= GetSystemDirectory(csTempPath1.GetBuffer(_MAX_PATH), _MAX_PATH)) { csTempPath1.ReleaseBuffer( ); csTempPath2 = csTempPath1; csTempPath1 += _T("\\oobe\\images\\btn2.gif"); csTempPath2 += _T("\\oobe\\images\\qmark.gif");
strTempFormat.LoadString(IDS_MENU_WEBEXT_ICON_FORMAT);
DWORD dwAttr = GetFileAttributes(csTempPath1); _bstrMenuIconBullet = _T("<BR>"); if (!(dwAttr == 0xffffffff || (dwAttr & FILE_ATTRIBUTE_DIRECTORY))) { // point to the hard coded file
_bstrMenuIconBullet.Format(strTempFormat,csTempPath1); }
dwAttr = GetFileAttributes(csTempPath2); _bstrMenuIconHelp = _T("<BR>"); if (!(dwAttr == 0xffffffff || (dwAttr & FILE_ATTRIBUTE_DIRECTORY))) { // point to the hard coded file
_bstrMenuIconHelp.Format(strTempFormat,csTempPath2); } } //
// NOTE ON RemoveChars()
// This was used to erase the & from a string like "&Allow"
// Because Javascript can't handle that, so it had to be stripped.
// this worked for english type languages but broke for languages
// like Japanese because in order to show a hotkey they would
// use "SomeHiraganaCharacters (&A)". and the "(" isn't able
// to be handled by Javascript either, so it broke.
// instead of just fixing RemoveChars() to remove ( and ) as well
// we just created new strings, that way localizers don't get confused
// when the string the created shows up in the UI as
// "SomeHiraganaCharacters" rather than "SomeHiraganaCharacters (A)"
//
strTempString1.LoadString(IDS_MENU_WEBEXT_ALLOW_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_ALLOW_FORMAT); _bstrMenuAllowOn.Format(strTempString2,strTempString1,_T("IDS_MENU_WEBEXT_ALLOW")); strTempString2.LoadString(IDS_MENU_WEBEXT_ALLOW_DISABLED_FORMAT); _bstrMenuAllowOff.Format(strTempString2,strTempString1);
strTempString1.LoadString(IDS_MENU_WEBEXT_PROHIBIT_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_PROHIBIT_FORMAT); _bstrMenuProhibitOn.Format(strTempString2,strTempString1,_T("IDS_MENU_WEBEXT_PROHIBIT")); strTempString2.LoadString(IDS_MENU_WEBEXT_PROHIBIT_DISABLED_FORMAT); _bstrMenuProhibitOff.Format(strTempString2,strTempString1);
strTempString1.LoadString(IDS_MENU_PROPERTIES_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_PROPERTIES_FORMAT); _bstrMenuPropertiesOn.Format(strTempString2,strTempString1,strTempString1); strTempString2.LoadString(IDS_MENU_WEBEXT_PROPERTIES_DISABLED_FORMAT); _bstrMenuPropertiesOff.Format(strTempString2,strTempString1,strTempString1); strTempString1.LoadString(IDS_MENU_WEBEXT_CONTAINER_ADD1_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_ADD1_FORMAT); _bstrMenuTask1.Format(strTempString2,_T("IDS_MENU_WEBEXT_CONTAINER_ADD1"),strTempString1);
strTempString1.LoadString(IDS_MENU_WEBEXT_CONTAINER_ADD2_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_ADD2_FORMAT); _bstrMenuTask2.Format(strTempString2,_T("IDS_MENU_WEBEXT_CONTAINER_ADD2"),strTempString1);
strTempString1.LoadString(IDS_MENU_WEBEXT_CONTAINER_PROHIBIT_ALL_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_PROHIBIT_ALL_FORMAT); _bstrMenuTask3.Format(strTempString2,_T("IDS_MENU_WEBEXT_CONTAINER_PROHIBIT_ALL"),strTempString1);
strTempString1.LoadString(IDS_MENU_WEBEXT_CONTAINER_HELP); strTempString3.LoadString(IDS_MENU_WEBEXT_CONTAINER_HELP_JAVA_SAFE); //RemoveChars(strTempString1, BAD_CHARS_FOR_HTML_PANE);
strTempString2.LoadString(IDS_MENU_WEBEXT_HELP_FORMAT); _bstrMenuTask4.Format(strTempString2,strTempString3,strTempString1);
strTempString2.LoadString(IDS_MENU_WEBEXT_TASKS); //RemoveChars(strTempString2, BAD_CHARS_FOR_HTML_PANE);
_bstrMenuTasks = strTempString2;
_fStaticsLoaded2 = TRUE; }
/*
// commented out: if we disable this, then there is no notification to
// re-enable it if the user hit cancel, thus the buttons will stay "grayed"...
// if there is a property dialog
// open on this item, then don't
// let them access these buttons...
if (IsMyPropertySheetOpen()) { strProperty += _bstrMenuAllowOff; strProperty += _bstrMenuProhibitOff; } else */ { // [Allowed] Button
// [Prohibited] Button
switch(GetState()) { case WEBSVCEXT_STATUS_ALLOWED: strProperty += _bstrMenuAllowOff; strProperty += _bstrMenuProhibitOn; break; case WEBSVCEXT_STATUS_PROHIBITED: strProperty += _bstrMenuAllowOn; strProperty += _bstrMenuProhibitOff; break; case WEBSVCEXT_STATUS_CUSTOM: strProperty += _bstrMenuAllowOn; strProperty += _bstrMenuProhibitOn; break; default: break; } }
// [Properties] Button
if (IsConfigurable()) { strProperty += _bstrMenuPropertiesOn; } else { strProperty += _bstrMenuPropertiesOff; }
// Tasks
// -------------------------
strProperty += _bstrMenuTasks;
// Task 1
strProperty += _bstrMenuIconBullet; strProperty += _bstrMenuTask1;
// Task 2
strProperty += _bstrMenuIconBullet; strProperty += _bstrMenuTask2;
// Task 3
strProperty += _bstrMenuIconBullet; strProperty += _bstrMenuTask3;
// Help
strProperty += _bstrMenuIconHelp; strProperty += _bstrMenuTask4; } else if (!_wcsicmp(L"CCF_DESCRIPTION",szPropertyName)) { // Display data in Description field...
} else { return S_FALSE; // unknown strPropertyName
}
*pbstrProperty = ::SysAllocString(strProperty); return S_OK; }
HRESULT CWebServiceExtension::UpdateResultItem(IResultData *pResultData,BOOL bSelect) { HRESULT hr = S_OK;
if (!pResultData) { return E_POINTER; }
RESULTDATAITEM ri; ::ZeroMemory(&ri, sizeof(ri)); ri.itemID = this->QueryResultItem(); ri.mask = RDI_STR | RDI_IMAGE; if (bSelect) { ri.mask = ri.mask | RDI_STATE; ri.nState = LVIS_SELECTED | LVIS_FOCUSED; } ri.str = MMC_CALLBACK; ri.nImage = this->QueryImage();
hr = pResultData->SetItem(&ri); pResultData->UpdateItem(ri.itemID);
return hr; }
HRESULT CWebServiceExtension::FindMyResultItem(IResultData *pResultData,BOOL bDeleteIfFound) { HRESULT hr,hr0 = S_FALSE; LPARAM lParam = (LPARAM) this; HRESULTITEM hresultItem = NULL; int i = 0;
hr0 = hr = pResultData->FindItemByLParam(lParam,&hresultItem); while (S_OK == hr) { if (i++ >= 10) { break; } if (bDeleteIfFound) { hr = pResultData->DeleteItem(hresultItem,0); } hr = pResultData->FindItemByLParam(lParam,&hresultItem); }
return hr0; }
HRESULT CWebServiceExtension::AddToResultPane(IResultData *pResultData, BOOL bSelect,BOOL bPleaseAddRef) { HRESULT hr = S_OK; HRESULTITEM hresultItem = NULL;
if (!pResultData) { return E_POINTER; }
RESULTDATAITEM ri; ::ZeroMemory(&ri, sizeof(ri)); ri.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; if (bSelect) { ri.mask = ri.mask | RDI_STATE; ri.nState = LVIS_SELECTED | LVIS_FOCUSED; } ri.str = MMC_CALLBACK; ri.nImage = this->QueryImage(); ri.lParam = (LPARAM) this;
// check if we're already in the list
if (S_OK == pResultData->FindItemByLParam((LPARAM) this,&hresultItem)) { // this needs to be set before calling UpdateResultItem...
ri.itemID = hresultItem; this->SetResultItem(ri.itemID); this->SetScopeItem(this->QueryContainer()->QueryScopeItem());
hr = pResultData->SetItem(&ri); if (bSelect) { //pResultData->UpdateItem(ri.itemID);
} return S_OK; }
//if (this->QueryContainer()->IsExpanded())
{ // a very important step here.
// if we don't have this AddRef, we will Access violate..
if (bPleaseAddRef) { this->AddRef(); }
hr = pResultData->InsertItem(&ri); if (SUCCEEDED(hr)) { this->SetScopeItem(this->QueryContainer()->QueryScopeItem()); this->SetResultItem(ri.itemID); } else { if (bPleaseAddRef) { this->Release(); } } }
return hr; }
HRESULT CWebServiceExtension::AddToResultPaneSorted(IResultData *pResultData,BOOL bSelect,BOOL bPleaseAddRef) { HRESULT hr = S_OK; if (!pResultData) { return E_POINTER; } hr = AddToResultPane(pResultData,bSelect,bPleaseAddRef);
// sort on Column0,Ascending,nodata
pResultData->Sort(0,0,0); return hr; }
INT CWebServiceExtension::GetState() const { INT iDisplayedState = GetRestrictUIState((CRestrictionUIEntry *) &m_RestrictionUIEntry); return iDisplayedState; }
HRESULT CWebServiceExtension::ChangeState(INT iDesiredState) { AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CError err; CWaitCursor wait; BOOL bProceed = TRUE; BOOL bShowedPopup = FALSE; IConsole * pConsole = (IConsole *)GetConsole();
// don't allow them to change the state if
// it's property sheet is already open...
// check if they have the property sheet open on it.
if (IsMyPropertySheetOpen()) { ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET_WEBSVCEXT2); return S_OK; }
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,METABASE_PATH_FOR_RESTRICT_LIST); if (err.Succeeded()) { // if it's the special entries
// check if they are sure if they want to do this...
if (WEBSVCEXT_TYPE_ALL_UNKNOWN_ISAPI == m_RestrictionUIEntry.iType || WEBSVCEXT_TYPE_ALL_UNKNOWN_CGI == m_RestrictionUIEntry.iType) { // check if they're tryinging to allow it.
if (WEBSVCEXT_STATUS_ALLOWED == iDesiredState) { CString strMsg; CString strMsgFormat; bProceed = FALSE; UINT iHelpID = 0; if (WEBSVCEXT_TYPE_ALL_UNKNOWN_ISAPI == m_RestrictionUIEntry.iType) { iHelpID = HIDD_WEBSVCEXT_UNKNOWN_ISAPI; strMsgFormat.LoadString(IDS_ALLOW_UNSAFE_ISAPI_MSG); } else { iHelpID = HIDD_WEBSVCEXT_UNKNOWN_CGI; strMsgFormat.LoadString(IDS_ALLOW_UNSAFE_CGI_MSG); } strMsg.Format(strMsgFormat,m_RestrictionUIEntry.strGroupDescription,m_RestrictionUIEntry.strGroupDescription);
// ensure the dialog gets themed
CThemeContextActivator activator(theApp.GetFusionInitHandle());
if (IDYES == DoHelpMessageBox(NULL,strMsg,MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2 | MB_HELP, iHelpID)) { bProceed = TRUE; bShowedPopup = TRUE; } } } else { // check if it's a normal entry
// and if other applications have dependencies upon it
// if there are dependencies, then ask if they're sure
// they want to disable it?
if (WEBSVCEXT_TYPE_REGULAR == m_RestrictionUIEntry.iType) { // Check if they want to disable it
if (WEBSVCEXT_STATUS_PROHIBITED == iDesiredState) { // Check if this item has apps that
// are dependent upon it.
CStringListEx strlstDependApps; if (TRUE == ReturnDependentAppsList(QueryInterface(),m_RestrictionUIEntry.strGroupID,&strlstDependApps,FALSE)) { bProceed = FALSE;
// ensure the dialog gets themed
CThemeContextActivator activator(theApp.GetFusionInitHandle());
// check if they really want to do this.
CDepedentAppsDlg dlg(&strlstDependApps,m_RestrictionUIEntry.strGroupDescription,GetMainWindow(pConsole)); if (dlg.DoModal() == IDOK) { bProceed = TRUE; bShowedPopup = TRUE; } } } } }
if (bProceed) { if (&m_RestrictionUIEntry) { err = ChangeStateOfEntry(QueryInterface(),iDesiredState,&m_RestrictionUIEntry); if (err.Succeeded() || err.Win32Error() == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { // just in case they are trying to set the allow/prohibit
// for an item which has already been removed from the metabase
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == err.Win32Error()) { err.MessageBoxOnFailure(); } err = RefreshData(FALSE); if (err.Succeeded()) { RefreshDisplay(); if (bShowedPopup) { // if we wanted to make the container node
// redisplay everything... we would uncomment this line.
// seems like we have to do this after displaying confirmation msg.
// dunno why.
CWebServiceExtensionContainer * pContainer = m_pOwner->QueryWebSvcExtContainer(); if (pContainer) { err = pContainer->RefreshDisplay(FALSE); } } } } err.MessageBoxOnFailure(); } } } else { return S_FALSE; } return err; }
|