2650 lines
84 KiB
C++
2650 lines
84 KiB
C++
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1994 - 1998.
|
||
|
//
|
||
|
// File: scope.cpp
|
||
|
//
|
||
|
// Contents: implementation of the scope pane
|
||
|
//
|
||
|
// Classes: CScopePane
|
||
|
//
|
||
|
// History: 03-14-1998 stevebl Created
|
||
|
// 05-20-1998 RahulTh added GetUNCPath and modified Command to
|
||
|
// use this function
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
#include "precomp.hxx"
|
||
|
#include <wbemcli.h>
|
||
|
#include "rsoputil.h"
|
||
|
#include <list>
|
||
|
|
||
|
// Comment this line to stop trying to set the main snapin icon in the
|
||
|
// scope pane.
|
||
|
#define SET_SCOPE_ICONS 1
|
||
|
|
||
|
// Un-comment the next line to persist snap-in related data. (This really
|
||
|
// shouldn't be necessary since I get all my info from my parent anyway.)
|
||
|
// #define PERSIST_DATA 1
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// IComponentData implementation
|
||
|
|
||
|
DEBUG_DECLARE_INSTANCE_COUNTER(CScopePane);
|
||
|
|
||
|
CScopePane::CScopePane()
|
||
|
{
|
||
|
#if DBG
|
||
|
dbg_cRef = 0;
|
||
|
#endif
|
||
|
DEBUG_INCREMENT_INSTANCE_COUNTER(CScopePane);
|
||
|
DebugMsg((DM_VERBOSE, TEXT("CScopePane::CScopePane this=%08x ref=%u"), this, dbg_cRef));
|
||
|
|
||
|
m_pToolDefs = NULL;
|
||
|
m_pTracking = NULL;
|
||
|
m_pCatList = NULL;
|
||
|
m_pFileExt = NULL;
|
||
|
m_bIsDirty = FALSE;
|
||
|
|
||
|
m_hwndMainWindow = NULL;
|
||
|
m_fMachine = FALSE;
|
||
|
m_fRSOP = FALSE;
|
||
|
m_iViewState = IDM_WINNER;
|
||
|
m_pScope = NULL;
|
||
|
m_pConsole = NULL;
|
||
|
m_pIClassAdmin = NULL;
|
||
|
m_pIPropertySheetProvider = NULL;
|
||
|
m_fLoaded = FALSE;
|
||
|
m_fExtension = FALSE;
|
||
|
m_pIGPEInformation = NULL;
|
||
|
m_pIRSOPInformation = NULL;
|
||
|
m_dwRSOPFlags = 0;
|
||
|
m_lLastAllocated = 0;
|
||
|
m_ToolDefaults.NPBehavior = NP_PUBLISHED;
|
||
|
m_ToolDefaults.fUseWizard = TRUE;
|
||
|
m_ToolDefaults.fCustomDeployment = FALSE;
|
||
|
m_ToolDefaults.UILevel = INSTALLUILEVEL_FULL;
|
||
|
m_ToolDefaults.szStartPath = L""; // UNDONE - need to come up with a
|
||
|
// good default setting for this
|
||
|
m_ToolDefaults.iDebugLevel = 0;
|
||
|
m_ToolDefaults.fShowPkgDetails = 0;
|
||
|
m_ToolDefaults.nUninstallTrackingMonths = 12;
|
||
|
m_ToolDefaults.fUninstallOnPolicyRemoval = FALSE;
|
||
|
m_ToolDefaults.fZapOn64 = FALSE;
|
||
|
m_ToolDefaults.f32On64 = TRUE;
|
||
|
m_ToolDefaults.fExtensionsOnly = TRUE;
|
||
|
m_CatList.cCategory = 0;
|
||
|
m_CatList.pCategoryInfo = NULL;
|
||
|
m_fBlockAddPackage = FALSE;
|
||
|
m_fDisplayedRsopARPWarning = FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
CScopePane::~CScopePane()
|
||
|
{
|
||
|
|
||
|
DEBUG_DECREMENT_INSTANCE_COUNTER(CScopePane);
|
||
|
DebugMsg((DM_VERBOSE, TEXT("CScopePane::~CScopePane this=%08x ref=%u"), this, dbg_cRef));
|
||
|
ClearCategories();
|
||
|
ASSERT(m_pScope == NULL);
|
||
|
ASSERT(CResultPane::lDataObjectRefCount == 0);
|
||
|
}
|
||
|
#include <msi.h>
|
||
|
|
||
|
STDMETHODIMP CScopePane::Initialize(LPUNKNOWN pUnknown)
|
||
|
{
|
||
|
ASSERT(pUnknown != NULL);
|
||
|
HRESULT hr;
|
||
|
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
// MMC should only call ::Initialize once!
|
||
|
ASSERT(m_pScope == NULL);
|
||
|
hr = pUnknown->QueryInterface(IID_IConsoleNameSpace,
|
||
|
reinterpret_cast<void**>(&m_pScope));
|
||
|
ASSERT(hr == S_OK);
|
||
|
|
||
|
hr = pUnknown->QueryInterface(IID_IPropertySheetProvider,
|
||
|
(void **)&m_pIPropertySheetProvider);
|
||
|
ASSERT(hr == S_OK);
|
||
|
|
||
|
hr = pUnknown->QueryInterface(IID_IConsole, reinterpret_cast<void**>(&m_pConsole));
|
||
|
ASSERT(hr == S_OK);
|
||
|
|
||
|
|
||
|
#ifdef SET_SCOPE_ICONS
|
||
|
LPIMAGELIST lpScopeImage;
|
||
|
hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
|
||
|
ASSERT(hr == S_OK);
|
||
|
|
||
|
// Load the bitmaps from the dll
|
||
|
CBitmap bmp16x16;
|
||
|
CBitmap bmp32x32;
|
||
|
bmp16x16.LoadBitmap(IDB_16x16);
|
||
|
bmp32x32.LoadBitmap(IDB_32x32);
|
||
|
|
||
|
// Set the images
|
||
|
lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
|
||
|
reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp32x32)),
|
||
|
0, RGB(255,0,255));
|
||
|
SAFE_RELEASE(lpScopeImage);
|
||
|
#endif
|
||
|
|
||
|
// get the main window
|
||
|
hr = m_pConsole->GetMainWindow(&m_hwndMainWindow);
|
||
|
ASSERT(hr == S_OK);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
void CScopePane::RemoveResultPane(CResultPane * pRP)
|
||
|
{
|
||
|
m_sResultPane.erase(pRP);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::CreateComponent(LPCOMPONENT* ppComponent)
|
||
|
{
|
||
|
ASSERT(ppComponent != NULL);
|
||
|
DebugMsg((DM_VERBOSE, TEXT("CScopePane::CreateComponent this=%08x ppComponent=%08x."), this, ppComponent));
|
||
|
|
||
|
CComObject<CResultPane>* pObject;
|
||
|
CComObject<CResultPane>::CreateInstance(&pObject);
|
||
|
ASSERT(pObject != NULL);
|
||
|
DebugMsg((DM_VERBOSE, TEXT("CScopePane::CreateComponent pObject=%08x."), pObject));
|
||
|
|
||
|
m_sResultPane.insert(pObject);
|
||
|
|
||
|
// Store IComponentData
|
||
|
pObject->SetIComponentData(this);
|
||
|
return pObject->QueryInterface(IID_IComponent,
|
||
|
reinterpret_cast<void**>(ppComponent));
|
||
|
}
|
||
|
|
||
|
HRESULT CScopePane::TestForRSoPData(BOOL * pfPolicyFailed)
|
||
|
{
|
||
|
*pfPolicyFailed = FALSE;
|
||
|
HRESULT hr = S_OK;
|
||
|
IWbemLocator * pLocator = NULL;
|
||
|
IWbemServices * pNamespace = NULL;
|
||
|
IWbemClassObject * pObj = NULL;
|
||
|
IEnumWbemClassObject * pEnum = NULL;
|
||
|
BSTR strQueryLanguage = SysAllocString(TEXT("WQL"));
|
||
|
BSTR strNamespace = SysAllocString(m_szRSOPNamespace);
|
||
|
BSTR strObject = SysAllocString(TEXT("RSOP_ExtensionStatus.extensionGuid=\"{c6dc5466-785a-11d2-84d0-00c04fb169f7}\""));
|
||
|
BSTR strQuery = SysAllocString(TEXT("SELECT * FROM RSOP_ApplicationManagementPolicySetting"));
|
||
|
ULONG n = 0;
|
||
|
hr = CoCreateInstance(CLSID_WbemLocator,
|
||
|
0,
|
||
|
CLSCTX_INPROC_SERVER,
|
||
|
IID_IWbemLocator,
|
||
|
(LPVOID *) & pLocator);
|
||
|
DebugReportFailure(hr, (DM_WARNING, TEXT("TestForRSoPData: CoCreateInstance failed with 0x%x"), hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
hr = pLocator->ConnectServer(strNamespace,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&pNamespace);
|
||
|
DebugReportFailure(hr, (DM_WARNING, TEXT("TestForRSoPData: pLocator->ConnectServer failed with 0x%x"), hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
hr = pNamespace->ExecQuery(strQueryLanguage,
|
||
|
strQuery,
|
||
|
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
|
||
|
NULL,
|
||
|
&pEnum);
|
||
|
DebugReportFailure(hr, (DM_WARNING, TEXT("TestForRSoPData: pNamespace->ExecQuery failed with 0x%x"), hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &n);
|
||
|
DebugReportFailure(hr, (DM_WARNING, TEXT("TestForRSoPData: pEnum->Next failed with 0x%x"), hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
if (n == 0)
|
||
|
{
|
||
|
// there's no data here
|
||
|
hr = E_FAIL;
|
||
|
goto cleanup;
|
||
|
}
|
||
|
if (pObj)
|
||
|
{
|
||
|
pObj->Release();
|
||
|
pObj=NULL;
|
||
|
}
|
||
|
|
||
|
// check for failed settings
|
||
|
hr = pNamespace->GetObject(strObject,
|
||
|
WBEM_FLAG_RETURN_WBEM_COMPLETE,
|
||
|
NULL,
|
||
|
&pObj,
|
||
|
NULL);
|
||
|
DebugReportFailure(hr, (DM_WARNING, TEXT("TestForRSoPData: pNamespace->GetObject failed with 0x%x"), hr));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HRESULT hrStatus;
|
||
|
hr = GetParameter(pObj,
|
||
|
TEXT("error"),
|
||
|
hrStatus);
|
||
|
DebugReportFailure(hr, (DM_WARNING, TEXT("TestForRSoPData: GetParameter(\"error\") failed with 0x%x"), hr));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
*pfPolicyFailed = hrStatus != 0;
|
||
|
}
|
||
|
}
|
||
|
cleanup:
|
||
|
SysFreeString(strObject);
|
||
|
SysFreeString(strQuery);
|
||
|
SysFreeString(strQueryLanguage);
|
||
|
SysFreeString(strNamespace);
|
||
|
if (pObj)
|
||
|
{
|
||
|
pObj->Release();
|
||
|
}
|
||
|
if (pEnum)
|
||
|
{
|
||
|
pEnum->Release();
|
||
|
}
|
||
|
if (pNamespace)
|
||
|
{
|
||
|
pNamespace->Release();
|
||
|
}
|
||
|
if (pLocator)
|
||
|
{
|
||
|
pLocator->Release();
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP CScopePane::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
|
||
|
{
|
||
|
ASSERT(m_pScope != NULL);
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// Since it's my folder it has an internal format.
|
||
|
// Design Note: for extension. I can use the fact, that the data object doesn't have
|
||
|
// my internal format and I should look at the node type and see how to extend it.
|
||
|
if (event == MMCN_PROPERTY_CHANGE)
|
||
|
{
|
||
|
SaveToolDefaults();
|
||
|
hr = OnProperties(param);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
|
||
|
MMC_COOKIE cookie = 0;
|
||
|
if (pInternal != NULL)
|
||
|
{
|
||
|
cookie = pInternal->m_cookie;
|
||
|
FREE_INTERNAL(pInternal);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// only way we could not be able to extract our own format is if we're operating as an extension
|
||
|
m_fExtension = TRUE;
|
||
|
}
|
||
|
|
||
|
if (m_fRSOP)
|
||
|
{
|
||
|
if (m_pIRSOPInformation == NULL)
|
||
|
{
|
||
|
WCHAR szBuffer[MAX_DS_PATH];
|
||
|
m_fRSOPEnumerate = FALSE;
|
||
|
IRSOPInformation * pIRSOPInformation;
|
||
|
hr = lpDataObject->QueryInterface(IID_IRSOPInformation,
|
||
|
reinterpret_cast<void**>(&pIRSOPInformation));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
m_pIRSOPInformation = pIRSOPInformation;
|
||
|
m_pIRSOPInformation->AddRef();
|
||
|
|
||
|
hr = m_pIRSOPInformation->GetFlags(&m_dwRSOPFlags);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
/* extract the namespace here */
|
||
|
hr = m_pIRSOPInformation->GetNamespace(m_fMachine ? GPO_SECTION_MACHINE : GPO_SECTION_USER, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
m_szRSOPNamespace = szBuffer;
|
||
|
// check to be sure that there is data to show in the RSoP database
|
||
|
if SUCCEEDED(TestForRSoPData(&m_fRSOPPolicyFailed))
|
||
|
m_fRSOPEnumerate = TRUE;
|
||
|
}
|
||
|
pIRSOPInformation->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_pIGPEInformation == NULL)
|
||
|
{
|
||
|
IGPEInformation * pIGPEInformation;
|
||
|
hr = lpDataObject->QueryInterface(IID_IGPEInformation,
|
||
|
reinterpret_cast<void**>(&pIGPEInformation));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
GROUP_POLICY_OBJECT_TYPE gpoType;
|
||
|
hr = pIGPEInformation->GetType(&gpoType);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (gpoType == GPOTypeDS)
|
||
|
{
|
||
|
WCHAR szBuffer[MAX_DS_PATH];
|
||
|
do
|
||
|
{
|
||
|
hr = pIGPEInformation->GetDSPath(GPO_SECTION_ROOT, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
m_szGPO = szBuffer;
|
||
|
hr = pIGPEInformation->GetDisplayName(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
m_szGPODisplayName = szBuffer;
|
||
|
hr = pIGPEInformation->GetDSPath(m_fMachine ? GPO_SECTION_MACHINE : GPO_SECTION_USER, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
m_pIGPEInformation = pIGPEInformation;
|
||
|
m_pIGPEInformation->AddRef();
|
||
|
m_szLDAP_Path = szBuffer;
|
||
|
hr = pIGPEInformation->GetFileSysPath(m_fMachine ? GPO_SECTION_MACHINE : GPO_SECTION_USER, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
|
||
|
|
||
|
if (FAILED(hr)) break;
|
||
|
m_szGPT_Path = szBuffer;
|
||
|
|
||
|
// Here we get the domain name from the GPT_Path.
|
||
|
// The domain name is the very first element in
|
||
|
// the path so this is quite trivial.
|
||
|
m_szDomainName = &((LPCTSTR)m_szGPT_Path)[2]; // skip the "\\"
|
||
|
m_szDomainName = m_szDomainName.SpanExcluding(L"\\");
|
||
|
|
||
|
m_szGPT_Path += L"\\Applications";
|
||
|
hr = InitializeADE();
|
||
|
LoadToolDefaults();
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// cleanup archived records in the class store
|
||
|
FILETIME ft;
|
||
|
SYSTEMTIME st;
|
||
|
// get current time
|
||
|
GetSystemTime(&st);
|
||
|
// convert it to a FILETIME value
|
||
|
SystemTimeToFileTime(&st, &ft);
|
||
|
// subtract the right number of days
|
||
|
LARGE_INTEGER li;
|
||
|
li.LowPart = ft.dwLowDateTime;
|
||
|
li.HighPart = ft.dwHighDateTime;
|
||
|
li.QuadPart -= ONE_FILETIME_DAY * (((LONGLONG)m_ToolDefaults.nUninstallTrackingMonths * 365)/12);
|
||
|
ft.dwLowDateTime = li.LowPart;
|
||
|
ft.dwHighDateTime = li.HighPart;
|
||
|
// tell the CS to clean up anything older
|
||
|
m_pIClassAdmin->Cleanup(&ft);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// we can still continue even if
|
||
|
// initialization failed provided
|
||
|
// that the reason it failed is that
|
||
|
// the ClassStore object doesn't exist.
|
||
|
if (CS_E_OBJECT_NOTFOUND == hr)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// report error
|
||
|
LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_INIT_FAILED, hr);
|
||
|
}
|
||
|
}
|
||
|
} while (0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// force this to fail
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
}
|
||
|
pIGPEInformation->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
switch(event)
|
||
|
{
|
||
|
case MMCN_EXPAND:
|
||
|
{
|
||
|
hr = OnExpand(cookie, arg, param);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MMCN_SELECT:
|
||
|
hr = OnSelect(cookie, arg, param);
|
||
|
break;
|
||
|
|
||
|
case MMCN_CONTEXTMENU:
|
||
|
hr = OnContextMenu(cookie, arg, param);
|
||
|
break;
|
||
|
|
||
|
case MMCN_REFRESH:
|
||
|
hr = Command(IDM_REFRESH, lpDataObject);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::Destroy()
|
||
|
{
|
||
|
// Delete enumerated scope items
|
||
|
DeleteList();
|
||
|
|
||
|
SAFE_RELEASE(m_pScope);
|
||
|
SAFE_RELEASE(m_pConsole);
|
||
|
SAFE_RELEASE(m_pIClassAdmin);
|
||
|
SAFE_RELEASE(m_pIPropertySheetProvider);
|
||
|
SAFE_RELEASE(m_pIGPEInformation);
|
||
|
SAFE_RELEASE(m_pIRSOPInformation);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
|
||
|
{
|
||
|
ASSERT(ppDataObject != NULL);
|
||
|
|
||
|
CComObject<CDataObject>* pObject;
|
||
|
|
||
|
CComObject<CDataObject>::CreateInstance(&pObject);
|
||
|
ASSERT(pObject != NULL);
|
||
|
|
||
|
pObject->m_fMachine = m_fMachine;
|
||
|
// Save cookie and type for delayed rendering
|
||
|
pObject->SetType(type);
|
||
|
pObject->SetCookie(cookie);
|
||
|
|
||
|
return pObject->QueryInterface(IID_IDataObject,
|
||
|
reinterpret_cast<void**>(ppDataObject));
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//// IPersistStreamInit interface members
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetClassID(CLSID *pClassID)
|
||
|
{
|
||
|
ASSERT(pClassID != NULL);
|
||
|
|
||
|
// Copy the CLSID for this snapin
|
||
|
if (m_fRSOP)
|
||
|
{
|
||
|
if (m_fMachine)
|
||
|
*pClassID = CLSID_RSOP_MachineSnapin;
|
||
|
else
|
||
|
*pClassID = CLSID_RSOP_Snapin;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_fMachine)
|
||
|
*pClassID = CLSID_MachineSnapin;
|
||
|
else
|
||
|
*pClassID = CLSID_Snapin;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::IsDirty()
|
||
|
{
|
||
|
return ThisIsDirty() ? S_OK : S_FALSE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::Load(IStream *pStm)
|
||
|
{
|
||
|
#ifdef PERSIST_DATA
|
||
|
ASSERT(pStm);
|
||
|
|
||
|
// Read the string
|
||
|
TCHAR psz[MAX_DS_PATH];
|
||
|
ULONG nBytesRead;
|
||
|
ULONG cb;
|
||
|
HRESULT hr = pStm->Read(&cb, sizeof(ULONG), &nBytesRead);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = pStm->Read(psz, cb, &nBytesRead);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (cb > MAX_DS_PATH * sizeof(TCHAR))
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
m_szLDAP_Path = psz;
|
||
|
|
||
|
hr = pStm->Read(&cb, sizeof(ULONG), &nBytesRead);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (cb > MAX_DS_PATH * sizeof(TCHAR))
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
hr = pStm->Read(psz, cb, &nBytesRead);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
m_szGPT_Path = psz;
|
||
|
m_fLoaded = TRUE;
|
||
|
ClearDirty();
|
||
|
LoadToolDefaults();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return SUCCEEDED(hr) ? S_OK : E_FAIL;
|
||
|
#else
|
||
|
return S_OK;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::Save(IStream *pStm, BOOL fClearDirty)
|
||
|
{
|
||
|
#ifdef PERSIST_DATA
|
||
|
ASSERT(pStm);
|
||
|
|
||
|
// Write the string
|
||
|
ULONG nBytesWritten;
|
||
|
ULONG cb = (m_szLDAP_Path.GetLength() + 1) * sizeof(TCHAR);
|
||
|
HRESULT hr = pStm->Write(&cb, sizeof(ULONG), &nBytesWritten);
|
||
|
if (FAILED(hr))
|
||
|
return STG_E_CANTSAVE;
|
||
|
hr = pStm->Write(m_szLDAP_Path, cb, &nBytesWritten);
|
||
|
if (FAILED(hr))
|
||
|
return STG_E_CANTSAVE;
|
||
|
|
||
|
cb = (m_szGPT_Path.GetLength() + 1) * sizeof(TCHAR);
|
||
|
hr = pStm->Write(&cb, sizeof(ULONG), &nBytesWritten);
|
||
|
if (FAILED(hr))
|
||
|
return STG_E_CANTSAVE;
|
||
|
hr = pStm->Write(m_szGPT_Path, cb, &nBytesWritten);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
return STG_E_CANTSAVE;
|
||
|
#endif
|
||
|
if (fClearDirty)
|
||
|
ClearDirty();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
||
|
{
|
||
|
#ifdef PERSIST_DATA
|
||
|
ASSERT(pcbSize);
|
||
|
|
||
|
ULONG cb = (m_szLDAP_Path.GetLength() + m_szGPT_Path.GetLength() + 2) * sizeof(TCHAR) + 2 * sizeof(ULONG);
|
||
|
// Set the size of the string to be saved
|
||
|
#else
|
||
|
ULONG cb = 0;
|
||
|
#endif
|
||
|
ULISet32(*pcbSize, cb);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::InitNew(void)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
void CScopePane::LoadToolDefaults()
|
||
|
{
|
||
|
CString szFileName = m_szGPT_Path;
|
||
|
szFileName += L"\\";
|
||
|
szFileName += CFGFILE;
|
||
|
FILE * f = _wfopen(szFileName, L"rt");
|
||
|
if (f)
|
||
|
{
|
||
|
WCHAR sz[256];
|
||
|
CString szData;
|
||
|
CString szKey;
|
||
|
while (fgetws(sz, 256, f))
|
||
|
{
|
||
|
szData = sz;
|
||
|
szKey = szData.SpanExcluding(L"=");
|
||
|
szData = szData.Mid(szKey.GetLength()+1);
|
||
|
szData.TrimRight();
|
||
|
szData.TrimLeft();
|
||
|
szKey.TrimRight();
|
||
|
if (0 == szKey.CompareNoCase(KEY_NPBehavior))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.NPBehavior);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_fUseWizard))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.fUseWizard);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_fCustomDeployment))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.fCustomDeployment);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_UILevel))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.UILevel);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_szStartPath))
|
||
|
{
|
||
|
m_ToolDefaults.szStartPath = szData;
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_nUninstallTrackingMonths))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.nUninstallTrackingMonths);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_iDebugLevel))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.iDebugLevel);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_fShowPkgDetails))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.fShowPkgDetails);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_fUninstallOnPolicyRemoval))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.fUninstallOnPolicyRemoval);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_f32On64))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.f32On64);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_fZapOn64))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.fZapOn64);
|
||
|
}
|
||
|
else if (0 == szKey.CompareNoCase(KEY_fExtensionsOnly))
|
||
|
{
|
||
|
swscanf(szData, L"%i", &m_ToolDefaults.fExtensionsOnly);
|
||
|
}
|
||
|
}
|
||
|
fclose(f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CScopePane::SaveToolDefaults()
|
||
|
{
|
||
|
CString szFileName = m_szGPT_Path;
|
||
|
szFileName += L"\\";
|
||
|
szFileName += CFGFILE;
|
||
|
FILE * f = _wfopen(szFileName, L"wt");
|
||
|
if (f)
|
||
|
{
|
||
|
fwprintf(f, L"%s=%i\n", KEY_NPBehavior, m_ToolDefaults.NPBehavior);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_fUseWizard, m_ToolDefaults.fUseWizard);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_fCustomDeployment, m_ToolDefaults.fCustomDeployment);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_UILevel, m_ToolDefaults.UILevel);
|
||
|
fwprintf(f, L"%s=%s\n", KEY_szStartPath, m_ToolDefaults.szStartPath);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_nUninstallTrackingMonths, m_ToolDefaults.nUninstallTrackingMonths);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_fUninstallOnPolicyRemoval, m_ToolDefaults.fUninstallOnPolicyRemoval);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_f32On64, m_ToolDefaults.f32On64);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_fZapOn64, m_ToolDefaults.fZapOn64);
|
||
|
fwprintf(f, L"%s=%i\n", KEY_fExtensionsOnly, m_ToolDefaults.fExtensionsOnly);
|
||
|
if (m_ToolDefaults.iDebugLevel > 0)
|
||
|
{
|
||
|
fwprintf(f, L"%s=%i\n", KEY_iDebugLevel, m_ToolDefaults.iDebugLevel);
|
||
|
}
|
||
|
if (m_ToolDefaults.fShowPkgDetails > 0)
|
||
|
{
|
||
|
fwprintf(f, L"%s=%i\n", KEY_fShowPkgDetails, m_ToolDefaults.fShowPkgDetails);
|
||
|
}
|
||
|
fclose(f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CScopePane::GetClassStoreName
|
||
|
//
|
||
|
// Synopsis: Gets the name of the class store from the DS.
|
||
|
// If the name isn't stored under the "defaultClassStore"
|
||
|
// property then the name "CN = Class Store" is used and the
|
||
|
// property is set.
|
||
|
//
|
||
|
// Arguments: [sz] - [out] name of the class store
|
||
|
// [fCreateOK] - [in] TRUE if the class store is to be created
|
||
|
// if it doesn't already exist. Otherwise this
|
||
|
// routine fails if the class store isn't found.
|
||
|
//
|
||
|
// Returns: S_OK on success
|
||
|
//
|
||
|
// History: 2-17-1998 stevebl Created
|
||
|
//
|
||
|
// Notes: Assumes m_szLDAP_Path contains the path to the DS object.
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
HRESULT CScopePane::GetClassStoreName(CString &sz, BOOL fCreateOK)
|
||
|
{
|
||
|
if (m_fRSOP)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
HRESULT hr;
|
||
|
LPOLESTR szCSPath;
|
||
|
hr = CsGetClassStorePath((LPOLESTR)((LPCOLESTR)m_szLDAP_Path), &szCSPath);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
sz = szCSPath;
|
||
|
OLESAFE_DELETE(szCSPath);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (fCreateOK)
|
||
|
{
|
||
|
// set sz to the default setting and save the path
|
||
|
IADsPathname * pADsPathname = NULL;
|
||
|
hr = CoCreateInstance(CLSID_Pathname,
|
||
|
NULL,
|
||
|
CLSCTX_INPROC_SERVER,
|
||
|
IID_IADsPathname,
|
||
|
(LPVOID*)&pADsPathname);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = pADsPathname->Set((LPOLESTR)((LPCOLESTR)m_szLDAP_Path), ADS_SETTYPE_FULL);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
pADsPathname->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = pADsPathname->AddLeafElement(L"CN=Class Store");
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
pADsPathname->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
BSTR bstr;
|
||
|
|
||
|
hr = pADsPathname->Retrieve(ADS_FORMAT_X500_NO_SERVER, &bstr);
|
||
|
|
||
|
pADsPathname->Release();
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
sz = bstr;
|
||
|
SysFreeString(bstr);
|
||
|
|
||
|
// This has to be here becuase CsSetClassStorePath will fail if the
|
||
|
// class store doesn't already exist.
|
||
|
hr = CsCreateClassStore((LPOLESTR)((LPCOLESTR)sz));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Changed to CS_E_OBJECT_ALREADY_EXISTS.
|
||
|
// I check for both ERROR_ALREAD_EXISTS and CS_E_OBJECT_ALREADY_EXISTS
|
||
|
// just to be safe.
|
||
|
if ((hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) && (hr != CS_E_OBJECT_ALREADY_EXISTS))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CScopePane::GetPackageDSPath
|
||
|
//
|
||
|
// Synopsis: gets the path to an individual package's DS object
|
||
|
//
|
||
|
// Arguments: [szPath] - [out] LDAP path to the package
|
||
|
// [szPackageName] - [in] name of the package
|
||
|
//
|
||
|
// Returns: S_OK on success
|
||
|
//
|
||
|
// History: 3-26-1998 stevebl Created
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
HRESULT CScopePane::GetPackageDSPath(CString &szPath, LPOLESTR szPackageName)
|
||
|
{
|
||
|
#if 1
|
||
|
LPOLESTR sz;
|
||
|
HRESULT hr = m_pIClassAdmin->GetDNFromPackageName(szPackageName, &sz);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
szPath = sz;
|
||
|
OLESAFE_DELETE(sz);
|
||
|
#else
|
||
|
HRESULT hr = GetClassStoreName(szPath, FALSE);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// set sz to the default setting and save the path
|
||
|
IADsPathname * pADsPathname = NULL;
|
||
|
hr = CoCreateInstance(CLSID_Pathname,
|
||
|
NULL,
|
||
|
CLSCTX_INPROC_SERVER,
|
||
|
IID_IADsPathname,
|
||
|
(LPVOID*)&pADsPathname);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = pADsPathname->Set((LPOLESTR)((LPCOLESTR)szPath), ADS_SETTYPE_FULL);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
pADsPathname->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = pADsPathname->AddLeafElement(L"CN=Packages");
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
pADsPathname->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
CString sz = L"CN=";
|
||
|
sz+= szPackageName;
|
||
|
hr = pADsPathname->AddLeafElement((LPOLESTR)((LPCOLESTR)sz));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
pADsPathname->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
BSTR bstr;
|
||
|
|
||
|
hr = pADsPathname->Retrieve(ADS_FORMAT_X500_NO_SERVER, &bstr);
|
||
|
|
||
|
pADsPathname->Release();
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
szPath = bstr;
|
||
|
SysFreeString(bstr);
|
||
|
#endif
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CScopePane::GetClassStore
|
||
|
//
|
||
|
// Synopsis: gets the IClassAdmin interface and creates a class store if
|
||
|
// it doesn't already exist.
|
||
|
//
|
||
|
// Arguments: [fCreateOK] - TRUE if the Class Store should be created if
|
||
|
// it doesn't already exist.
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Modifies: m_pIClassAdmin
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// History: 2-11-1998 stevebl Created
|
||
|
//
|
||
|
// Notes: Assumes m_szLDAP_Path contains the path to the DS object
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
HRESULT CScopePane::GetClassStore(BOOL fCreateOK)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CString szCSPath;
|
||
|
hr = GetClassStoreName(szCSPath, fCreateOK);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = CsGetClassStore((LPOLESTR)((LPCOLESTR)szCSPath), (LPVOID*)&m_pIClassAdmin);
|
||
|
if (FAILED(hr) && fCreateOK)
|
||
|
{
|
||
|
// Sometimes we can get into this wierd state where
|
||
|
// GetClassStoreName was able to create a entry for the class store
|
||
|
// name but it wasn't able to actually create the class store. This
|
||
|
// should handle that special case.
|
||
|
// Try and create it here and then bind to it again.
|
||
|
hr = CsCreateClassStore((LPOLESTR)((LPCOLESTR)szCSPath));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Changed to CS_E_OBJECT_ALREADY_EXISTS.
|
||
|
// I check for both ERROR_ALREAD_EXISTS and CS_E_OBJECT_ALREADY_EXISTS
|
||
|
// just to be safe.
|
||
|
// I'll check for both just to be safe.
|
||
|
if ((hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) && (hr != CS_E_OBJECT_ALREADY_EXISTS))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
}
|
||
|
hr = CsGetClassStore((LPOLESTR)((LPCOLESTR)szCSPath), (LPVOID*)&m_pIClassAdmin);
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
UINT CScopePane::CreateNestedDirectory (LPTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||
|
{
|
||
|
TCHAR szDirectory[MAX_PATH];
|
||
|
LPTSTR lpEnd;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Check for NULL pointer
|
||
|
//
|
||
|
|
||
|
if (!lpDirectory || !(*lpDirectory)) {
|
||
|
SetLastError(ERROR_INVALID_DATA);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// First, see if we can create the directory without having
|
||
|
// to build parent directories.
|
||
|
//
|
||
|
|
||
|
if (CreateDirectory (lpDirectory, lpSecurityAttributes)) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If this directory exists already, this is OK too.
|
||
|
//
|
||
|
|
||
|
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||
|
return ERROR_ALREADY_EXISTS;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// No luck, copy the string to a buffer we can munge
|
||
|
//
|
||
|
|
||
|
lstrcpy (szDirectory, lpDirectory);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Find the first subdirectory name
|
||
|
//
|
||
|
|
||
|
lpEnd = szDirectory;
|
||
|
|
||
|
if (szDirectory[1] == TEXT(':')) {
|
||
|
lpEnd += 3;
|
||
|
} else if (szDirectory[1] == TEXT('\\')) {
|
||
|
|
||
|
//
|
||
|
// Skip the first two slashes
|
||
|
//
|
||
|
|
||
|
lpEnd += 2;
|
||
|
|
||
|
//
|
||
|
// Find the slash between the server name and
|
||
|
// the share name.
|
||
|
//
|
||
|
|
||
|
while (*lpEnd && *lpEnd != TEXT('\\')) {
|
||
|
lpEnd++;
|
||
|
}
|
||
|
|
||
|
if (!(*lpEnd)) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Skip the slash, and find the slash between
|
||
|
// the share name and the directory name.
|
||
|
//
|
||
|
|
||
|
lpEnd++;
|
||
|
|
||
|
while (*lpEnd && *lpEnd != TEXT('\\')) {
|
||
|
lpEnd++;
|
||
|
}
|
||
|
|
||
|
if (!(*lpEnd)) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Leave pointer at the beginning of the directory.
|
||
|
//
|
||
|
|
||
|
lpEnd++;
|
||
|
|
||
|
|
||
|
} else if (szDirectory[0] == TEXT('\\')) {
|
||
|
lpEnd++;
|
||
|
}
|
||
|
|
||
|
while (*lpEnd) {
|
||
|
|
||
|
while (*lpEnd && *lpEnd != TEXT('\\')) {
|
||
|
lpEnd++;
|
||
|
}
|
||
|
|
||
|
if (*lpEnd == TEXT('\\')) {
|
||
|
*lpEnd = TEXT('\0');
|
||
|
|
||
|
if (!CreateDirectory (szDirectory, NULL)) {
|
||
|
|
||
|
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*lpEnd = TEXT('\\');
|
||
|
lpEnd++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Create the final directory
|
||
|
//
|
||
|
|
||
|
if (CreateDirectory (szDirectory, lpSecurityAttributes)) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||
|
return ERROR_ALREADY_EXISTS;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Failed
|
||
|
//
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//// Notify handlers for IComponentData
|
||
|
|
||
|
HRESULT CScopePane::OnAdd(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CScopePane::OnExpand(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
|
||
|
{
|
||
|
if (arg == TRUE)
|
||
|
{
|
||
|
// Did Initialize get called?
|
||
|
ASSERT(m_pScope != NULL);
|
||
|
|
||
|
EnumerateScopePane(cookie,
|
||
|
param);
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CScopePane::OnSelect(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
HRESULT CScopePane::OnContextMenu(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CScopePane::OnProperties(LPARAM param)
|
||
|
{
|
||
|
if (param == NULL)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
ASSERT(param != NULL);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CScopePane::EnumerateScopePane(MMC_COOKIE cookie, HSCOPEITEM pParent)
|
||
|
{
|
||
|
if (m_fRSOP && !m_fRSOPEnumerate)
|
||
|
{
|
||
|
// don't allow an empty RSOP database to enumerate the snapin
|
||
|
return;
|
||
|
}
|
||
|
// make sure that the result pane gets enumerated once
|
||
|
// so that internal structures get initialized.
|
||
|
|
||
|
// We only have one folder so this is really easy.
|
||
|
if (cookie != NULL)
|
||
|
return ;
|
||
|
|
||
|
if (m_fExtension)
|
||
|
{
|
||
|
// if we're an extension then add a root folder to hang everything off of
|
||
|
SCOPEDATAITEM * m_pScopeItem = new SCOPEDATAITEM;
|
||
|
memset(m_pScopeItem, 0, sizeof(SCOPEDATAITEM));
|
||
|
m_pScopeItem->mask = SDI_STR | SDI_PARAM | SDI_CHILDREN;
|
||
|
#ifdef SET_SCOPE_ICONS
|
||
|
m_pScopeItem->mask |= SDI_IMAGE | SDI_OPENIMAGE;
|
||
|
if (m_fRSOP && m_fRSOPPolicyFailed)
|
||
|
{
|
||
|
m_pScopeItem->nImage = IMG_CLOSED_FAILED;
|
||
|
m_pScopeItem->nOpenImage = IMG_OPEN_FAILED;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pScopeItem->nImage = IMG_CLOSEDBOX;
|
||
|
m_pScopeItem->nOpenImage = IMG_OPENBOX;
|
||
|
}
|
||
|
#endif
|
||
|
m_pScopeItem->relativeID = pParent;
|
||
|
m_pScopeItem->displayname = (unsigned short *)-1;
|
||
|
m_pScopeItem->lParam = -1; // made up cookie for my main folder
|
||
|
m_pScope->InsertItem(m_pScopeItem);
|
||
|
}
|
||
|
if (m_pIClassAdmin)
|
||
|
{
|
||
|
// if there's no IClassAdmin then there's nothing to enumerate
|
||
|
set <CResultPane *>::iterator i;
|
||
|
for (i = m_sResultPane.begin(); i != m_sResultPane.end(); i++)
|
||
|
{
|
||
|
(*i)->EnumerateResultPane(cookie);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetSnapinDescription(LPOLESTR * lpDescription)
|
||
|
{
|
||
|
OLESAFE_COPYSTRING(*lpDescription, L"description");
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetProvider(LPOLESTR * lpName)
|
||
|
{
|
||
|
OLESAFE_COPYSTRING(*lpName, L"provider");
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetSnapinVersion(LPOLESTR * lpVersion)
|
||
|
{
|
||
|
OLESAFE_COPYSTRING(*lpVersion, L"version");
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetSnapinImage(HICON * hAppIcon)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetStaticFolderImage(HBITMAP * hSmallImage,
|
||
|
HBITMAP * hSmallImageOpen,
|
||
|
HBITMAP * hLargeImage,
|
||
|
COLORREF * cMask)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
|
||
|
{
|
||
|
LPOLESTR lpHelpFile;
|
||
|
|
||
|
|
||
|
lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
|
||
|
|
||
|
if (!lpHelpFile)
|
||
|
{
|
||
|
DebugMsg((DM_WARNING, TEXT("CScopePane::GetHelpTopic: Failed to allocate memory.")));
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
if (m_fRSOP)
|
||
|
{
|
||
|
ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\RSOP.chm::/RSPintro.htm",
|
||
|
lpHelpFile, MAX_PATH);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\SPConcepts.chm::/ADE.htm",
|
||
|
lpHelpFile, MAX_PATH);
|
||
|
}
|
||
|
|
||
|
*lpCompiledHelpFile = lpHelpFile;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
void CScopePane::DeleteList()
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
ASSERT(pScopeDataItem != NULL);
|
||
|
if (pScopeDataItem == NULL)
|
||
|
return E_POINTER;
|
||
|
|
||
|
if (pScopeDataItem->lParam == -1)
|
||
|
{
|
||
|
m_szFolderTitle.LoadString(IDS_FOLDER_TITLE);
|
||
|
pScopeDataItem->displayname = (unsigned short *)((LPCOLESTR)m_szFolderTitle);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(pScopeDataItem->mask == TVIF_TEXT);
|
||
|
pScopeDataItem->displayname = (unsigned short *)((LPCOLESTR)m_AppData[pScopeDataItem->lParam].m_pDetails->pszPackageName);
|
||
|
}
|
||
|
|
||
|
ASSERT(pScopeDataItem->displayname != NULL);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
|
||
|
{
|
||
|
if (lpDataObjectA == NULL || lpDataObjectB == NULL)
|
||
|
return E_POINTER;
|
||
|
|
||
|
// Make sure both data object are mine
|
||
|
INTERNAL* pA;
|
||
|
INTERNAL* pB;
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
pA = ExtractInternalFormat(lpDataObjectA);
|
||
|
pB = ExtractInternalFormat(lpDataObjectB);
|
||
|
|
||
|
if (pA != NULL && pB != NULL)
|
||
|
hr = ((pA->m_type == pB->m_type) && (pA->m_cookie == pB->m_cookie)) ? S_OK : S_FALSE;
|
||
|
|
||
|
FREE_INTERNAL(pA);
|
||
|
FREE_INTERNAL(pB);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// Scope item property pages:
|
||
|
STDMETHODIMP CScopePane::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
|
||
|
LONG_PTR handle,
|
||
|
LPDATAOBJECT lpIDataObject)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
|
||
|
|
||
|
if (!pInternal)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
MMC_COOKIE cookie = pInternal->m_cookie;
|
||
|
FREE_INTERNAL(pInternal);
|
||
|
|
||
|
//
|
||
|
// make sure we have an up-to-date categories list
|
||
|
//
|
||
|
ClearCategories();
|
||
|
if (m_fRSOP)
|
||
|
{
|
||
|
GetRSoPCategories();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = CsGetAppCategories(&m_CatList);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// report it
|
||
|
LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GETCATEGORIES_ERROR, hr, NULL);
|
||
|
|
||
|
// Since failure only means the categories list will be
|
||
|
// empty, we'll proceed as if nothing happened.
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the ToolDefs property page
|
||
|
//
|
||
|
m_pToolDefs = new CToolDefs();
|
||
|
m_pToolDefs->m_ppThis = &m_pToolDefs;
|
||
|
m_pToolDefs->m_pToolDefaults = & m_ToolDefaults;
|
||
|
m_pToolDefs->m_cookie = cookie;
|
||
|
m_pToolDefs->m_hConsoleHandle = handle;
|
||
|
m_pToolDefs->m_fMachine = m_fMachine;
|
||
|
hr = SetPropPageToDeleteOnClose(&m_pToolDefs->m_psp);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HPROPSHEETPAGE hToolDefs = CreateThemedPropertySheetPage(&m_pToolDefs->m_psp);
|
||
|
if (hToolDefs == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
lpProvider->AddPage(hToolDefs);
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Create the ToolAdvDefs property page
|
||
|
//
|
||
|
m_pToolAdvDefs = new CToolAdvDefs();
|
||
|
m_pToolAdvDefs->m_ppThis = &m_pToolAdvDefs;
|
||
|
m_pToolAdvDefs->m_pToolDefaults = & m_ToolDefaults;
|
||
|
m_pToolAdvDefs->m_cookie = cookie;
|
||
|
m_pToolAdvDefs->m_hConsoleHandle = handle;
|
||
|
m_pToolAdvDefs->m_fMachine = m_fMachine;
|
||
|
hr = SetPropPageToDeleteOnClose(&m_pToolAdvDefs->m_psp);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HPROPSHEETPAGE hToolAdvDefs = CreateThemedPropertySheetPage(&m_pToolAdvDefs->m_psp);
|
||
|
if (hToolAdvDefs == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
lpProvider->AddPage(hToolAdvDefs);
|
||
|
}
|
||
|
|
||
|
CString szCSPath;
|
||
|
hr = GetClassStoreName(szCSPath, FALSE);
|
||
|
if (SUCCEEDED(hr) && m_pIClassAdmin)
|
||
|
{
|
||
|
//
|
||
|
// Create the FileExt property page
|
||
|
//
|
||
|
m_pFileExt = new CFileExt();
|
||
|
m_pFileExt->m_ppThis = &m_pFileExt;
|
||
|
m_pFileExt->m_pScopePane = this;
|
||
|
|
||
|
// no longer need to marshal this, just set it
|
||
|
m_pFileExt->m_pIClassAdmin = m_pIClassAdmin;
|
||
|
m_pIClassAdmin->AddRef();
|
||
|
|
||
|
hr = SetPropPageToDeleteOnClose(&m_pFileExt->m_psp);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HPROPSHEETPAGE hFileExt = CreateThemedPropertySheetPage(&m_pFileExt->m_psp);
|
||
|
if (hFileExt == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
lpProvider->AddPage(hFileExt);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Create the FileExt property page without an IClassAdmin
|
||
|
//
|
||
|
m_pFileExt = new CFileExt();
|
||
|
m_pFileExt->m_ppThis = &m_pFileExt;
|
||
|
m_pFileExt->m_pScopePane = this;
|
||
|
hr = SetPropPageToDeleteOnClose(&m_pFileExt->m_psp);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HPROPSHEETPAGE hFileExt = CreateThemedPropertySheetPage(&m_pFileExt->m_psp);
|
||
|
if (hFileExt == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
lpProvider->AddPage(hFileExt);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the CatList property page
|
||
|
//
|
||
|
|
||
|
m_pCatList = new CCatList();
|
||
|
m_pCatList->m_szDomainName = m_szDomainName;
|
||
|
m_pCatList->m_ppThis = &m_pCatList;
|
||
|
m_pCatList->m_pScopePane = this;
|
||
|
m_pCatList->m_fRSOP = m_fRSOP;
|
||
|
hr = SetPropPageToDeleteOnClose(&m_pCatList->m_psp);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HPROPSHEETPAGE hCatList = CreateThemedPropertySheetPage(&m_pCatList->m_psp);
|
||
|
if (hCatList == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
lpProvider->AddPage(hCatList);
|
||
|
}
|
||
|
#ifdef DIGITAL_SIGNATURES
|
||
|
//
|
||
|
// Create the Digital Signatures property page
|
||
|
//
|
||
|
m_pSignatures = new CSignatures();
|
||
|
m_pSignatures->m_ppThis = &m_pSignatures;
|
||
|
m_pSignatures->m_pScopePane = this;
|
||
|
m_pSignatures->m_fRSOP = m_fRSOP;
|
||
|
m_pSignatures->m_pIGPEInformation = m_pIGPEInformation;
|
||
|
hr = SetPropPageToDeleteOnClose(&m_pSignatures->m_psp);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HPROPSHEETPAGE hSignatures = CreateThemedPropertySheetPage(&m_pSignatures->m_psp);
|
||
|
if (hSignatures == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
lpProvider->AddPage(hSignatures);
|
||
|
}
|
||
|
#endif // DIGITAL_SIGNATURES
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
// Scope item property pages:
|
||
|
STDMETHODIMP CScopePane::QueryPagesFor(LPDATAOBJECT lpDataObject)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
// Look at the data object and see if it an item that we want to have a property sheet
|
||
|
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
|
||
|
if (pInternal)
|
||
|
{
|
||
|
// The main Software Installation node only has a property sheet if
|
||
|
// we are not in RSOP mode.
|
||
|
if ((m_fRSOP != TRUE) && (CCT_SCOPE == pInternal->m_type))
|
||
|
{
|
||
|
FREE_INTERNAL(pInternal);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
FREE_INTERNAL(pInternal);
|
||
|
}
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CScopePane::IsScopePaneNode(LPDATAOBJECT lpDataObject)
|
||
|
{
|
||
|
BOOL bResult = FALSE;
|
||
|
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
|
||
|
if (pInternal)
|
||
|
{
|
||
|
if (pInternal->m_type == CCT_SCOPE)
|
||
|
bResult = TRUE;
|
||
|
|
||
|
FREE_INTERNAL(pInternal);
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// IExtendContextMenu implementation
|
||
|
//
|
||
|
STDMETHODIMP CScopePane::AddMenuItems(LPDATAOBJECT pDataObject,
|
||
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
||
|
LONG * pInsertionAllowed)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
|
||
|
if (!pInternal)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
CONTEXTMENUITEM menuitem;
|
||
|
WCHAR szName[256];
|
||
|
WCHAR szStatus[256];
|
||
|
menuitem.strName = szName;
|
||
|
menuitem.strStatusBarText = szStatus;
|
||
|
menuitem.fFlags = 0;
|
||
|
menuitem.fSpecialFlags = 0;
|
||
|
|
||
|
do {
|
||
|
|
||
|
if ((m_fRSOP != TRUE) && ((*pInsertionAllowed) & CCM_INSERTIONALLOWED_NEW))
|
||
|
{
|
||
|
//
|
||
|
// Add Application menu item
|
||
|
//
|
||
|
::LoadString(ghInstance, IDM_ADD_APP, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_ADD_APP_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_ADD_APP;
|
||
|
menuitem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_NEW;
|
||
|
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ((m_fRSOP == TRUE) && ((*pInsertionAllowed) & CCM_INSERTIONALLOWED_VIEW))
|
||
|
{
|
||
|
menuitem.lCommandID = 0;
|
||
|
menuitem.fFlags = MFT_SEPARATOR;
|
||
|
menuitem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
|
||
|
menuitem.fSpecialFlags = CCM_SPECIAL_SEPARATOR;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
::LoadString(ghInstance, IDM_WINNER, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_WINNER_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_WINNER;
|
||
|
menuitem.fFlags = menuitem.lCommandID == m_iViewState ? MFS_CHECKED | MFT_RADIOCHECK : 0;
|
||
|
menuitem.fSpecialFlags = 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
|
||
|
if ((m_dwRSOPFlags & RSOP_INFO_FLAG_DIAGNOSTIC_MODE) == RSOP_INFO_FLAG_DIAGNOSTIC_MODE)
|
||
|
{
|
||
|
// removed packages should only apply when I'm in diagnostic mode
|
||
|
::LoadString(ghInstance, IDM_REMOVED, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_REMOVED_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_REMOVED;
|
||
|
menuitem.fFlags = menuitem.lCommandID == m_iViewState ? MFS_CHECKED | MFT_RADIOCHECK : 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!m_fMachine)
|
||
|
{
|
||
|
::LoadString(ghInstance, IDM_ARP, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_ARP_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_ARP;
|
||
|
menuitem.fFlags = menuitem.lCommandID == m_iViewState ? MFS_CHECKED | MFT_RADIOCHECK : 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update & Remove application if this is a result pane item
|
||
|
//
|
||
|
|
||
|
if (pInternal->m_type == CCT_RESULT)
|
||
|
{
|
||
|
CAppData & data = m_AppData[pInternal->m_cookie];
|
||
|
DWORD dwFlags = data.m_pDetails->pInstallInfo->dwActFlags;
|
||
|
|
||
|
if ((m_fRSOP != TRUE) && ((*pInsertionAllowed) & CCM_INSERTIONALLOWED_TOP))
|
||
|
{
|
||
|
::LoadString(ghInstance, IDM_AUTOINST, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_AUTOINST_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_AUTOINST;
|
||
|
menuitem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
|
||
|
|
||
|
// only enable for published apps
|
||
|
if (dwFlags & ACTFLG_Published)
|
||
|
menuitem.fFlags = 0;
|
||
|
else
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
if (dwFlags & ACTFLG_OnDemandInstall)
|
||
|
menuitem.fFlags += MFS_CHECKED;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
|
||
|
::LoadString(ghInstance, IDM_ASSIGN, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_ASSIGN_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_ASSIGN;
|
||
|
if ((dwFlags & ACTFLG_Assigned) || (data.m_pDetails->pInstallInfo->PathType == SetupNamePath))
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
else
|
||
|
menuitem.fFlags = 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
|
||
|
::LoadString(ghInstance, IDM_PUBLISH, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_PUBLISH_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_PUBLISH;
|
||
|
if ((dwFlags & ACTFLG_Published) || m_fMachine)
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
else
|
||
|
menuitem.fFlags = 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
#if 0
|
||
|
::LoadString(ghInstance, IDM_DISABLE, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_DISABLE_DESC, szStatus, 256);
|
||
|
|
||
|
if (dwFlags & (ACTFLG_Published | ACTFLG_Assigned))
|
||
|
menuitem.fFlags = 0;
|
||
|
else
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
menuitem.lCommandID = IDM_DISABLE;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
#endif
|
||
|
menuitem.lCommandID = 0;
|
||
|
menuitem.fFlags = MFT_SEPARATOR;
|
||
|
menuitem.fSpecialFlags = CCM_SPECIAL_SEPARATOR;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
}
|
||
|
if ((m_fRSOP != TRUE) && ((*pInsertionAllowed) & CCM_INSERTIONALLOWED_TASK))
|
||
|
{
|
||
|
::LoadString(ghInstance, IDM_ASSIGN, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_ASSIGN_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_ASSIGN_T;
|
||
|
menuitem.fSpecialFlags = 0;
|
||
|
if ((dwFlags & ACTFLG_Assigned) || (data.m_pDetails->pInstallInfo->PathType == SetupNamePath))
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
else
|
||
|
menuitem.fFlags = 0;
|
||
|
menuitem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TASK;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
|
||
|
::LoadString(ghInstance, IDM_PUBLISH, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_PUBLISH_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_PUBLISH_T;
|
||
|
if ((dwFlags & ACTFLG_Published) || m_fMachine)
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
else
|
||
|
menuitem.fFlags = 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
#if 0
|
||
|
::LoadString(ghInstance, IDM_DISABLE, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_DISABLE_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_DISABLE_T;
|
||
|
if (dwFlags & (ACTFLG_Published | ACTFLG_Assigned))
|
||
|
menuitem.fFlags = 0;
|
||
|
else
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
#endif
|
||
|
menuitem.lCommandID = 0;
|
||
|
menuitem.fFlags = MFT_SEPARATOR;
|
||
|
menuitem.fSpecialFlags = CCM_SPECIAL_SEPARATOR;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
|
||
|
::LoadString(ghInstance, IDM_DEL_APP, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_DEL_APP_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_DEL_APP;
|
||
|
menuitem.fFlags = 0;
|
||
|
menuitem.fSpecialFlags = 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
|
||
|
::LoadString(ghInstance, IDM_REDEPLOY, szName, 256);
|
||
|
::LoadString(ghInstance, IDS_REDEPLOY_DESC, szStatus, 256);
|
||
|
menuitem.lCommandID = IDM_REDEPLOY;
|
||
|
if (data.m_pDetails->pInstallInfo->PathType == SetupNamePath)
|
||
|
menuitem.fFlags = MFS_DISABLED;
|
||
|
else
|
||
|
menuitem.fFlags = 0;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
menuitem.lCommandID = 0;
|
||
|
menuitem.fFlags = MFT_SEPARATOR;
|
||
|
menuitem.fSpecialFlags = CCM_SPECIAL_SEPARATOR;
|
||
|
hr = pContextMenuCallback->AddItem(&menuitem);
|
||
|
if (FAILED(hr))
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} while (FALSE);
|
||
|
|
||
|
|
||
|
FREE_INTERNAL(pInternal);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CScopePane::GetRSoPCategories(void)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
list <APPCATEGORYINFO> CatList;
|
||
|
IWbemLocator * pLocator = NULL;
|
||
|
IWbemServices * pNamespace = NULL;
|
||
|
IWbemClassObject * pObj = NULL;
|
||
|
IEnumWbemClassObject * pEnum = NULL;
|
||
|
BSTR strQueryLanguage = SysAllocString(TEXT("WQL"));
|
||
|
BSTR strQueryCategories = SysAllocString(TEXT("SELECT * FROM RSOP_ApplicationManagementCategory"));
|
||
|
BSTR strNamespace = SysAllocString(m_szRSOPNamespace);
|
||
|
ULONG n = 0;
|
||
|
hr = CoCreateInstance(CLSID_WbemLocator,
|
||
|
0,
|
||
|
CLSCTX_INPROC_SERVER,
|
||
|
IID_IWbemLocator,
|
||
|
(LPVOID *) & pLocator);
|
||
|
DebugReportFailure(hr, (DM_WARNING, L"GetRSoPCategories: CoCreateInstance failed with 0x%x", hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
hr = pLocator->ConnectServer(strNamespace,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&pNamespace);
|
||
|
DebugReportFailure(hr, (DM_WARNING, L"GetRSoPCategories: pLocator->ConnectServer failed with 0x%x", hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
// First perform the query to get the list of categories
|
||
|
|
||
|
// erase any existing list
|
||
|
ClearCategories();
|
||
|
|
||
|
// create a new one
|
||
|
hr = pNamespace->ExecQuery(strQueryLanguage,
|
||
|
strQueryCategories,
|
||
|
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
|
||
|
NULL,
|
||
|
&pEnum);
|
||
|
DebugReportFailure(hr, (DM_WARNING, L"GetRSoPCategories: pNamespace->ExecQuery failed with 0x%x", hr));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
do
|
||
|
{
|
||
|
hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &n);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
if (n > 0)
|
||
|
{
|
||
|
APPCATEGORYINFO ci;
|
||
|
memset(&ci, 0, sizeof(APPCATEGORYINFO));
|
||
|
ci.Locale = 0;
|
||
|
hr = GetParameter(pObj,
|
||
|
TEXT("CategoryId"),
|
||
|
ci.AppCategoryId);
|
||
|
DebugReportFailure(hr, (DM_WARNING, L"GetRSoPCategories: GetParameter(\"CategoryId\") failed with 0x%x", hr));
|
||
|
hr = GetParameter(pObj,
|
||
|
TEXT("Name"),
|
||
|
ci.pszDescription);
|
||
|
DebugReportFailure(hr, (DM_WARNING, L"GetRSoPCategories: GetParameter(\"Name\") failed with 0x%x", hr));
|
||
|
CatList.push_back(ci);
|
||
|
}
|
||
|
} while (n > 0);
|
||
|
|
||
|
// put the list of categories into the proper format so it matches
|
||
|
// what we would get from the class store
|
||
|
n = CatList.size();
|
||
|
if (n > 0)
|
||
|
{
|
||
|
m_CatList.pCategoryInfo =
|
||
|
(APPCATEGORYINFO *)OLEALLOC(sizeof(APPCATEGORYINFO) * n);
|
||
|
if (m_CatList.pCategoryInfo)
|
||
|
{
|
||
|
m_CatList.cCategory = n;
|
||
|
while (n--)
|
||
|
{
|
||
|
m_CatList.pCategoryInfo[n] = *CatList.begin();
|
||
|
CatList.erase(CatList.begin());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
cleanup:
|
||
|
SysFreeString(strQueryLanguage);
|
||
|
SysFreeString(strQueryCategories);
|
||
|
SysFreeString(strNamespace);
|
||
|
if (pObj)
|
||
|
{
|
||
|
pObj->Release();
|
||
|
}
|
||
|
if (pEnum)
|
||
|
{
|
||
|
pEnum->Release();
|
||
|
}
|
||
|
if (pNamespace)
|
||
|
{
|
||
|
pNamespace->Release();
|
||
|
}
|
||
|
if (pLocator)
|
||
|
{
|
||
|
pLocator->Release();
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT CScopePane::InitializeADE()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if ((!m_fRSOP) && (!m_pIClassAdmin))
|
||
|
{
|
||
|
// make sure directories are created:
|
||
|
CreateNestedDirectory ((LPOLESTR)((LPCOLESTR)m_szGPT_Path), NULL);
|
||
|
|
||
|
// try and get IClassAdmin
|
||
|
hr = GetClassStore(FALSE);
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
void CScopePane::Refresh()
|
||
|
{
|
||
|
if (m_fRSOP || ((!m_fBlockAddPackage) && (m_pIClassAdmin)))
|
||
|
{
|
||
|
|
||
|
map <MMC_COOKIE, CAppData>::iterator i;
|
||
|
set <CResultPane *>::iterator i2;
|
||
|
for (i2 = m_sResultPane.begin(); i2 != m_sResultPane.end(); i2++)
|
||
|
{
|
||
|
(*i2)->m_pResult->DeleteAllRsltItems();
|
||
|
}
|
||
|
for (i=m_AppData.begin(); i != m_AppData.end(); i++)
|
||
|
{
|
||
|
// if (i->second.m_fVisible)
|
||
|
// {
|
||
|
// }
|
||
|
OLESAFE_DELETE(i->second.m_psd);
|
||
|
FreePackageDetail(i->second.m_pDetails);
|
||
|
}
|
||
|
m_AppData.erase(m_AppData.begin(), m_AppData.end());
|
||
|
m_UpgradeIndex.erase(m_UpgradeIndex.begin(), m_UpgradeIndex.end());
|
||
|
m_Extensions.erase(m_Extensions.begin(), m_Extensions.end());
|
||
|
m_lLastAllocated = 0;
|
||
|
for (i2 = m_sResultPane.begin(); i2 != m_sResultPane.end(); i2++)
|
||
|
{
|
||
|
(*i2)->EnumerateResultPane(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CScopePane::Command(long nCommandID, LPDATAOBJECT pDataObject)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
|
||
|
if (!pInternal)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
// Note - snap-ins need to look at the data object and determine
|
||
|
// in what context the command is being called.
|
||
|
|
||
|
// Handle each of the commands.
|
||
|
switch (nCommandID)
|
||
|
{
|
||
|
case IDM_AUTOINST:
|
||
|
if (pInternal->m_type == CCT_RESULT)
|
||
|
{
|
||
|
CAppData &data = m_AppData[pInternal->m_cookie];
|
||
|
DWORD dwNewFlags = data.m_pDetails->pInstallInfo->dwActFlags ^ ACTFLG_OnDemandInstall;
|
||
|
ChangePackageState(data, dwNewFlags, TRUE);
|
||
|
}
|
||
|
break;
|
||
|
case IDM_ASSIGN:
|
||
|
case IDM_ASSIGN_T:
|
||
|
if (pInternal->m_type == CCT_RESULT)
|
||
|
{
|
||
|
CAppData &data = m_AppData[pInternal->m_cookie];
|
||
|
DWORD dwNewFlags = data.m_pDetails->pInstallInfo->dwActFlags;
|
||
|
dwNewFlags &= ~(ACTFLG_Published);
|
||
|
dwNewFlags |= (ACTFLG_Assigned | ACTFLG_UserInstall | ACTFLG_OnDemandInstall);
|
||
|
ChangePackageState(data, dwNewFlags, TRUE);
|
||
|
}
|
||
|
break;
|
||
|
case IDM_PUBLISH:
|
||
|
case IDM_PUBLISH_T:
|
||
|
if (pInternal->m_type == CCT_RESULT)
|
||
|
{
|
||
|
CAppData &data = m_AppData[pInternal->m_cookie];
|
||
|
DWORD dwNewFlags = data.m_pDetails->pInstallInfo->dwActFlags;
|
||
|
dwNewFlags &= ~ACTFLG_Assigned;
|
||
|
dwNewFlags |= ACTFLG_Published | ACTFLG_UserInstall;
|
||
|
ChangePackageState(data, dwNewFlags, TRUE);
|
||
|
}
|
||
|
break;
|
||
|
case IDM_DISABLE:
|
||
|
case IDM_DISABLE_T:
|
||
|
if (pInternal->m_type == CCT_RESULT)
|
||
|
{
|
||
|
CAppData &data = m_AppData[pInternal->m_cookie];
|
||
|
DWORD dwNewFlags = data.m_pDetails->pInstallInfo->dwActFlags;
|
||
|
dwNewFlags &= ~(ACTFLG_OnDemandInstall | ACTFLG_Assigned | ACTFLG_UserInstall | ACTFLG_Published);
|
||
|
ChangePackageState(data, dwNewFlags, TRUE);
|
||
|
}
|
||
|
break;
|
||
|
case IDM_REDEPLOY:
|
||
|
{
|
||
|
CAppData &data = m_AppData[pInternal->m_cookie];
|
||
|
CString sz;
|
||
|
sz.LoadString(IDS_REDEPLOYWARNING);
|
||
|
int iReturn = IDNO;
|
||
|
m_pConsole->MessageBox( sz,
|
||
|
data.m_pDetails->pszPackageName,
|
||
|
MB_YESNO,
|
||
|
&iReturn);
|
||
|
if (IDYES == iReturn)
|
||
|
{
|
||
|
CHourglass hourglass;
|
||
|
//CString szScriptPath = data.m_pDetails->pInstallInfo->pszScriptPath;
|
||
|
CString szScriptPath = m_szGPT_Path;
|
||
|
DWORD dwRevision;
|
||
|
HRESULT hr = S_OK;
|
||
|
BOOL bStatus;
|
||
|
|
||
|
szScriptPath += L"\\temp.aas";
|
||
|
CString szTransformList = L"";
|
||
|
int i;
|
||
|
if (data.m_pDetails->cSources > 1)
|
||
|
{
|
||
|
CString szSource = data.m_pDetails->pszSourceList[0];
|
||
|
int nChars = 1 + szSource.ReverseFind(L'\\');
|
||
|
BOOL fTransformsAtSource = TRUE;
|
||
|
for (i = 1; i < data.m_pDetails->cSources && TRUE == fTransformsAtSource; i++)
|
||
|
{
|
||
|
if (0 == wcsncmp(szSource, data.m_pDetails->pszSourceList[i], nChars))
|
||
|
{
|
||
|
// make sure there isn't a sub-path
|
||
|
int n = nChars;
|
||
|
while (0 != data.m_pDetails->pszSourceList[i][n] && TRUE == fTransformsAtSource)
|
||
|
{
|
||
|
if (data.m_pDetails->pszSourceList[i][n] == L'\\')
|
||
|
{
|
||
|
fTransformsAtSource = FALSE;
|
||
|
}
|
||
|
n++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fTransformsAtSource = FALSE;
|
||
|
}
|
||
|
}
|
||
|
if (fTransformsAtSource)
|
||
|
{
|
||
|
szTransformList = L"@";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szTransformList = L"|";
|
||
|
nChars = 0;
|
||
|
}
|
||
|
for (i = 1; i < data.m_pDetails->cSources; i++)
|
||
|
{
|
||
|
if (i > 1)
|
||
|
{
|
||
|
szTransformList += L";";
|
||
|
}
|
||
|
szTransformList += &data.m_pDetails->pszSourceList[i][nChars];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// disable MSI ui
|
||
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
||
|
|
||
|
// build the script file
|
||
|
|
||
|
DWORD dwPlatform;
|
||
|
|
||
|
if ( CAppData::Is64Bit( data.m_pDetails ) )
|
||
|
{
|
||
|
dwPlatform = MSIARCHITECTUREFLAGS_IA64;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwPlatform = MSIARCHITECTUREFLAGS_X86;
|
||
|
}
|
||
|
|
||
|
UINT uMsiStatus = MsiAdvertiseProductEx(
|
||
|
data.m_pDetails->pszSourceList[0],
|
||
|
szScriptPath,
|
||
|
szTransformList,
|
||
|
LANGIDFROMLCID(data.m_pDetails->pPlatformInfo->prgLocale[0]),
|
||
|
dwPlatform,
|
||
|
0);
|
||
|
|
||
|
if (uMsiStatus)
|
||
|
{
|
||
|
DebugMsg((DM_WARNING, TEXT("MsiAdvertiseProduct failed with %u"), uMsiStatus));
|
||
|
hr = HRESULT_FROM_WIN32(uMsiStatus);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
dwRevision = data.m_pDetails->pInstallInfo->dwRevision + 1;
|
||
|
hr = m_pIClassAdmin->ChangePackageProperties(data.m_pDetails->pszPackageName,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&dwRevision);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// delete the old script
|
||
|
bStatus = DeleteFile(data.m_pDetails->pInstallInfo->pszScriptPath);
|
||
|
|
||
|
// rename the new one
|
||
|
if ( bStatus )
|
||
|
bStatus = MoveFile(szScriptPath, data.m_pDetails->pInstallInfo->pszScriptPath);
|
||
|
|
||
|
data.m_pDetails->pInstallInfo->dwRevision = dwRevision;
|
||
|
|
||
|
if ( bStatus )
|
||
|
{
|
||
|
if (FAILED(m_pIGPEInformation->PolicyChanged(m_fMachine, TRUE, &guidExtension,
|
||
|
m_fMachine ? &guidMachSnapin
|
||
|
: &guidUserSnapin)))
|
||
|
{
|
||
|
ReportPolicyChangedError(m_hwndMainWindow);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
|
||
|
if ( ! SUCCEEDED(hr) )
|
||
|
{
|
||
|
DebugMsg((DM_WARNING, TEXT("ChangePackageProperties failed with 0x%x"), hr));
|
||
|
// display failure message
|
||
|
sz.LoadString(IDS_REDEPLOYERROR);
|
||
|
m_pConsole->MessageBox(sz,
|
||
|
data.m_pDetails->pszPackageName,
|
||
|
MB_OK | MB_ICONEXCLAMATION, NULL);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case IDM_ADD_APP:
|
||
|
{
|
||
|
if (!m_fBlockAddPackage)
|
||
|
{
|
||
|
m_fBlockAddPackage=TRUE;
|
||
|
CString szExtension;
|
||
|
CString szFilter;
|
||
|
szExtension.LoadString(IDS_DEF_EXTENSION);
|
||
|
if (m_fMachine)
|
||
|
{
|
||
|
szFilter.LoadString(IDS_EXTENSION_FILTER_M);
|
||
|
}
|
||
|
else
|
||
|
szFilter.LoadString(IDS_EXTENSION_FILTER);
|
||
|
OPENFILENAME ofn;
|
||
|
memset(&ofn, 0, sizeof(ofn));
|
||
|
ofn.lStructSize = sizeof(ofn);
|
||
|
ofn.hwndOwner = GetActiveWindow();
|
||
|
ofn.hInstance = ghInstance;
|
||
|
TCHAR lpstrFilter[MAX_PATH];
|
||
|
wcsncpy(lpstrFilter, szFilter, MAX_PATH);
|
||
|
ofn.lpstrFilter = lpstrFilter;
|
||
|
TCHAR szFileTitle[MAX_PATH];
|
||
|
TCHAR szFile[MAX_PATH];
|
||
|
szFile[0] = NULL;
|
||
|
ofn.lpstrFile = szFile;
|
||
|
ofn.nMaxFile = MAX_PATH;
|
||
|
ofn.lpstrFileTitle = szFileTitle;
|
||
|
ofn.nMaxFileTitle = MAX_PATH;
|
||
|
ofn.lpstrInitialDir = m_ToolDefaults.szStartPath;
|
||
|
ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ALLOWMULTISELECT;
|
||
|
ofn.lpstrDefExt = szExtension;
|
||
|
int iBreak = 0;
|
||
|
while (lpstrFilter[iBreak])
|
||
|
{
|
||
|
if (lpstrFilter[iBreak] == TEXT('|'))
|
||
|
{
|
||
|
lpstrFilter[iBreak] = 0;
|
||
|
}
|
||
|
iBreak++;
|
||
|
}
|
||
|
if (GetOpenFileName(&ofn))
|
||
|
{
|
||
|
CHourglass hourglass;
|
||
|
CString szPackagePath;
|
||
|
HRESULT hr = E_FAIL;
|
||
|
TCHAR szFile[MAX_PATH];
|
||
|
TCHAR * szNextFile = ofn.lpstrFile + ofn.nFileOffset;
|
||
|
TCHAR * szFileTitle = szFile + ofn.nFileOffset;
|
||
|
_tcscpy(szFile, ofn.lpstrFile);
|
||
|
if (0 == szFile[ofn.nFileOffset - 1])
|
||
|
{
|
||
|
// this is a list of files (not just one)
|
||
|
// need to put a slash here so it will work
|
||
|
szFile[ofn.nFileOffset - 1] = TEXT('\\');
|
||
|
}
|
||
|
TCHAR * szFileExtension;
|
||
|
|
||
|
// don't allow deployment over http or ftp
|
||
|
if (_wcsnicmp(ofn.lpstrFile, TEXT("http:"), 5) == 0
|
||
|
||
|
||
|
_wcsnicmp(ofn.lpstrFile, TEXT("ftp:"), 4) == 0)
|
||
|
{
|
||
|
CString sz;
|
||
|
sz.LoadString(IDS_ILLEGAL_PATH);
|
||
|
int iReturn = IDNO;
|
||
|
m_pConsole->MessageBox(sz, szPackagePath,
|
||
|
MB_OK | MB_ICONEXCLAMATION,
|
||
|
&iReturn);
|
||
|
goto skip_deployment;
|
||
|
}
|
||
|
|
||
|
// at this point I have a path and I have a list of file names
|
||
|
|
||
|
do
|
||
|
{
|
||
|
_tcscpy(szFileTitle, szNextFile);
|
||
|
|
||
|
hr = GetUNCPath (szFile, szPackagePath);
|
||
|
DebugMsg((DM_VERBOSE, TEXT("GetUNCPath(%s) returned %s"), szFile, szPackagePath));
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
CString sz;
|
||
|
sz.LoadString(IDS_NO_UNIVERSAL_NAME);
|
||
|
int iReturn = IDNO;
|
||
|
m_pConsole->MessageBox(sz, szPackagePath,
|
||
|
MB_YESNO | MB_ICONEXCLAMATION,
|
||
|
&iReturn);
|
||
|
if (IDYES != iReturn)
|
||
|
{
|
||
|
goto skip_deployment;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
szFileExtension = _tcsrchr(szFile, TEXT('.'));
|
||
|
|
||
|
|
||
|
if ((szFileExtension) &&
|
||
|
(0 == _wcsicmp(szFileExtension, L".zap")))
|
||
|
{
|
||
|
if (m_fMachine)
|
||
|
{
|
||
|
CString szText;
|
||
|
CString szTitle;
|
||
|
szText.LoadString(IDS_NO_ZAPS_ALLOWED);
|
||
|
// only allow ZAP files to be deployed to users
|
||
|
m_pConsole->MessageBox(
|
||
|
szText,
|
||
|
szTitle,
|
||
|
MB_OK | MB_ICONEXCLAMATION,
|
||
|
NULL);
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = AddZAPPackage(szPackagePath, szFileTitle);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = AddMSIPackage(szPackagePath, szFileTitle);
|
||
|
}
|
||
|
szNextFile += _tcslen(szNextFile) + 1;
|
||
|
} while (szNextFile[0]);
|
||
|
|
||
|
skip_deployment:
|
||
|
// Notify clients of change
|
||
|
if (SUCCEEDED(hr) && m_pIGPEInformation)
|
||
|
{
|
||
|
if (FAILED(m_pIGPEInformation->PolicyChanged(m_fMachine, TRUE, &guidExtension,
|
||
|
m_fMachine ? &guidMachSnapin
|
||
|
: &guidUserSnapin)))
|
||
|
{
|
||
|
ReportPolicyChangedError(m_hwndMainWindow);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
m_fBlockAddPackage = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// consider a message here
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
case IDM_WINNER:
|
||
|
case IDM_REMOVED:
|
||
|
case IDM_FAILED:
|
||
|
case IDM_ARP:
|
||
|
m_iViewState = nCommandID;
|
||
|
{
|
||
|
// change toolbar state
|
||
|
set <CResultPane *>::iterator i;
|
||
|
for (i = m_sResultPane.begin(); i != m_sResultPane.end(); i++)
|
||
|
{
|
||
|
if ((*i)->m_pToolbar)
|
||
|
{
|
||
|
(*i)->m_pToolbar->SetButtonState(IDM_WINNER,
|
||
|
BUTTONPRESSED,
|
||
|
FALSE);
|
||
|
(*i)->m_pToolbar->SetButtonState(IDM_REMOVED,
|
||
|
BUTTONPRESSED,
|
||
|
FALSE);
|
||
|
(*i)->m_pToolbar->SetButtonState(IDM_ARP,
|
||
|
BUTTONPRESSED,
|
||
|
FALSE);
|
||
|
(*i)->m_pToolbar->SetButtonState(nCommandID,
|
||
|
BUTTONPRESSED,
|
||
|
TRUE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// deliberately fall through to REFRESH
|
||
|
case IDM_REFRESH:
|
||
|
Refresh();
|
||
|
|
||
|
//
|
||
|
// In logging mode, we need to show a message box to the user
|
||
|
// in the case that ARP view is empty so that users are clear
|
||
|
// that this may be because ARP has not been run yet
|
||
|
//
|
||
|
if ( m_fRSOP &&
|
||
|
( IDM_ARP == nCommandID ) &&
|
||
|
( m_dwRSOPFlags & RSOP_INFO_FLAG_DIAGNOSTIC_MODE ) &&
|
||
|
! m_fDisplayedRsopARPWarning &&
|
||
|
( m_AppData.end() == m_AppData.begin() ) )
|
||
|
{
|
||
|
CString szTitle;
|
||
|
CString szText;
|
||
|
szTitle.LoadString(IDS_RSOP_ARP_WARNING_TITLE);
|
||
|
szText.LoadString(IDS_RSOP_ARP_WARNING);
|
||
|
int iReturn;
|
||
|
m_pConsole->MessageBox(szText,
|
||
|
szTitle,
|
||
|
MB_OK,
|
||
|
&iReturn);
|
||
|
|
||
|
m_fDisplayedRsopARPWarning = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
case IDM_DEL_APP:
|
||
|
if (pInternal->m_type == CCT_RESULT)
|
||
|
{
|
||
|
CAppData & data = m_AppData[pInternal->m_cookie];
|
||
|
if ((data.m_pDetails->pInstallInfo->PathType == SetupNamePath))
|
||
|
{
|
||
|
// this is a legacy app it can't be uninstalled
|
||
|
CString szTitle;
|
||
|
CString szText;
|
||
|
szTitle.LoadString(IDS_REMOVE_LEGACY_TITLE);
|
||
|
szText.LoadString(IDS_REMOVE_LEGACY_TEXT);
|
||
|
int iReturn = IDNO;
|
||
|
m_pConsole->MessageBox(szText,
|
||
|
szTitle,
|
||
|
MB_YESNO,
|
||
|
&iReturn);
|
||
|
if (IDYES == iReturn)
|
||
|
{
|
||
|
RemovePackage(pInternal->m_cookie, FALSE, FALSE);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CRemove dlg;
|
||
|
// Activate the theme context in order to theme this dialog
|
||
|
CThemeContextActivator themer;
|
||
|
|
||
|
int iReturn = dlg.DoModal();
|
||
|
|
||
|
if (IDOK == iReturn)
|
||
|
{
|
||
|
switch (dlg.m_iState)
|
||
|
{
|
||
|
case 0:
|
||
|
RemovePackage(pInternal->m_cookie, TRUE, FALSE);
|
||
|
break;
|
||
|
case 1:
|
||
|
RemovePackage(pInternal->m_cookie, FALSE, FALSE);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
static PFNDSCREATEISECINFO pDSCreateISecurityInfoObject = NULL;
|
||
|
static HINSTANCE hInst_dssec = NULL;
|
||
|
STDAPI DSCreateISecurityInfoObject(LPCWSTR pwszObjectPath,
|
||
|
LPCWSTR pwszObjectClass,
|
||
|
DWORD dwFlags,
|
||
|
LPSECURITYINFO * ppSI,
|
||
|
PFNREADOBJECTSECURITY pfnReadSD,
|
||
|
PFNWRITEOBJECTSECURITY pfnWriteSD,
|
||
|
LPARAM lpContext)
|
||
|
{
|
||
|
if (NULL == pDSCreateISecurityInfoObject)
|
||
|
{
|
||
|
if (NULL == hInst_dssec)
|
||
|
{
|
||
|
hInst_dssec = LoadLibrary(L"dssec.dll");
|
||
|
if (NULL == hInst_dssec)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
pDSCreateISecurityInfoObject = (PFNDSCREATEISECINFO)
|
||
|
GetProcAddress(hInst_dssec, "DSCreateISecurityInfoObject");
|
||
|
if (NULL == pDSCreateISecurityInfoObject)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
return pDSCreateISecurityInfoObject(pwszObjectPath, pwszObjectClass, dwFlags, ppSI, pfnReadSD, pfnWriteSD, lpContext);
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GetUNCPath
|
||
|
//
|
||
|
// Synopsis: This function takes in a driver based path and converts
|
||
|
// it to a UNC path
|
||
|
//
|
||
|
// Arguments:
|
||
|
// [in] [szPath] - The drive based path
|
||
|
// [out][szUNCPath] - The UNC path
|
||
|
//
|
||
|
// Returns:
|
||
|
// S_OK - If the function succeeds in obtaining a UNC path
|
||
|
// E_FAIL - If the function cannot obtain a UNC path
|
||
|
//
|
||
|
// History: 5/20/1998 RahulTh created
|
||
|
//
|
||
|
// Notes: If the function cannot obtain a UNC path, it simply copies szPath
|
||
|
// into szUNCPath on return.
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
HRESULT GetUNCPath (LPCOLESTR szPath, CString& szUNCPath)
|
||
|
{
|
||
|
TCHAR* lpszUNCName;
|
||
|
UNIVERSAL_NAME_INFO * pUni;
|
||
|
ULONG cbSize;
|
||
|
HRESULT hr;
|
||
|
DWORD retVal;
|
||
|
|
||
|
szUNCPath.Empty(); //safety measure
|
||
|
lpszUNCName = new TCHAR[MAX_PATH];
|
||
|
pUni = (UNIVERSAL_NAME_INFO*) lpszUNCName;
|
||
|
cbSize = MAX_PATH * sizeof(TCHAR);
|
||
|
|
||
|
retVal = WNetGetUniversalName(szPath,
|
||
|
UNIVERSAL_NAME_INFO_LEVEL,
|
||
|
(LPVOID) pUni,
|
||
|
&cbSize);
|
||
|
if (ERROR_MORE_DATA == retVal) //if the buffer was not large enough
|
||
|
{
|
||
|
delete [] pUni;
|
||
|
pUni = (UNIVERSAL_NAME_INFO *) new BYTE [cbSize];
|
||
|
retVal = WNetGetUniversalName(szPath,
|
||
|
UNIVERSAL_NAME_INFO_LEVEL,
|
||
|
pUni,
|
||
|
&cbSize);
|
||
|
}
|
||
|
|
||
|
if (NO_ERROR == retVal)
|
||
|
{
|
||
|
szUNCPath = pUni->lpUniversalName;
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szUNCPath = szPath;
|
||
|
if (0 != wcsncmp(szPath, L"\\\\", 2))
|
||
|
hr = E_FAIL; //probably not a remote share.
|
||
|
else
|
||
|
hr = S_OK; //probably a remote share.
|
||
|
}
|
||
|
delete[] pUni;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LogADEEvent
|
||
|
//
|
||
|
// Synopsis: logs an ADE event in the event log
|
||
|
//
|
||
|
// Arguments: [wType] - type of event
|
||
|
// [dwEventID] - event ID
|
||
|
// [hr] - HRESULT that triggered the event to be logged
|
||
|
// [szOptional] - additional descriptive text used by some events
|
||
|
//
|
||
|
// Returns: nothing
|
||
|
//
|
||
|
// Modifies: nothing
|
||
|
//
|
||
|
// History: 05-27-1999 stevebl Created
|
||
|
// 04-28-2000 stevebl Modified to allow more complex logging
|
||
|
//
|
||
|
// Notes: We attempt to use FormatMessage to craft a legible message
|
||
|
// but in the case that it fails, we just log the HRESULT.
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
void LogADEEvent(WORD wType, DWORD dwEventID, HRESULT hr, LPCWSTR szOptional)
|
||
|
{
|
||
|
TCHAR szBuffer[256];
|
||
|
DWORD dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
||
|
NULL,
|
||
|
hr,
|
||
|
0,
|
||
|
szBuffer,
|
||
|
sizeof(szBuffer) / sizeof(szBuffer[0]),
|
||
|
NULL);
|
||
|
if (0 == dw)
|
||
|
{
|
||
|
// FormatMessage failed.
|
||
|
// We'll have to come up with some sort of reasonable message.
|
||
|
wsprintf(szBuffer, TEXT("(HRESULT: 0x%lX)"), hr);
|
||
|
|
||
|
}
|
||
|
HANDLE hEventLog = OpenEventLog( NULL, ADE_EVENT_SOURCE );
|
||
|
|
||
|
if (hEventLog)
|
||
|
{
|
||
|
LPCWSTR rgsz[2];
|
||
|
rgsz[0] = szBuffer;
|
||
|
rgsz[1] = szOptional;
|
||
|
ReportEvent(hEventLog,
|
||
|
wType,
|
||
|
0,
|
||
|
dwEventID,
|
||
|
NULL,
|
||
|
NULL == szOptional ? 1 : 2,
|
||
|
sizeof(hr),
|
||
|
rgsz,
|
||
|
&hr);
|
||
|
|
||
|
CloseEventLog(hEventLog);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ReportGeneralPropertySheetError
|
||
|
//
|
||
|
// Synopsis: Pops up a message box indicating why changes to a property
|
||
|
// page could not be applies and logs the error in the event log.
|
||
|
//
|
||
|
// Arguments: [sz] - Title bar text
|
||
|
// [hr] - hresult of the error
|
||
|
//
|
||
|
// Returns: nothing
|
||
|
//
|
||
|
// History: 9-30-1998 stevebl Created
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
void ReportGeneralPropertySheetError(HWND hwnd, LPCWSTR sz, HRESULT hr)
|
||
|
{
|
||
|
LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GENERAL_ERROR, hr);
|
||
|
|
||
|
CString szMessage;
|
||
|
szMessage.LoadString(IDS_GENERALERROR);
|
||
|
|
||
|
MessageBox( hwnd,
|
||
|
szMessage,
|
||
|
sz,
|
||
|
MB_OK | MB_ICONEXCLAMATION);
|
||
|
}
|
||
|
|
||
|
void ReportPolicyChangedError(HWND hwnd)
|
||
|
{
|
||
|
CString szMessage;
|
||
|
szMessage.LoadString(IDS_ERRORPOLICYCHANGED);
|
||
|
MessageBox(hwnd,
|
||
|
szMessage,
|
||
|
NULL,
|
||
|
MB_OK | MB_ICONEXCLAMATION);
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LoadHelpInfo
|
||
|
//
|
||
|
// Synopsis: routine that loads and locks the help mapping resources
|
||
|
//
|
||
|
// Arguments: [nIDD] - ID of the dialog making the help request
|
||
|
//
|
||
|
// Returns: handle to the locked and loaded mapping table
|
||
|
//
|
||
|
// History: 10-22-1998 stevebl Created
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
LPDWORD LoadHelpInfo(UINT nIDD)
|
||
|
{
|
||
|
HRSRC hrsrc = FindResource(ghInstance, MAKEINTRESOURCE(nIDD),
|
||
|
MAKEINTRESOURCE(RT_HELPINFO));
|
||
|
if (hrsrc == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
HGLOBAL hHelpInfo = LoadResource(ghInstance, hrsrc);
|
||
|
if (hHelpInfo == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
LPDWORD lpdwHelpInfo = (LPDWORD)LockResource(hHelpInfo);
|
||
|
return lpdwHelpInfo;
|
||
|
}
|
||
|
|
||
|
#define RSOP_HELP_FILE TEXT("gpedit.hlp")
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: StandardHelp
|
||
|
//
|
||
|
// Synopsis: Standardized routine for bringing up context sensitive help.
|
||
|
//
|
||
|
// Arguments: [hWnd] - window that needs help
|
||
|
// [nIDD] - ID of the dialog making the request
|
||
|
// Notes:
|
||
|
//
|
||
|
//
|
||
|
// History: 10-22-1998 stevebl modified from the OLEDLG sources
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
void WINAPI StandardHelp(HWND hWnd, UINT nIDD, BOOL fRsop /* = FALSE */ )
|
||
|
{
|
||
|
LPDWORD lpdwHelpInfo = LoadHelpInfo(nIDD);
|
||
|
if (lpdwHelpInfo == NULL)
|
||
|
{
|
||
|
DebugMsg((DL_VERBOSE, TEXT("Warning: unable to load help information (RT_HELPINFO)\n")));
|
||
|
return;
|
||
|
}
|
||
|
WinHelp(hWnd, fRsop ? RSOP_HELP_FILE : HELP_FILE, HELP_WM_HELP, (DWORD_PTR)lpdwHelpInfo);
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: StandardContextMenu
|
||
|
//
|
||
|
// Synopsis: Standardized routine for bringing up context menu based help.
|
||
|
//
|
||
|
// Arguments: [hWnd] -
|
||
|
// [nIDD] - ID of the dialog making the request
|
||
|
//
|
||
|
// History: 10-22-1998 stevebl modified from the OLEDLG sources
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
void WINAPI StandardContextMenu(HWND hWnd, UINT nIDD, BOOL fRsop /* = FALSE */ )
|
||
|
{
|
||
|
LPDWORD lpdwHelpInfo = LoadHelpInfo(nIDD);
|
||
|
if (lpdwHelpInfo == NULL)
|
||
|
{
|
||
|
DebugMsg((DL_VERBOSE, TEXT("Warning: unable to load help information (RT_HELPINFO)\n")));
|
||
|
return;
|
||
|
}
|
||
|
WinHelp(hWnd, fRsop ? RSOP_HELP_FILE : HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)lpdwHelpInfo);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CreateThemedPropertyPage
|
||
|
//
|
||
|
// Synopsis: Helper function to make sure that property pages put up
|
||
|
// by the snap-in are themed.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 4/20/2001 RahulTh created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
HPROPSHEETPAGE CreateThemedPropertySheetPage(AFX_OLDPROPSHEETPAGE* psp)
|
||
|
{
|
||
|
PROPSHEETPAGE_V3 sp_v3 = {0};
|
||
|
CopyMemory (&sp_v3, psp, psp->dwSize);
|
||
|
sp_v3.dwSize = sizeof(sp_v3);
|
||
|
|
||
|
return (::CreatePropertySheetPage (&sp_v3));
|
||
|
}
|