ReactOS 0.4.17-dev-1190-g4c812f4
CSnapin.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Management Console
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Retrieve / store information about a snapin
5 * COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
6 * Copyright 2026 Eric Kohl (eric.kohl@reactos.org)
7 */
8
9#include "precomp.h"
10
11// https://web.archive.org/web/20010614160959/msdn.microsoft.com/library/psdk/mmc/mmc12apx02_8jc5.htm
12// https://msdn.microsoft.com/en-us/library/aa814846(v=vs.85).aspx
13
14
15// https://msdn.microsoft.com/en-us/library/aa815510(v=vs.85).aspx
16// MMC initializes a snap-in by calling the Initialize method of the IComponentData object.
17// During initialization, IComponentData should query the console for its IConsoleNamespace and IConsole interfaces using
18// the console's IUnknown interface pointer that is passed into the call to Initialize.
19// The snap-in should then cache the returned pointers and use them for calling IConsoleNamespace and IConsole interface methods.
20
21
23 :m_CacheEntry(CacheEntry)
24{
25 m_NodeId = NodeId;
26 if (displayName)
28 else
30}
31
33{
35}
36
37const CAtlString& CSnapin::Name() const { return m_CacheEntry->Name(); }
40const CAtlString& CSnapin::Version() const { return m_CacheEntry->Version(); }
42
44{
45 m_DisplayName = pszName;
46}
47
48UINT
50{
51 return m_NodeId;
52}
53
55{
56 return m_CacheEntry;
57}
58
59void
61{
62 CSnapin *SubNode;
63 POSITION pos = m_SubNodes.GetHeadPosition();
64 while (pos != NULL)
65 {
66 SubNode = (CSnapin*)m_SubNodes.GetNext(pos);
67 if (SubNode)
68 delete SubNode;
69 }
70 m_SubNodes.RemoveAll();
71}
72
73void
75{
76#if 0
77 CComPtr<IComponentData> spComponentData;
78 HRESULT hr = CoCreateInstance(m_Guid, NULL, CLSCTX_INPROC, IID_PPV_ARG(IComponentData, &spComponentData));
79
80 if (SUCCEEDED(hr))
81 {
82 //CComPtr<IExtendPropertySheet> spPropertySheet;
83 }
84#endif
85}
86
87void
89{
90#if 0
91 CComPtr<IComponentData> spComponentData;
92 HRESULT hr = CoCreateInstance(m_Guid, NULL, CLSCTX_INPROC, IID_PPV_ARG(IComponentData, &spComponentData));
93
94 if (SUCCEEDED(hr))
95 {
96 hr = spComponentData->Initialize(console);
97 // CComponentData::CreatePropertyPages(
98 if (SUCCEEDED(hr))
99 {
100 SCOPEDATAITEM item = { 0 };
101 item.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
102
103 hr = spComponentData->GetDisplayInfo(&item);
104
105 printf("%S\n", item.displayname);
106
107
108 CComPtr<IDataObject> spDataObject;
109
110 hr = spComponentData->QueryDataObject(NULL, CCT_SCOPE, &spDataObject);
111
112 if (SUCCEEDED(hr))
113 {
114 //spDataObject->
115 }
116 }
117 }
118#endif
119}
120
121VOID
123{
124 IXMLDOMElement *pNodeElement = NULL;
125 IXMLDOMElement *pNodesElement = NULL;
126 IXMLDOMElement *pStringElement = NULL;
127 IXMLDOMElement *pBitmapsElement = NULL;
128 IXMLDOMElement *pComponentDatasElement = NULL;
129 IXMLDOMElement *pComponentDataElement = NULL;
130 IXMLDOMElement *pComponentsElement = NULL;
132 CSnapin *SubNode;
133 WCHAR szBuffer[32];
134 HRESULT hr = S_OK;
135
136 /* <Node ID="3" ImageIdx="0" CLSID="{C96401CC-0E17-11D3-885B-00C04F72C717}" Preload="true"> */
137 CHK_HR(mscFile->CreateAndAddElementNode(L"Node", pParentNode, &pNodeElement));
138 _swprintf(szBuffer, L"%u", m_NodeId);
139 CHK_HR(mscFile->CreateAndAddAttributeNode(L"ID", szBuffer, pNodeElement));
140 CHK_HR(mscFile->CreateAndAddAttributeNode(L"ImageIdx", L"0", pNodeElement)); /* FIXME */
141 CHK_HR(mscFile->CreateAndAddAttributeNode(L"CLSID", CacheEntry()->GuidString().GetString(), pNodeElement));
142 CHK_HR(mscFile->CreateAndAddAttributeNode(L"Preload", L"true", pNodeElement)); /* FIXME */
143
144 /* <Nodes> */
145 CHK_HR(mscFile->CreateAndAddElementNode(L"Nodes", pNodeElement, &pNodesElement));
146 pos = m_SubNodes.GetHeadPosition();
147 while (pos != NULL)
148 {
149 SubNode = (CSnapin*)m_SubNodes.GetNext(pos);
150 if (SubNode)
151 SubNode->SaveNode(mscFile, pNodesElement);
152 }
153 SAFE_RELEASE(pNodesElement); /* </Nodes> */
154
155 /* <String Name="Name" ID="2"/> */
156 CHK_HR(mscFile->CreateAndAddElementNode(L"String", pNodeElement, &pStringElement));
157 CHK_HR(mscFile->CreateAndAddAttributeNode(L"Name", m_DisplayName.GetString(), pStringElement)); /* FIXME */
158 SAFE_RELEASE(pStringElement); /* </String> */
159
160 /* <Bitmaps> */
161 CHK_HR(mscFile->CreateAndAddElementNode(L"Bitmaps", pNodeElement, &pBitmapsElement));
162/*
163 <BinaryData Name="Small" BinaryRefIndex="3"/>
164 <BinaryData Name="Large" BinaryRefIndex="4"/>
165*/
166 SAFE_RELEASE(pBitmapsElement); /* </Bitmaps> */
167
168 /* <ComponentDatas> */
169 CHK_HR(mscFile->CreateAndAddElementNode(L"ComponentDatas", pNodeElement, &pComponentDatasElement));
170 /* <ComponentData> */
171 CHK_HR(mscFile->CreateAndAddElementNode(L"ComponentData", pComponentDatasElement, &pComponentDataElement));
172/*
173 <GUID Name="Snapin">{C96401CC-0E17-11D3-885B-00C04F72C717}</GUID>
174 <Stream BinaryRefIndex="5"/>
175*/
176 SAFE_RELEASE(pComponentDataElement); /* </ComponentData> */
177 SAFE_RELEASE(pComponentDatasElement); /* </ComponentDatas> */
178
179 /* <Components /> */
180 CHK_HR(mscFile->CreateAndAddElementNode(L"Components", pNodeElement, &pComponentsElement));
181 SAFE_RELEASE(pComponentsElement); /* </Components> */
182
183CleanUp:
184 SAFE_RELEASE(pNodeElement); /* </Node> */
185}
186
188CSnapin::ParseSnapin(CMainWnd *pMainWnd, MscFile *mscFile, IXMLDOMElement *pSnapinNode, CSnapin **ppSnapin)
189{
190 VARIANT SnapinID, SnapinCLSID, SnapinDisplayName;
191 IXMLDOMElement *pStringElement = NULL;
192 IXMLDOMElement *pNodesElement = NULL;
193 IXMLDOMNodeList *pChildList = NULL;
194 PWSTR pwstr;
195 CSnapinCacheEntry *pCacheEntry = NULL;
196 CSnapin *pSnapin = NULL;
197 UINT uSnapinId;
198 HRESULT hr = S_OK;
199
200 VariantInit(&SnapinID);
201 VariantInit(&SnapinCLSID);
202 VariantInit(&SnapinDisplayName);
203
204 /* Read the ID attribute */
205 hr = mscFile->GetAttribute(pSnapinNode, (LPWSTR)L"ID", &SnapinID);
206 if (hr != S_OK)
207 goto done;
208
209 /* Read the CLSID attribute */
210 hr = mscFile->GetAttribute(pSnapinNode, (LPWSTR)L"CLSID", &SnapinCLSID);
211 if (hr != S_OK)
212 goto done;
213
214 /* FIXME: Read the ImageIdx attribute */
215 /* FIXME: Read the Preload attribute */
216
217 /* Open the String Element */
218 hr = mscFile->GetElement(pSnapinNode, (LPWSTR)L"String", &pStringElement);
219 if (hr != S_OK)
220 goto done;
221
222 /* Read the Name attribute */
223 hr = mscFile->GetAttribute(pStringElement, (LPWSTR)L"Name", &SnapinDisplayName);
224 if (hr != S_OK)
225 goto done;
226
227 /* FIXME: Use a string cache and the ID attribute instead of Name later */
228
229 /* Create the Snap-in */
230 pCacheEntry = pMainWnd->GetSnapinCacheEntryByGuid(V_BSTR(&SnapinCLSID));
231 if (pCacheEntry == NULL)
232 {
233 hr = E_FAIL;
234 goto done;
235 }
236
237 uSnapinId = (UINT)wcstoul(V_BSTR(&SnapinID), &pwstr, 10);
238 pMainWnd->UpdateNextNodeId(uSnapinId);
239
240 pSnapin = new CSnapin(pCacheEntry,
241 uSnapinId,
242 V_BSTR(&SnapinDisplayName));
243 if (pSnapin == NULL)
244 {
245 hr = E_FAIL;
246 goto done;
247 }
248
249 /* Add the Snap-in to the temporary node map */
250 pMainWnd->m_TempNodeMap->Add(uSnapinId, pSnapin);
251
252 /* FIXME: Read the Bitmaps element */
253 /* FIXME: Read the ComponentDatas element */
254 /* FIXME: Read the Component element */
255
256 /* Get the Nodes element */
257 hr = mscFile->GetElement(pSnapinNode, (LPWSTR)L"Nodes", &pNodesElement);
258 if (hr != S_OK)
259 goto done;
260
261 hr = pNodesElement->get_childNodes(&pChildList);
262 if (FAILED(hr))
263 goto done;
264
265done:
266 if (pStringElement)
267 pStringElement->Release();
268
269 VariantInit(&SnapinDisplayName);
270 VariantInit(&SnapinCLSID);
271 VariantInit(&SnapinID);
272
273 /* Parse Nodes Element and create Sub-Snapins */
274 if (pChildList)
275 {
276 IXMLDOMNode *nextItem;
278 BSTR NodeName = NULL;
279
280 for (;;)
281 {
282 hr = pChildList->nextNode(&nextItem);
283 if (hr == S_FALSE)
284 {
285 hr = S_OK;
286 break;
287 }
288
289 hr = nextItem->get_nodeType(&NodeType);
290 if (hr == S_OK)
291 {
292 if (NodeType == NODE_ELEMENT)
293 {
294 NodeName = NULL;
295 hr = nextItem->get_baseName(&NodeName);
296 if (hr == S_OK)
297 {
298 if (_wcsicmp(NodeName, L"Node") == 0)
299 {
300 CSnapin *pSubSnapin;
301 hr = ParseSnapin(pMainWnd, mscFile, (IXMLDOMElement *)nextItem, &pSubSnapin);
302 if (hr == S_OK)
303 {
304 pSnapin->m_SubNodes.AddTail(pSubSnapin);
305 }
306 }
307 SysFreeString(NodeName);
308 NodeName = NULL;
309 }
310 }
311 }
312
313 nextItem->Release();
314 }
315
316 pChildList->Release();
317
318 if (NodeName)
319 SysFreeString(NodeName);
320 }
321
322 if (pNodesElement)
323 pNodesElement->Release();
324
325 *ppSnapin = pSnapin;
326
327 return hr;
328}
#define IID_PPV_ARG(Itype, ppType)
static HRESULT GetString(ASSOCSTR Str, UINT Flags, LPCWSTR pszAssoc, LPCWSTR pszExtra, PWSTR Out, HKEY hProgId=NULL)
NodeType
Definition: Node.h:6
PXSTR GetString() noexcept
Definition: atlsimpstr.h:367
CSimpleMap< UINT, CSnapin * > * m_TempNodeMap
Definition: CMainWnd.h:59
VOID UpdateNextNodeId(UINT NodeId)
Definition: CMainWnd.cpp:701
CSnapinCacheEntry * GetSnapinCacheEntryByGuid(PWSTR pszGuid)
Definition: CMainWnd.cpp:650
const CAtlString & Description() const
const CAtlString & Version() const
const CAtlString & Provider() const
const CAtlString & Name() const
void OnAccept(IConsole *console)
Definition: CSnapin.cpp:88
CSnapin(CSnapinCacheEntry *CacheEntry, UINT NodeId, PWSTR displayName=NULL)
Definition: CSnapin.cpp:22
~CSnapin()
Definition: CSnapin.cpp:32
UINT m_NodeId
Definition: CSnapin.h:26
void OnAdd(IConsole *console)
Definition: CSnapin.cpp:74
CAtlString m_DisplayName
Definition: CSnapin.h:28
CSnapinCacheEntry * CacheEntry()
Definition: CSnapin.cpp:54
const CAtlString & Name() const
Definition: CSnapin.cpp:37
const CAtlString & Provider() const
Definition: CSnapin.cpp:38
const CAtlString & DisplayName() const
Definition: CSnapin.cpp:41
CSnapinCacheEntry * m_CacheEntry
Definition: CSnapin.h:27
VOID SaveNode(MscFile *mscFile, IXMLDOMElement *pParentNode)
Definition: CSnapin.cpp:122
void RemoveAllSubnodes()
Definition: CSnapin.cpp:60
const CAtlString & Description() const
Definition: CSnapin.cpp:39
static HRESULT ParseSnapin(CMainWnd *pMainWnd, MscFile *mscFile, IXMLDOMElement *pSnapinNode, CSnapin **ppSnapin)
Definition: CSnapin.cpp:188
CAtlList< CSnapin * > m_SubNodes
Definition: CSnapin.h:46
UINT GetNodeId()
Definition: CSnapin.cpp:49
const CAtlString & Version() const
Definition: CSnapin.cpp:40
void SetDisplayName(LPWSTR pszName)
Definition: CSnapin.cpp:43
HRESULT GetElement(IXMLDOMElement *pParentElement, LPWSTR pszElementName, IXMLDOMElement **ppElement)
Definition: mscfile.cpp:509
HRESULT GetAttribute(IXMLDOMElement *pElement, LPWSTR pszAttributeName, VARIANT *pAttributeValue)
Definition: mscfile.cpp:484
HRESULT CreateAndAddAttributeNode(PCWSTR wszName, PCWSTR wszValue, IXMLDOMElement *pParent)
Definition: mscfile.cpp:137
HRESULT CreateAndAddElementNode(PCWSTR wszName, IXMLDOMNode *pParent, IXMLDOMElement **ppElement=NULL)
Definition: mscfile.cpp:204
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
OLECHAR * BSTR
Definition: compat.h:2293
_ACRTIMP __msvcrt_ulong __cdecl wcstoul(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2917
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
#define L(x)
Definition: resources.c:13
#define NodeType(P)
Definition: nodetype.h:51
#define printf
Definition: freeldr.h:103
unsigned int UINT
Definition: sysinfo.c:13
ULONG Release()
HRESULT nextNode([retval, out] IXMLDOMNode **outNode)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
@ CCT_SCOPE
Definition: mmc.idl:88
static PWSTR GuidString
Definition: apphelp.c:93
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
#define SAFE_RELEASE(p)
Definition: mscfile.h:15
#define CHK_HR(stmt)
Definition: mscfile.h:9
enum tagDOMNodeType DOMNodeType
@ NODE_ELEMENT
Definition: msxml6.idl:113
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
#define V_BSTR(A)
Definition: oleauto.h:226
short WCHAR
Definition: pedump.c:58
#define UINT
Definition: utils.c:29
char displayName[]
Definition: tftpd.cpp:35
uint16_t * PWSTR
Definition: typedefs.h:56
uint16_t * LPWSTR
Definition: typedefs.h:56
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:547
#define S_FALSE
Definition: winerror.h:3451