Leaked source code of windows server 2003
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.

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