//+-------------------------------------------------------------------------- // // 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 #include "rsoputil.h" #include // 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 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(&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(&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(static_cast(bmp16x16)), reinterpret_cast(static_cast(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* pObject; CComObject::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(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(&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(&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* pObject; CComObject::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(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 ::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 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 ::iterator i; set ::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 ::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)); }