//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: regutil.cpp // // Contents: // // Classes: // // Functions: // // History: 3/21/1997 RaviR Created //____________________________________________________________________________ // #include "stdafx.h" #include "regutil.h" #include "..\inc\strings.h" #include "policy.h" TCHAR g_szNodeTypesKey[] = TEXT("Software\\Microsoft\\MMC\\NodeTypes\\"); CExtensionsIterator::CExtensionsIterator() : m_pExtSI(NULL), m_ppExtUsed(NULL), m_pDynExtCLSID(NULL), m_cDynExt(0), m_nDynIndex(0), m_pMMCPolicy(NULL) { #ifdef DBG dbg_m_fInit = FALSE; #endif } CExtensionsIterator::~CExtensionsIterator() { if (NULL != m_pMMCPolicy) delete m_pMMCPolicy; delete [] m_ppExtUsed; } /*+-------------------------------------------------------------------------* * * CExtensionsIterator::ScInitialize * * PURPOSE: 1st variation - initializes the iterator from a dataobject and an extension type * * PARAMETERS: * LPDATAOBJECT pDataObject : * LPCTSTR pszExtensionTypeKey : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CExtensionsIterator::ScInitialize(LPDATAOBJECT pDataObject, LPCTSTR pszExtensionTypeKey) { DECLARE_SC(sc, TEXT("CExtensionsIterator::ScInitialize")); // validate inputs sc = ScCheckPointers(pDataObject, pszExtensionTypeKey); if(sc) return sc; // get the nodetype and the snap-in pointer CSnapInPtr spSnapIn; GUID guidNodeType; sc = CNodeInitObject::GetSnapInAndNodeType(pDataObject, &spSnapIn, &guidNodeType); if (sc) return sc; // Fix for bug #469922(9/20/2001): DynamicExtensions broken in MMC20 // Use member variable - stack variable lifetime is not long enough. ExtractDynExtensions(pDataObject, m_cachedDynExtens); //call the second init function sc = ScInitialize(spSnapIn,guidNodeType, pszExtensionTypeKey, m_cachedDynExtens.GetData(), m_cachedDynExtens.GetSize()); return sc; } /*+-------------------------------------------------------------------------* * * CExtensionsIterator::ScInitialize * * PURPOSE: 2nd variation (legacy) * * PARAMETERS: * CSnapIn * pSnapIn : * GUID& rGuidNodeType : * LPCTSTR pszExtensionTypeKey : * LPCLSID pDynExtCLSID : * int cDynExt : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CExtensionsIterator::ScInitialize(CSnapIn *pSnapIn, GUID& rGuidNodeType, LPCTSTR pszExtensionTypeKey, LPCLSID pDynExtCLSID, int cDynExt) { DECLARE_SC(sc, TEXT("CExtensionsIterator::ScInitialize")); // validate inputs sc = ScCheckPointers(pSnapIn, pszExtensionTypeKey); if(sc) return sc; // store the inputs m_spSnapIn = pSnapIn; m_pDynExtCLSID = pDynExtCLSID, m_cDynExt = cDynExt; // Count the static extensions CExtSI* pExtSI = m_spSnapIn->GetExtensionSnapIn(); int cExtStatic = 0; while (pExtSI != NULL) { cExtStatic++; pExtSI = pExtSI->Next(); } // Allocate array of extension pointers m_ppExtUsed = new CExtSI*[cExtStatic]; m_cExtUsed = 0; m_pMMCPolicy = new CPolicy; ASSERT(NULL != m_pMMCPolicy); // call init sc = Init(rGuidNodeType, pszExtensionTypeKey); if(sc) return sc; return sc; } HRESULT CExtensionsIterator::Init(GUID& rGuidNodeType, LPCTSTR pszExtensionTypeKey) { DECLARE_SC (sc, _T("CExtensionsIterator::Init")); CStr strBufDynExt; CStr strBuf = g_szNodeTypesKey; CCoTaskMemPtr spszNodeType; sc = StringFromCLSID(rGuidNodeType, &spszNodeType); if (sc) return (sc.ToHr()); strBuf += static_cast(spszNodeType); strBuf += _T("\\"); strBufDynExt = strBuf; strBufDynExt += g_szDynamicExtensions; strBuf += g_szExtensions; strBuf += _T("\\"); strBuf += pszExtensionTypeKey; // Try to open the optional dynamic extensions key (ignoring errors) m_rkeyDynExt.ScOpen (HKEY_LOCAL_MACHINE, strBufDynExt, KEY_READ); // Open the key sc = m_rkey.ScOpen (HKEY_LOCAL_MACHINE, strBuf, KEY_READ); if (sc) { /* * ignore ERROR_FILE_NOT_FOUND */ if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND)) sc.Clear(); else return (sc.ToHr()); } if (NULL == m_pMMCPolicy) return ((sc = E_OUTOFMEMORY).ToHr()); sc = m_pMMCPolicy->ScInit(); if (sc) return (sc.ToHr()); #ifdef DBG dbg_m_fInit = TRUE; #endif Reset(); return (sc.ToHr()); } BOOL CExtensionsIterator::_Extends(BOOL bStatically) { BOOL fRet = FALSE; ASSERT(!IsEnd()); LPOLESTR polestr = NULL; HRESULT hr = StringFromCLSID(GetCLSID(), &polestr); CHECK_HRESULT(hr); if (SUCCEEDED(hr)) { USES_CONVERSION; LPTSTR pszTemp = OLE2T(polestr); fRet = m_rkey.IsValuePresent( pszTemp) && m_pMMCPolicy->IsPermittedSnapIn(GetCLSID()); if (fRet && bStatically) fRet = !((HKEY)m_rkeyDynExt && m_rkeyDynExt.IsValuePresent(pszTemp)); CoTaskMemFree(polestr); } return fRet; } HRESULT MMCGetExtensionsForSnapIn(const CLSID& clsid, CExtensionsCache& extnsCache) { DECLARE_SC (sc, _T("MMCGetExtensionsForSnapIn")); CStr strBuf = SNAPINS_KEY; strBuf += _T("\\"); CCoTaskMemPtr spszNodeType; sc = StringFromCLSID(clsid, &spszNodeType); if (sc) return (sc.ToHr()); strBuf += static_cast(spszNodeType); strBuf += _T("\\"); strBuf += g_szNodeTypes; // Open the key CRegKeyEx rkeyNodeTypes; WORD wResId; sc = rkeyNodeTypes.ScOpen (HKEY_LOCAL_MACHINE, strBuf, KEY_READ); if (sc) { if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND)) sc = S_FALSE; return (sc.ToHr()); } USES_CONVERSION; TCHAR szSubKey[100]; for (DWORD iSubkey = 0; ; ++iSubkey) { DWORD cchName = countof(szSubKey); sc = rkeyNodeTypes.ScEnumKey (iSubkey, szSubKey, &cchName); if (sc) { if (sc == ScFromWin32 (ERROR_NO_MORE_ITEMS)) sc.Clear(); return (sc.ToHr()); } GUID guid; if ((sc = CLSIDFromString( T2W(szSubKey), &guid)).IsError() || (sc = ScGetExtensionsForNodeType(guid, extnsCache)).IsError()) { sc.Clear(); continue; } } return (sc.ToHr()); } SC ScGetExtensionsForNodeType(GUID& guid, CExtensionsCache& extnsCache) { DECLARE_SC (sc, _T("ScGetExtensionsForNodeType")); CStr strBuf = NODE_TYPES_KEY; strBuf += _T("\\"); CCoTaskMemPtr spszNodeType; sc = StringFromCLSID(guid, &spszNodeType); if (sc) return (sc.ToHr()); strBuf += static_cast(spszNodeType); // Open Dynamic Extensions key CStr strBufDyn = strBuf; strBufDyn += _T("\\"); strBufDyn += g_szDynamicExtensions; CRegKeyEx rkeyDynExtns; sc = rkeyDynExtns.ScOpen (HKEY_LOCAL_MACHINE, strBufDyn, KEY_READ); BOOL bDynExtnsKey = !sc.IsError(); sc.Clear(); // Open Extensions key strBuf += _T("\\"); strBuf += g_szExtensions; CRegKeyEx rkeyExtensions; sc = rkeyExtensions.ScOpen (HKEY_LOCAL_MACHINE, strBuf, KEY_READ); if (sc) { if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND)) sc = S_FALSE; return (sc.ToHr()); } USES_CONVERSION; TCHAR szValue[100]; LPCTSTR apszExtnType[] = {g_szNameSpace, g_szContextMenu, g_szToolbar, g_szPropertySheet, g_szTask, g_szView}; int iExtnTypeFlag[] = { CExtSI::EXT_TYPE_NAMESPACE, CExtSI::EXT_TYPE_CONTEXTMENU, CExtSI::EXT_TYPE_TOOLBAR, CExtSI::EXT_TYPE_PROPERTYSHEET, CExtSI::EXT_TYPE_TASK, CExtSI::EXT_TYPE_VIEW}; for (int i=0; i < countof(apszExtnType); ++i) { CRegKeyEx rkeyTemp; sc = rkeyTemp.ScOpen (rkeyExtensions, apszExtnType[i], KEY_READ); if (sc) { if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND)) { sc.Clear(); continue; } return (sc.ToHr()); } for (DWORD iValue = 0; ; ++iValue) { DWORD cchValue = countof(szValue); sc = rkeyTemp.ScEnumValue (iValue, szValue, &cchValue); if (sc) { if (sc == ScFromWin32 (ERROR_NO_MORE_ITEMS)) sc.Clear(); else sc.TraceAndClear(); break; // do NOT return; still need to loop through all snapins } GUID guid; sc = ::CLSIDFromString( T2W(szValue), &guid); if (sc) { sc.Clear(); continue; } int iCurTypes = 0; extnsCache.Lookup(guid, iCurTypes); /* * After getting the snapin that extends given nodetype we should check if the * snapin is registered under SNAPINS key. If not do not add the entry to the * CExtensionsCache. */ CRegKeyEx rkeySnapins; tstring strSnapin = SNAPINS_KEY; strSnapin += TEXT("\\"); strSnapin += szValue; sc = rkeySnapins.ScOpen(HKEY_LOCAL_MACHINE, strSnapin.data(), KEY_READ); if (sc) { sc.TraceAndClear(); continue; } iCurTypes |= iExtnTypeFlag[i]; if (bDynExtnsKey && rkeyDynExtns.IsValuePresent(szValue)) iCurTypes |= CExtSI::EXT_TYPE_DYNAMIC; else iCurTypes |= CExtSI::EXT_TYPE_STATIC; extnsCache.SetAt(guid, iCurTypes); } } return (sc.ToHr()); } BOOL ExtendsNodeNameSpace(GUID& rguidNodeType, CLSID* pclsidExtn) { BOOL bExtendsNameSpace = FALSE; USES_CONVERSION; OLECHAR szguid[40]; int iStat = StringFromGUID2(rguidNodeType, szguid, countof(szguid)); ASSERT(iStat != 0); // Create reg key string CStr strTestBuf = NODE_TYPES_KEY; strTestBuf += _T("\\"); strTestBuf += OLE2T(szguid); strTestBuf += _T("\\"); strTestBuf += g_szExtensions; strTestBuf += _T("\\"); strTestBuf += g_szNameSpace; CRegKeyEx rKey; SC sc = rKey.ScOpen (HKEY_LOCAL_MACHINE, strTestBuf, KEY_READ); if (sc) return (false); // checking for any extension or a particular extension if (pclsidExtn == NULL) { DWORD dwValues; LONG lResult = ::RegQueryInfoKey( rKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues, NULL, NULL, NULL, NULL); ASSERT(lResult == ERROR_SUCCESS); bExtendsNameSpace = (dwValues != 0); } else { iStat = StringFromGUID2(*pclsidExtn, szguid, countof(szguid)); ASSERT(iStat != 0); bExtendsNameSpace = rKey.IsValuePresent(OLE2T(szguid)); } return bExtendsNameSpace; } //+------------------------------------------------------------------- // // Member: GetSnapinNameFromCLSID // // Synopsis: Get the name of the snapin provided class id. // // Arguments: [clsid] - Class id of the snapin. // [wszSnapinName] - Name. // // Returns: true if success else false // //-------------------------------------------------------------------- bool GetSnapinNameFromCLSID(/*[in]*/ const CLSID& clsid, /*[out]*/ tstring& tszSnapinName) { tszSnapinName.erase(); WTL::CString strName; SC sc = ScGetSnapinNameFromRegistry (clsid, strName); if (sc) return false; tszSnapinName = strName; return true; } //+------------------------------------------------------------------- // // Member: ScGetAboutFromSnapinCLSID // // Synopsis: Get the CLSID of about object of given snapin. // // Arguments: [clsidSnapin] - Class id of the snapin. // [clsidAbout] - out param, about object class-id. // // Returns: SC // //-------------------------------------------------------------------- SC ScGetAboutFromSnapinCLSID(/*[in]*/ const CLSID& clsidSnapin, /*[out]*/ CLSID& clsidAbout) { DECLARE_SC(sc, TEXT("ScGetAboutFromSnapinCLSID")); // convert class id to string CCoTaskMemPtr spszClsid; sc = StringFromCLSID(clsidSnapin, &spszClsid); if (sc) return sc; USES_CONVERSION; SC scNoTrace = ScGetAboutFromSnapinCLSID(OLE2CT(spszClsid), clsidAbout); if (scNoTrace) return scNoTrace; return sc; } //+------------------------------------------------------------------- // // Member: ScGetAboutFromSnapinCLSID // // Synopsis: Get the CLSID of about object of given snapin. // // Arguments: [lpszClsidSnapin] - Class id of the snapin. // [clsidAbout] - out param, about object class-id. // // Returns: SC // //-------------------------------------------------------------------- SC ScGetAboutFromSnapinCLSID(/*[in]*/ LPCTSTR lpszClsidSnapin, /*[out]*/ CLSID& clsidAbout) { DECLARE_SC(sc, TEXT("ScGetAboutFromSnapinCLSID")); // Get About CRegKeyEx SnapinKey; LONG lRet = SnapinKey.Open(HKEY_LOCAL_MACHINE, SNAPINS_KEY, KEY_READ); if (ERROR_SUCCESS != lRet) return (sc = E_FAIL); lRet = SnapinKey.Open(SnapinKey, lpszClsidSnapin, KEY_READ); if (ERROR_SUCCESS != lRet) return (sc = E_FAIL); TCHAR szAbout[100]; DWORD dwSize = countof(szAbout); DWORD dwType = REG_SZ; SC scNoTrace = SnapinKey.ScQueryValue (g_szAbout, &dwType, szAbout, &dwSize); if (scNoTrace) return (scNoTrace); USES_CONVERSION; sc = CLSIDFromString(T2OLE(szAbout), &clsidAbout); if (sc) return sc; return sc; }