Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

555 lines
13 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: regutil.cpp
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 3/21/1997 RaviR Created
  15. //____________________________________________________________________________
  16. //
  17. #include "stdafx.h"
  18. #include "regutil.h"
  19. #include "..\inc\strings.h"
  20. #include "policy.h"
  21. TCHAR g_szNodeTypesKey[] = TEXT("Software\\Microsoft\\MMC\\NodeTypes\\");
  22. CExtensionsIterator::CExtensionsIterator() :
  23. m_pExtSI(NULL),
  24. m_pDynExtCLSID(NULL),
  25. m_cDynExt(0),
  26. m_nDynIndex(0),
  27. m_pMMCPolicy(NULL),
  28. m_ppExtUsed(NULL)
  29. {
  30. #ifdef DBG
  31. dbg_m_fInit = FALSE;
  32. #endif
  33. }
  34. CExtensionsIterator::~CExtensionsIterator()
  35. {
  36. if (NULL != m_pMMCPolicy)
  37. delete m_pMMCPolicy;
  38. delete [] m_ppExtUsed;
  39. }
  40. /*+-------------------------------------------------------------------------*
  41. *
  42. * CExtensionsIterator::ScInitialize
  43. *
  44. * PURPOSE: 1st variation - initializes the iterator from a dataobject and an extension type
  45. *
  46. * PARAMETERS:
  47. * LPDATAOBJECT pDataObject :
  48. * LPCTSTR pszExtensionTypeKey :
  49. *
  50. * RETURNS:
  51. * SC
  52. *
  53. *+-------------------------------------------------------------------------*/
  54. SC
  55. CExtensionsIterator::ScInitialize(LPDATAOBJECT pDataObject, LPCTSTR pszExtensionTypeKey)
  56. {
  57. DECLARE_SC(sc, TEXT("CExtensionsIterator::ScInitialize"));
  58. // validate inputs
  59. sc = ScCheckPointers(pDataObject, pszExtensionTypeKey);
  60. if(sc)
  61. return sc;
  62. // get the nodetype and the snap-in pointer
  63. CSnapInPtr spSnapIn;
  64. GUID guidNodeType;
  65. sc = CNodeInitObject::GetSnapInAndNodeType(pDataObject, &spSnapIn, &guidNodeType);
  66. if (sc)
  67. return sc;
  68. // Fix for bug #469922(9/20/2001): [XPSP1 bug 599913]
  69. // DynamicExtensions broken in MMC20
  70. // Use member variable - stack variable lifetime is not long enough.
  71. ExtractDynExtensions(pDataObject, m_cachedDynExtens);
  72. //call the second init function
  73. sc = ScInitialize(spSnapIn,guidNodeType, pszExtensionTypeKey, m_cachedDynExtens.GetData(), m_cachedDynExtens.GetSize());
  74. return sc;
  75. }
  76. /*+-------------------------------------------------------------------------*
  77. *
  78. * CExtensionsIterator::ScInitialize
  79. *
  80. * PURPOSE: 2nd variation (legacy)
  81. *
  82. * PARAMETERS:
  83. * CSnapIn * pSnapIn :
  84. * GUID& rGuidNodeType :
  85. * LPCTSTR pszExtensionTypeKey :
  86. * LPCLSID pDynExtCLSID :
  87. * int cDynExt :
  88. *
  89. * RETURNS:
  90. * SC
  91. *
  92. *+-------------------------------------------------------------------------*/
  93. SC
  94. CExtensionsIterator::ScInitialize(CSnapIn *pSnapIn, GUID& rGuidNodeType, LPCTSTR pszExtensionTypeKey, LPCLSID pDynExtCLSID, int cDynExt)
  95. {
  96. DECLARE_SC(sc, TEXT("CExtensionsIterator::ScInitialize"));
  97. // validate inputs
  98. sc = ScCheckPointers(pSnapIn, pszExtensionTypeKey);
  99. if(sc)
  100. return sc;
  101. // store the inputs
  102. m_spSnapIn = pSnapIn;
  103. m_pDynExtCLSID = pDynExtCLSID,
  104. m_cDynExt = cDynExt;
  105. // Count the static extensions
  106. CExtSI* pExtSI = m_spSnapIn->GetExtensionSnapIn();
  107. int cExtStatic = 0;
  108. while (pExtSI != NULL)
  109. {
  110. cExtStatic++;
  111. pExtSI = pExtSI->Next();
  112. }
  113. // Allocate array of extension pointers
  114. m_ppExtUsed = new CExtSI*[cExtStatic];
  115. m_cExtUsed = 0;
  116. m_pMMCPolicy = new CPolicy;
  117. ASSERT(NULL != m_pMMCPolicy);
  118. // call init
  119. sc = Init(rGuidNodeType, pszExtensionTypeKey);
  120. if(sc)
  121. return sc;
  122. return sc;
  123. }
  124. HRESULT CExtensionsIterator::Init(GUID& rGuidNodeType, LPCTSTR pszExtensionTypeKey)
  125. {
  126. DECLARE_SC (sc, _T("CExtensionsIterator::Init"));
  127. CStr strBufDynExt;
  128. CStr strBuf = g_szNodeTypesKey;
  129. CCoTaskMemPtr<WCHAR> spszNodeType;
  130. sc = StringFromCLSID(rGuidNodeType, &spszNodeType);
  131. if (sc)
  132. return (sc.ToHr());
  133. strBuf += static_cast<WCHAR*>(spszNodeType);
  134. strBuf += _T("\\");
  135. strBufDynExt = strBuf;
  136. strBufDynExt += g_szDynamicExtensions;
  137. strBuf += g_szExtensions;
  138. strBuf += _T("\\");
  139. strBuf += pszExtensionTypeKey;
  140. // Try to open the optional dynamic extensions key (ignoring errors)
  141. m_rkeyDynExt.ScOpen (HKEY_LOCAL_MACHINE, strBufDynExt, KEY_READ);
  142. // Open the key
  143. sc = m_rkey.ScOpen (HKEY_LOCAL_MACHINE, strBuf, KEY_READ);
  144. if (sc)
  145. {
  146. /*
  147. * ignore ERROR_FILE_NOT_FOUND
  148. */
  149. if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND))
  150. sc.Clear();
  151. else
  152. return (sc.ToHr());
  153. }
  154. if (NULL == m_pMMCPolicy)
  155. return ((sc = E_OUTOFMEMORY).ToHr());
  156. sc = m_pMMCPolicy->ScInit();
  157. if (sc)
  158. return (sc.ToHr());
  159. #ifdef DBG
  160. dbg_m_fInit = TRUE;
  161. #endif
  162. Reset();
  163. return (sc.ToHr());
  164. }
  165. BOOL CExtensionsIterator::_Extends(BOOL bStatically)
  166. {
  167. BOOL fRet = FALSE;
  168. ASSERT(!IsEnd());
  169. LPOLESTR polestr = NULL;
  170. HRESULT hr = StringFromCLSID(GetCLSID(), &polestr);
  171. CHECK_HRESULT(hr);
  172. if (SUCCEEDED(hr))
  173. {
  174. USES_CONVERSION;
  175. LPTSTR pszTemp = OLE2T(polestr);
  176. fRet = m_rkey.IsValuePresent( pszTemp) && m_pMMCPolicy->IsPermittedSnapIn(GetCLSID());
  177. if (fRet && bStatically)
  178. fRet = !((HKEY)m_rkeyDynExt && m_rkeyDynExt.IsValuePresent(pszTemp));
  179. CoTaskMemFree(polestr);
  180. }
  181. return fRet;
  182. }
  183. HRESULT MMCGetExtensionsForSnapIn(const CLSID& clsid,
  184. CExtensionsCache& extnsCache)
  185. {
  186. DECLARE_SC (sc, _T("MMCGetExtensionsForSnapIn"));
  187. CStr strBuf = SNAPINS_KEY;
  188. strBuf += _T("\\");
  189. CCoTaskMemPtr<WCHAR> spszNodeType;
  190. sc = StringFromCLSID(clsid, &spszNodeType);
  191. if (sc)
  192. return (sc.ToHr());
  193. strBuf += static_cast<WCHAR*>(spszNodeType);
  194. strBuf += _T("\\");
  195. strBuf += g_szNodeTypes;
  196. // Open the key
  197. CRegKeyEx rkeyNodeTypes;
  198. WORD wResId;
  199. sc = rkeyNodeTypes.ScOpen (HKEY_LOCAL_MACHINE, strBuf, KEY_READ);
  200. if (sc)
  201. {
  202. if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND))
  203. sc = S_FALSE;
  204. return (sc.ToHr());
  205. }
  206. USES_CONVERSION;
  207. TCHAR szSubKey[100];
  208. for (DWORD iSubkey = 0; ; ++iSubkey)
  209. {
  210. DWORD cchName = countof(szSubKey);
  211. sc = rkeyNodeTypes.ScEnumKey (iSubkey, szSubKey, &cchName);
  212. if (sc)
  213. {
  214. if (sc == ScFromWin32 (ERROR_NO_MORE_ITEMS))
  215. sc.Clear();
  216. return (sc.ToHr());
  217. }
  218. GUID guid;
  219. if ((sc = CLSIDFromString( T2W(szSubKey), &guid)).IsError() ||
  220. (sc = ScGetExtensionsForNodeType(guid, extnsCache)).IsError())
  221. {
  222. sc.Clear();
  223. continue;
  224. }
  225. }
  226. return (sc.ToHr());
  227. }
  228. SC ScGetExtensionsForNodeType(GUID& guid, CExtensionsCache& extnsCache)
  229. {
  230. DECLARE_SC (sc, _T("ScGetExtensionsForNodeType"));
  231. CStr strBuf = NODE_TYPES_KEY;
  232. strBuf += _T("\\");
  233. CCoTaskMemPtr<WCHAR> spszNodeType;
  234. sc = StringFromCLSID(guid, &spszNodeType);
  235. if (sc)
  236. return (sc.ToHr());
  237. strBuf += static_cast<WCHAR*>(spszNodeType);
  238. // Open Dynamic Extensions key
  239. CStr strBufDyn = strBuf;
  240. strBufDyn += _T("\\");
  241. strBufDyn += g_szDynamicExtensions;
  242. CRegKeyEx rkeyDynExtns;
  243. sc = rkeyDynExtns.ScOpen (HKEY_LOCAL_MACHINE, strBufDyn, KEY_READ);
  244. BOOL bDynExtnsKey = !sc.IsError();
  245. sc.Clear();
  246. // Open Extensions key
  247. strBuf += _T("\\");
  248. strBuf += g_szExtensions;
  249. CRegKeyEx rkeyExtensions;
  250. sc = rkeyExtensions.ScOpen (HKEY_LOCAL_MACHINE, strBuf, KEY_READ);
  251. if (sc)
  252. {
  253. if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND))
  254. sc = S_FALSE;
  255. return (sc.ToHr());
  256. }
  257. USES_CONVERSION;
  258. TCHAR szValue[100];
  259. LPCTSTR apszExtnType[] = {g_szNameSpace, g_szContextMenu,
  260. g_szToolbar, g_szPropertySheet,
  261. g_szTask, g_szView};
  262. int iExtnTypeFlag[] = { CExtSI::EXT_TYPE_NAMESPACE, CExtSI::EXT_TYPE_CONTEXTMENU,
  263. CExtSI::EXT_TYPE_TOOLBAR, CExtSI::EXT_TYPE_PROPERTYSHEET,
  264. CExtSI::EXT_TYPE_TASK, CExtSI::EXT_TYPE_VIEW};
  265. for (int i=0; i < countof(apszExtnType); ++i)
  266. {
  267. CRegKeyEx rkeyTemp;
  268. sc = rkeyTemp.ScOpen (rkeyExtensions, apszExtnType[i], KEY_READ);
  269. if (sc)
  270. {
  271. if (sc == ScFromWin32 (ERROR_FILE_NOT_FOUND))
  272. {
  273. sc.Clear();
  274. continue;
  275. }
  276. return (sc.ToHr());
  277. }
  278. for (DWORD iValue = 0; ; ++iValue)
  279. {
  280. DWORD cchValue = countof(szValue);
  281. sc = rkeyTemp.ScEnumValue (iValue, szValue, &cchValue);
  282. if (sc)
  283. {
  284. if (sc == ScFromWin32 (ERROR_NO_MORE_ITEMS))
  285. sc.Clear();
  286. else
  287. sc.TraceAndClear();
  288. break; // do NOT return; still need to loop through all snapins
  289. }
  290. GUID guid;
  291. sc = ::CLSIDFromString( T2W(szValue), &guid);
  292. if (sc)
  293. {
  294. sc.Clear();
  295. continue;
  296. }
  297. int iCurTypes = 0;
  298. extnsCache.Lookup(guid, iCurTypes);
  299. /*
  300. * After getting the snapin that extends given nodetype we should check if the
  301. * snapin is registered under SNAPINS key. If not do not add the entry to the
  302. * CExtensionsCache.
  303. */
  304. CRegKeyEx rkeySnapins;
  305. tstring strSnapin = SNAPINS_KEY;
  306. strSnapin += TEXT("\\");
  307. strSnapin += szValue;
  308. sc = rkeySnapins.ScOpen(HKEY_LOCAL_MACHINE, strSnapin.data(), KEY_READ);
  309. if (sc)
  310. {
  311. sc.TraceAndClear();
  312. continue;
  313. }
  314. iCurTypes |= iExtnTypeFlag[i];
  315. if (bDynExtnsKey && rkeyDynExtns.IsValuePresent(szValue))
  316. iCurTypes |= CExtSI::EXT_TYPE_DYNAMIC;
  317. else
  318. iCurTypes |= CExtSI::EXT_TYPE_STATIC;
  319. extnsCache.SetAt(guid, iCurTypes);
  320. }
  321. }
  322. return (sc.ToHr());
  323. }
  324. BOOL ExtendsNodeNameSpace(GUID& rguidNodeType, CLSID* pclsidExtn)
  325. {
  326. BOOL bExtendsNameSpace = FALSE;
  327. USES_CONVERSION;
  328. OLECHAR szguid[40];
  329. int iStat = StringFromGUID2(rguidNodeType, szguid, countof(szguid));
  330. ASSERT(iStat != 0);
  331. // Create reg key string
  332. CStr strTestBuf = NODE_TYPES_KEY;
  333. strTestBuf += _T("\\");
  334. strTestBuf += OLE2T(szguid);
  335. strTestBuf += _T("\\");
  336. strTestBuf += g_szExtensions;
  337. strTestBuf += _T("\\");
  338. strTestBuf += g_szNameSpace;
  339. CRegKeyEx rKey;
  340. SC sc = rKey.ScOpen (HKEY_LOCAL_MACHINE, strTestBuf, KEY_READ);
  341. if (sc)
  342. return (false);
  343. // checking for any extension or a particular extension
  344. if (pclsidExtn == NULL)
  345. {
  346. DWORD dwValues;
  347. LONG lResult = ::RegQueryInfoKey( rKey, NULL, NULL, NULL, NULL, NULL, NULL,
  348. &dwValues, NULL, NULL, NULL, NULL);
  349. ASSERT(lResult == ERROR_SUCCESS);
  350. bExtendsNameSpace = (dwValues != 0);
  351. }
  352. else
  353. {
  354. iStat = StringFromGUID2(*pclsidExtn, szguid, countof(szguid));
  355. ASSERT(iStat != 0);
  356. bExtendsNameSpace = rKey.IsValuePresent(OLE2T(szguid));
  357. }
  358. return bExtendsNameSpace;
  359. }
  360. //+-------------------------------------------------------------------
  361. //
  362. // Member: GetSnapinNameFromCLSID
  363. //
  364. // Synopsis: Get the name of the snapin provided class id.
  365. //
  366. // Arguments: [clsid] - Class id of the snapin.
  367. // [wszSnapinName] - Name.
  368. //
  369. // Returns: true if success else false
  370. //
  371. //--------------------------------------------------------------------
  372. bool GetSnapinNameFromCLSID(/*[in]*/ const CLSID& clsid,
  373. /*[out]*/ tstring& tszSnapinName)
  374. {
  375. tszSnapinName.erase();
  376. WTL::CString strName;
  377. SC sc = ScGetSnapinNameFromRegistry (clsid, strName);
  378. if (sc)
  379. return false;
  380. tszSnapinName = strName;
  381. return true;
  382. }
  383. //+-------------------------------------------------------------------
  384. //
  385. // Member: ScGetAboutFromSnapinCLSID
  386. //
  387. // Synopsis: Get the CLSID of about object of given snapin.
  388. //
  389. // Arguments: [clsidSnapin] - Class id of the snapin.
  390. // [clsidAbout] - out param, about object class-id.
  391. //
  392. // Returns: SC
  393. //
  394. //--------------------------------------------------------------------
  395. SC ScGetAboutFromSnapinCLSID(/*[in]*/ const CLSID& clsidSnapin,
  396. /*[out]*/ CLSID& clsidAbout)
  397. {
  398. DECLARE_SC(sc, TEXT("ScGetAboutFromSnapinCLSID"));
  399. // convert class id to string
  400. CCoTaskMemPtr<WCHAR> spszClsid;
  401. sc = StringFromCLSID(clsidSnapin, &spszClsid);
  402. if (sc)
  403. return sc;
  404. USES_CONVERSION;
  405. SC scNoTrace = ScGetAboutFromSnapinCLSID(OLE2CT(spszClsid), clsidAbout);
  406. if (scNoTrace)
  407. return scNoTrace;
  408. return sc;
  409. }
  410. //+-------------------------------------------------------------------
  411. //
  412. // Member: ScGetAboutFromSnapinCLSID
  413. //
  414. // Synopsis: Get the CLSID of about object of given snapin.
  415. //
  416. // Arguments: [lpszClsidSnapin] - Class id of the snapin.
  417. // [clsidAbout] - out param, about object class-id.
  418. //
  419. // Returns: SC
  420. //
  421. //--------------------------------------------------------------------
  422. SC ScGetAboutFromSnapinCLSID(/*[in]*/ LPCTSTR lpszClsidSnapin,
  423. /*[out]*/ CLSID& clsidAbout)
  424. {
  425. DECLARE_SC(sc, TEXT("ScGetAboutFromSnapinCLSID"));
  426. // Get About
  427. CRegKeyEx SnapinKey;
  428. LONG lRet = SnapinKey.Open(HKEY_LOCAL_MACHINE, SNAPINS_KEY, KEY_READ);
  429. if (ERROR_SUCCESS != lRet)
  430. return (sc = E_FAIL);
  431. lRet = SnapinKey.Open(SnapinKey, lpszClsidSnapin, KEY_READ);
  432. if (ERROR_SUCCESS != lRet)
  433. return (sc = E_FAIL);
  434. TCHAR szAbout[100];
  435. DWORD dwSize = countof(szAbout);
  436. DWORD dwType = REG_SZ;
  437. SC scNoTrace = SnapinKey.ScQueryValue (g_szAbout, &dwType, szAbout, &dwSize);
  438. if (scNoTrace)
  439. return (scNoTrace);
  440. USES_CONVERSION;
  441. sc = CLSIDFromString(T2OLE(szAbout), &clsidAbout);
  442. if (sc)
  443. return sc;
  444. return sc;
  445. }