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.

307 lines
7.5 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. dynext.cpp
  7. dynamic extension helper
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "Dynext.h"
  12. #include "tregkey.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. const TCHAR g_szContextMenu[] = TEXT("ContextMenu");
  19. const TCHAR g_szNameSpace[] = TEXT("NameSpace");
  20. const TCHAR g_szPropertySheet[] = TEXT("PropertySheet");
  21. const TCHAR g_szToolbar[] = TEXT("Toolbar");
  22. const TCHAR g_szExtensions[] = TEXT("Extensions");
  23. const TCHAR g_szTask[] = TEXT("Task");
  24. const TCHAR g_szDynamicExtensions[] = TEXT("Dynamic Extensions");
  25. const TCHAR NODE_TYPES_KEY[] = TEXT("Software\\Microsoft\\MMC\\NodeTypes");
  26. const TCHAR SNAPINS_KEY[] = TEXT("Software\\Microsoft\\MMC\\SnapIns");
  27. CDynamicExtensions::CDynamicExtensions()
  28. {
  29. m_bLoaded = FALSE;
  30. }
  31. CDynamicExtensions::~CDynamicExtensions()
  32. {
  33. }
  34. HRESULT
  35. CDynamicExtensions::SetNode(const GUID * guid)
  36. {
  37. m_guidNode = *guid;
  38. return hrOK;
  39. }
  40. HRESULT
  41. CDynamicExtensions::Reset()
  42. {
  43. HRESULT hr = hrOK;
  44. m_aNameSpace.RemoveAll();
  45. m_aMenu.RemoveAll();
  46. m_aToolbar.RemoveAll();
  47. m_aPropSheet.RemoveAll();
  48. m_aTask.RemoveAll();
  49. m_bLoaded = FALSE;
  50. return hr;
  51. }
  52. HRESULT
  53. CDynamicExtensions::Load()
  54. {
  55. HRESULT hr = hrOK;
  56. LONG lRes;
  57. CGUIDArray aDynExtensions;
  58. Reset();
  59. OLECHAR szGuid[128] = {0};
  60. ::StringFromGUID2(m_guidNode, szGuid, 128);
  61. RegKey regkeyNodeTypes;
  62. lRes = regkeyNodeTypes.Open(HKEY_LOCAL_MACHINE, NODE_TYPES_KEY);
  63. Assert(lRes == ERROR_SUCCESS);
  64. if (lRes != ERROR_SUCCESS)
  65. {
  66. return HRESULT_FROM_WIN32(lRes); // failed to open
  67. }
  68. RegKey regkeyNode;
  69. lRes = regkeyNode.Open(regkeyNodeTypes, szGuid);
  70. if (lRes != ERROR_SUCCESS)
  71. {
  72. return HRESULT_FROM_WIN32(lRes); // failed to open
  73. }
  74. // open the key for dynamic extensions and enumerate
  75. RegKey regkeyDynExt;
  76. lRes = regkeyDynExt.Open(regkeyNode, g_szDynamicExtensions);
  77. if (lRes != ERROR_SUCCESS)
  78. {
  79. return HRESULT_FROM_WIN32(lRes); // failed to open
  80. }
  81. RegKey regkeyExtensions;
  82. lRes = regkeyExtensions.Open(regkeyNode, g_szExtensions);
  83. if (lRes != ERROR_SUCCESS)
  84. {
  85. return HRESULT_FROM_WIN32(lRes); // failed to open
  86. }
  87. CString strKey;
  88. RegValueIterator iterDynExt;
  89. iterDynExt.Init(&regkeyDynExt);
  90. while (iterDynExt.Next(&strKey, NULL) == hrOK)
  91. {
  92. GUID guid;
  93. ::CLSIDFromString(((LPTSTR) (LPCTSTR) strKey), &guid);
  94. if (!aDynExtensions.IsInList(guid))
  95. aDynExtensions.Add(guid);
  96. }
  97. // ok, have the list of dynamic extensions, now enumerate the various extension types
  98. // namespace extensions
  99. RegKey regkeyNSExt;
  100. lRes = regkeyNSExt.Open(regkeyExtensions, g_szNameSpace);
  101. if (lRes == ERROR_SUCCESS)
  102. {
  103. // enumerate the ns dynamic extensions
  104. RegValueIterator iterNSExt;
  105. iterNSExt.Init(&regkeyNSExt);
  106. while (iterNSExt.Next(&strKey, NULL) == hrOK)
  107. {
  108. GUID guid;
  109. ::CLSIDFromString(((LPTSTR) (LPCTSTR) strKey), &guid);
  110. if (aDynExtensions.IsInList(guid))
  111. m_aNameSpace.Add(guid);
  112. }
  113. }
  114. // Menu extensions
  115. RegKey regkeyMenuExt;
  116. lRes = regkeyMenuExt.Open(regkeyExtensions, g_szContextMenu);
  117. if (lRes == ERROR_SUCCESS)
  118. {
  119. // enumerate the ns dynamic extensions
  120. RegValueIterator iterMenuExt;
  121. iterMenuExt.Init(&regkeyMenuExt);
  122. while (iterMenuExt.Next(&strKey, NULL) == hrOK)
  123. {
  124. GUID guid;
  125. ::CLSIDFromString(((LPTSTR) (LPCTSTR) strKey), &guid);
  126. if (aDynExtensions.IsInList(guid))
  127. m_aMenu.Add(guid);
  128. }
  129. }
  130. // toolbar extensions
  131. RegKey regkeyToolbarExt;
  132. lRes = regkeyToolbarExt.Open(regkeyExtensions, g_szToolbar);
  133. if (lRes == ERROR_SUCCESS)
  134. {
  135. // enumerate the ns dynamic extensions
  136. RegValueIterator iterToolbarExt;
  137. iterToolbarExt.Init(&regkeyToolbarExt);
  138. while (iterToolbarExt.Next(&strKey, NULL) == hrOK)
  139. {
  140. GUID guid;
  141. ::CLSIDFromString(((LPTSTR) (LPCTSTR) strKey), &guid);
  142. if (aDynExtensions.IsInList(guid))
  143. m_aToolbar.Add(guid);
  144. }
  145. }
  146. // PropPage extensions
  147. RegKey regkeyPSExt;
  148. lRes = regkeyPSExt.Open(regkeyExtensions, g_szPropertySheet);
  149. if (lRes == ERROR_SUCCESS)
  150. {
  151. // enumerate the ns dynamic extensions
  152. RegValueIterator iterPSExt;
  153. iterPSExt.Init(&regkeyPSExt);
  154. while (iterPSExt.Next(&strKey, NULL) == hrOK)
  155. {
  156. GUID guid;
  157. ::CLSIDFromString(((LPTSTR) (LPCTSTR) strKey), &guid);
  158. if (aDynExtensions.IsInList(guid))
  159. m_aPropSheet.Add(guid);
  160. }
  161. }
  162. // taskpad extensions
  163. RegKey regkeyTaskExt;
  164. lRes = regkeyTaskExt.Open(regkeyExtensions, g_szTask);
  165. if (lRes == ERROR_SUCCESS)
  166. {
  167. // enumerate the ns dynamic extensions
  168. RegValueIterator iterTaskExt;
  169. iterTaskExt.Init(&regkeyTaskExt);
  170. while (iterTaskExt.Next(&strKey, NULL) == hrOK)
  171. {
  172. GUID guid;
  173. ::CLSIDFromString(((LPTSTR) (LPCTSTR) strKey), &guid);
  174. if (aDynExtensions.IsInList(guid))
  175. m_aTask.Add(guid);
  176. }
  177. }
  178. m_bLoaded = TRUE;
  179. return hr;
  180. }
  181. HRESULT
  182. CDynamicExtensions::GetNamespaceExtensions(CGUIDArray & aGuids)
  183. {
  184. HRESULT hr = hrOK;
  185. aGuids.Copy(m_aNameSpace);
  186. return hr;
  187. }
  188. HRESULT
  189. CDynamicExtensions::BuildMMCObjectTypes(HGLOBAL * phGlobal)
  190. {
  191. HRESULT hr = hrOK;
  192. HGLOBAL hGlobal = NULL;
  193. SMMCDynamicExtensions * pDynExt = NULL;
  194. if (phGlobal)
  195. *phGlobal = NULL;
  196. COM_PROTECT_TRY
  197. {
  198. int i;
  199. CGUIDArray aOtherDynExt;
  200. // build our main list of other extension types
  201. // other means everything except namespace
  202. for (i = 0; i < m_aMenu.GetSize(); i++)
  203. {
  204. if (!aOtherDynExt.IsInList(m_aMenu[i]))
  205. aOtherDynExt.Add(m_aMenu[i]);
  206. }
  207. for (i = 0; i < m_aToolbar.GetSize(); i++)
  208. {
  209. if (!aOtherDynExt.IsInList(m_aToolbar[i]))
  210. aOtherDynExt.Add(m_aToolbar[i]);
  211. }
  212. for (i = 0; i < m_aPropSheet.GetSize(); i++)
  213. {
  214. if (!aOtherDynExt.IsInList(m_aPropSheet[i]))
  215. aOtherDynExt.Add(m_aPropSheet[i]);
  216. }
  217. for (i = 0; i < m_aTask.GetSize(); i++)
  218. {
  219. if (!aOtherDynExt.IsInList(m_aTask[i]))
  220. aOtherDynExt.Add(m_aTask[i]);
  221. }
  222. int nCount = (int)aOtherDynExt.GetSize();
  223. hGlobal = (SMMCDynamicExtensions *) ::GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE,
  224. sizeof(SMMCDynamicExtensions) + (nCount * sizeof(GUID)));
  225. pDynExt = reinterpret_cast<SMMCDynamicExtensions*>(::GlobalLock(hGlobal));
  226. if (!pDynExt)
  227. {
  228. hr = E_OUTOFMEMORY;
  229. goto Error;
  230. }
  231. ZeroMemory(pDynExt, sizeof(SMMCDynamicExtensions) + (nCount * sizeof(GUID)));
  232. // now build the real struct
  233. pDynExt->count = nCount;
  234. for (i = 0; i < nCount; i++)
  235. {
  236. pDynExt->guid[i] = aOtherDynExt[i];
  237. }
  238. ::GlobalUnlock(hGlobal);
  239. COM_PROTECT_ERROR_LABEL;
  240. }
  241. COM_PROTECT_CATCH
  242. if (SUCCEEDED(hr) && phGlobal)
  243. *phGlobal = hGlobal;
  244. return hr;
  245. }