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.

432 lines
11 KiB

  1. // compdata.cpp : Implementation of Ccompdata
  2. #include "stdafx.h"
  3. #include "BOMSnap.h"
  4. #include "rowitem.h"
  5. #include "scopenode.h"
  6. #include "compdata.h"
  7. #include "compont.h"
  8. #include "dataobj.h"
  9. #include "streamio.h"
  10. #include "adext.h"
  11. HWND g_hwndMain = NULL; // MMC main window
  12. DWORD g_dwFileVer; // Current console file version number
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CComponentData
  15. UINT CComponentData::m_cfDisplayName = RegisterClipboardFormat(TEXT("CCF_DISPLAY_NAME"));
  16. STDMETHODIMP CComponentData::Initialize(LPUNKNOWN pUnknown)
  17. {
  18. VALIDATE_POINTER( pUnknown );
  19. // Get Interfaces
  20. m_spConsole = pUnknown;
  21. if (m_spConsole == NULL) return E_NOINTERFACE;
  22. m_spNameSpace = pUnknown;
  23. if (m_spNameSpace == NULL) return E_NOINTERFACE;
  24. m_spStringTable = pUnknown;
  25. if (m_spStringTable == NULL) return E_NOINTERFACE;
  26. // Get main window for message boxes (see DisplayMessageBox in util.cpp)
  27. HRESULT hr = m_spConsole->GetMainWindow(&g_hwndMain);
  28. ASSERT(SUCCEEDED(hr));
  29. // Create the root scope node
  30. CComObject<CRootNode>* pnode;
  31. hr = CComObject<CRootNode>::CreateInstance(&pnode);
  32. RETURN_ON_FAILURE(hr);
  33. m_spRootNode = pnode;
  34. hr = m_spRootNode->Initialize(this);
  35. RETURN_ON_FAILURE(hr);
  36. // Initialize the common controls once
  37. static BOOL bInitComCtls = FALSE;
  38. if (!bInitComCtls)
  39. {
  40. INITCOMMONCONTROLSEX icex;
  41. icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  42. icex.dwICC = ICC_USEREX_CLASSES | ICC_LISTVIEW_CLASSES;
  43. bInitComCtls = InitCommonControlsEx(&icex);
  44. }
  45. // Init the active directory proxy class
  46. CActDirExtProxy::InitProxy();
  47. return S_OK;
  48. }
  49. STDMETHODIMP CComponentData::Destroy()
  50. {
  51. // Release all refs to mmc
  52. m_spConsole.Release();
  53. m_spNameSpace.Release();
  54. m_spStringTable.Release();
  55. return S_OK;
  56. }
  57. STDMETHODIMP CComponentData::CreateComponent(LPCOMPONENT* ppComponent)
  58. {
  59. VALIDATE_POINTER(ppComponent);
  60. CComObject<CComponent>* pComp;
  61. HRESULT hr = CComObject<CComponent>::CreateInstance(&pComp);
  62. RETURN_ON_FAILURE(hr);
  63. // Store back pointer to ComponentData
  64. pComp->SetComponentData(this);
  65. return pComp->QueryInterface(IID_IComponent, (void**)ppComponent);
  66. }
  67. STDMETHODIMP CComponentData::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  68. {
  69. // Special handling of prop change message for lpDataObject
  70. // We will get data object and lparam from PropChangeInfo passed as param
  71. // The lpDataObject from MMC is NULL
  72. if (event == MMCN_PROPERTY_CHANGE)
  73. {
  74. VALIDATE_POINTER( param );
  75. PropChangeInfo* pchg = reinterpret_cast<PropChangeInfo*>(param);
  76. lpDataObject = pchg->pDataObject;
  77. param = pchg->lNotifyParam;
  78. delete pchg;
  79. }
  80. // Query data object for private Back Office Manager interface
  81. IBOMObjectPtr spObj = lpDataObject;
  82. if (spObj == NULL)
  83. {
  84. ASSERT(0 && "Foreign data object");
  85. return E_INVALIDARG;
  86. }
  87. // Pass notification to object
  88. return spObj->Notify(m_spConsole, event, arg, param);
  89. }
  90. STDMETHODIMP CComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  91. {
  92. VALIDATE_POINTER( ppDataObject );
  93. if (type == CCT_SNAPIN_MANAGER)
  94. return GetUnknown()->QueryInterface(IID_IDataObject, (void**)ppDataObject);
  95. IDataObject* pDO = NULL;
  96. if (type == CCT_SCOPE)
  97. {
  98. CScopeNode* pNode = CookieToScopeNode(cookie);
  99. if (pNode)
  100. return pNode->QueryInterface(IID_IDataObject, (void**)ppDataObject);
  101. else
  102. return E_INVALIDARG;
  103. }
  104. return E_FAIL;
  105. }
  106. STDMETHODIMP CComponentData::GetDisplayInfo(SCOPEDATAITEM* pSDI)
  107. {
  108. VALIDATE_POINTER( pSDI );
  109. CScopeNode* pNode = CookieToScopeNode(pSDI->lParam);
  110. if (pNode == NULL) return E_INVALIDARG;
  111. return pNode->GetDisplayInfo(pSDI);
  112. }
  113. STDMETHODIMP CComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  114. {
  115. IUnknownPtr pUnkA= lpDataObjectA;
  116. IUnknownPtr pUnkB = lpDataObjectB;
  117. return (pUnkA == pUnkB) ? S_OK : S_FALSE;
  118. }
  119. HRESULT CComponentData::GetDataImpl(UINT cf, HGLOBAL* phGlobal)
  120. {
  121. VALIDATE_POINTER( phGlobal );
  122. HRESULT hr = DV_E_FORMATETC;
  123. tstring strName = StrLoadString(IDS_ROOTNODE);
  124. if (cf == m_cfDisplayName)
  125. {
  126. hr = DataToGlobal(phGlobal, strName.c_str(), (strName.length() + 1) * sizeof(WCHAR) );
  127. }
  128. return hr;
  129. }
  130. //--------------------------------------------------------------------------------
  131. // IPersistStreamInit Implementation
  132. //--------------------------------------------------------------------------------
  133. HRESULT CComponentData::GetClassID(CLSID *pClassID)
  134. {
  135. VALIDATE_POINTER(pClassID)
  136. memcpy(pClassID, &CLSID_BOMSnapIn, sizeof(CLSID));
  137. return S_OK;
  138. }
  139. HRESULT CComponentData::IsDirty()
  140. {
  141. return m_bDirty ? S_OK : S_FALSE;
  142. }
  143. HRESULT CComponentData::Load(IStream *pStream)
  144. {
  145. VALIDATE_POINTER(pStream)
  146. HRESULT hr = S_OK;
  147. try
  148. {
  149. // Read version code
  150. *pStream >> g_dwFileVer;
  151. // Should already have a default root node from the Initialize call
  152. ASSERT(m_spRootNode != NULL);
  153. if (m_spRootNode == NULL)
  154. return E_UNEXPECTED;
  155. // Now load the root node and the rest of the node tree
  156. hr = m_spRootNode->Load(*pStream);
  157. }
  158. catch (_com_error& err)
  159. {
  160. hr = err.Error();
  161. }
  162. // Don't keep a tree that failed to load
  163. if (FAILED(hr))
  164. m_spRootNode.Release();
  165. return hr;
  166. }
  167. HRESULT CComponentData::Save(IStream *pStream, BOOL fClearDirty)
  168. {
  169. VALIDATE_POINTER(pStream)
  170. // Can't save if haven't been loaded or initialized
  171. if (m_spRootNode == NULL)
  172. return E_FAIL;
  173. HRESULT hr = S_OK;
  174. try
  175. {
  176. // Write version code
  177. *pStream << SNAPIN_VERSION;
  178. // Write root node and rest of the node tree
  179. hr = m_spRootNode->Save(*pStream);
  180. }
  181. catch (_com_error& err)
  182. {
  183. hr = err.Error();
  184. }
  185. if (SUCCEEDED(hr) && fClearDirty)
  186. m_bDirty = FALSE;
  187. return hr;
  188. }
  189. HRESULT CComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  190. {
  191. return E_NOTIMPL;
  192. }
  193. HRESULT CComponentData::Notify(LPCONSOLE2 pCons, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  194. {
  195. return S_OK;
  196. }
  197. /******************************************************************************************
  198. * Menus and verbs
  199. ******************************************************************************************/
  200. HRESULT CComponentData::AddMenuItems( LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pCallback, long* plAllowed )
  201. {
  202. VALIDATE_POINTER( pCallback );
  203. VALIDATE_POINTER( plAllowed );
  204. IBOMObjectPtr spObj = pDataObject;
  205. if (spObj == NULL) return E_INVALIDARG;
  206. return spObj->AddMenuItems(pCallback, plAllowed);
  207. }
  208. HRESULT CComponentData::Command(long lCommand, LPDATAOBJECT pDataObject)
  209. {
  210. IBOMObjectPtr spObj = pDataObject;
  211. if (spObj == NULL) return E_INVALIDARG;
  212. return spObj->MenuCommand(m_spConsole, lCommand);
  213. }
  214. HRESULT CComponentData::AddMenuItems(LPCONTEXTMENUCALLBACK pCallback, long* plAllowed)
  215. {
  216. return S_OK;
  217. }
  218. HRESULT CComponentData::MenuCommand(LPCONSOLE2 pConsole, long lCommand)
  219. {
  220. return S_FALSE;
  221. }
  222. HRESULT CComponentData::SetToolButtons(LPTOOLBAR pToolbar)
  223. {
  224. return S_FALSE;
  225. }
  226. HRESULT CComponentData::SetVerbs(LPCONSOLEVERB pConsVerb)
  227. {
  228. return S_OK;
  229. }
  230. /*****************************************************************************************
  231. * Property Pages
  232. *****************************************************************************************/
  233. HRESULT CComponentData::QueryPagesFor(LPDATAOBJECT pDataObject)
  234. {
  235. IBOMObjectPtr spObj = pDataObject;
  236. if (spObj == NULL) return E_INVALIDARG;
  237. return spObj->QueryPagesFor();
  238. }
  239. HRESULT CComponentData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK pProvider, LONG_PTR handle, LPDATAOBJECT pDataObject)
  240. {
  241. VALIDATE_POINTER( pProvider );
  242. IBOMObjectPtr spObj = pDataObject;
  243. if (spObj == NULL) return E_INVALIDARG;
  244. return spObj->CreatePropertyPages(pProvider, handle);
  245. }
  246. HRESULT CComponentData::GetWatermarks(LPDATAOBJECT pDataObject, HBITMAP* phWatermark, HBITMAP* phHeader,
  247. HPALETTE* phPalette, BOOL* bStreach)
  248. {
  249. IBOMObjectPtr spObj = pDataObject;
  250. if (spObj == NULL) return E_INVALIDARG;
  251. return spObj->GetWatermarks(phWatermark, phHeader, phPalette, bStreach);
  252. }
  253. HRESULT CComponentData::QueryPagesFor()
  254. {
  255. return S_FALSE;
  256. }
  257. HRESULT CComponentData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK pProvider, LONG_PTR handle)
  258. {
  259. return S_FALSE;
  260. }
  261. HRESULT CComponentData::GetWatermarks(HBITMAP* phWatermark, HBITMAP* phHeader, HPALETTE* phPalette, BOOL* bStreach)
  262. {
  263. return S_FALSE;
  264. }
  265. //--------------------------------------------------------------------------------
  266. // ISnapinHelp2 Implementation
  267. //--------------------------------------------------------------------------------
  268. HRESULT CComponentData::GetHelpTopic(LPOLESTR* ppszHelpFile)
  269. {
  270. VALIDATE_POINTER(ppszHelpFile);
  271. *ppszHelpFile = NULL;
  272. tstring strTmp = _T("");
  273. tstring strHelpFile = _T("");
  274. // Build path to %systemroot%\help
  275. TCHAR szWindowsDir[MAX_PATH+1] = {0};
  276. UINT nSize = GetSystemWindowsDirectory( szWindowsDir, MAX_PATH );
  277. if( nSize == 0 || nSize > MAX_PATH )
  278. {
  279. return E_FAIL;
  280. }
  281. strTmp = StrLoadString(IDS_HELPFILE);
  282. if( strTmp.empty() )
  283. {
  284. return E_FAIL;
  285. }
  286. strHelpFile = szWindowsDir;
  287. strHelpFile += _T("\\Help\\");
  288. strHelpFile += strTmp;
  289. // Form file path in allocated buffer
  290. int nLen = strHelpFile.length() + 1;
  291. *ppszHelpFile = (LPOLESTR)CoTaskMemAlloc(nLen * sizeof(OLECHAR));
  292. if( *ppszHelpFile == NULL ) return E_OUTOFMEMORY;
  293. // Copy into allocated buffer
  294. ocscpy( *ppszHelpFile, T2OLE( (LPTSTR)strHelpFile.c_str() ) );
  295. return S_OK;
  296. }
  297. HRESULT CComponentData::GetLinkedTopics(LPOLESTR* ppszLinkedFiles)
  298. {
  299. VALIDATE_POINTER(ppszLinkedFiles);
  300. // no linked files
  301. *ppszLinkedFiles = NULL;
  302. return S_FALSE;
  303. }
  304. //-------------------------------------------------------------------------------------------
  305. // Class registration
  306. //-------------------------------------------------------------------------------------------
  307. HRESULT WINAPI CComponentData::UpdateRegistry(BOOL bRegister)
  308. {
  309. // Load snap-in root name to use as registered snap-in name
  310. tstring strSnapinName = StrLoadString(IDS_ROOTNODE);
  311. // Specify the substitution parameters for IRegistrar.
  312. _ATL_REGMAP_ENTRY rgEntries[] =
  313. {
  314. {TEXT("SNAPIN_NAME"), strSnapinName.c_str()},
  315. {NULL, NULL},
  316. };
  317. // Register the component data object
  318. HRESULT hr = _Module.UpdateRegistryFromResource(IDR_BOMSNAP, bRegister, rgEntries);
  319. return hr;
  320. }