1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS Device Manager
3c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory
4c2c66affSColin Finck * FILE: dll/win32/devmgr/devmgmt/ClassNode.cpp
5c2c66affSColin Finck * PURPOSE: Class object for
6c2c66affSColin Finck * COPYRIGHT: Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
7c2c66affSColin Finck *
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck #include "precomp.h"
11c2c66affSColin Finck #include "devmgmt.h"
12c2c66affSColin Finck #include "DeviceNode.h"
13c2c66affSColin Finck
14c2c66affSColin Finck
CDeviceNode(_In_opt_ DEVINST Device,_In_ PSP_CLASSIMAGELIST_DATA ImageListData)15c2c66affSColin Finck CDeviceNode::CDeviceNode(
16c2c66affSColin Finck _In_opt_ DEVINST Device,
17c2c66affSColin Finck _In_ PSP_CLASSIMAGELIST_DATA ImageListData
18c2c66affSColin Finck ) :
19c2c66affSColin Finck CNode(DeviceNode, ImageListData),
20c2c66affSColin Finck m_DevInst(Device),
21c2c66affSColin Finck m_hDevInfo(NULL),
22c2c66affSColin Finck m_Status(0),
23c2c66affSColin Finck m_ProblemNumber(0),
24c2c66affSColin Finck m_OverlayImage(0)
25c2c66affSColin Finck {
26c2c66affSColin Finck ZeroMemory(&m_DevinfoData, sizeof(SP_DEVINFO_DATA));
27c2c66affSColin Finck }
28c2c66affSColin Finck
CDeviceNode(_In_ const CDeviceNode & Node)29c2c66affSColin Finck CDeviceNode::CDeviceNode(
30c2c66affSColin Finck _In_ const CDeviceNode &Node
31c2c66affSColin Finck ) :
32c2c66affSColin Finck CNode(Node)
33c2c66affSColin Finck {
34c2c66affSColin Finck m_DevInst = Node.m_DevInst;
35c2c66affSColin Finck m_hDevInfo = Node.m_hDevInfo;
36c2c66affSColin Finck m_Status = Node.m_Status;
37c2c66affSColin Finck m_ProblemNumber = Node.m_ProblemNumber;
38c2c66affSColin Finck m_OverlayImage = Node.m_OverlayImage;
39c2c66affSColin Finck CopyMemory(&m_DevinfoData, &Node.m_DevinfoData, sizeof(SP_DEVINFO_DATA));
40c2c66affSColin Finck
41c2c66affSColin Finck size_t size = wcslen(Node.m_DeviceId) + 1;
42c2c66affSColin Finck m_DeviceId = new WCHAR[size];
43c2c66affSColin Finck StringCbCopyW(m_DeviceId, size * sizeof(WCHAR), Node.m_DeviceId);
44c2c66affSColin Finck }
45c2c66affSColin Finck
~CDeviceNode()46c2c66affSColin Finck CDeviceNode::~CDeviceNode()
47c2c66affSColin Finck {
48c2c66affSColin Finck Cleanup();
49c2c66affSColin Finck }
50c2c66affSColin Finck
51c2c66affSColin Finck bool
SetupNode()52c2c66affSColin Finck CDeviceNode::SetupNode()
53c2c66affSColin Finck {
54c2c66affSColin Finck WCHAR ClassGuidString[MAX_GUID_STRING_LEN];
55c2c66affSColin Finck ULONG ulLength;
56c2c66affSColin Finck CONFIGRET cr;
57c2c66affSColin Finck
58c2c66affSColin Finck // Get the length of the device id string
59c2c66affSColin Finck cr = CM_Get_Device_ID_Size(&ulLength, m_DevInst, 0);
60c2c66affSColin Finck if (cr == CR_SUCCESS)
61c2c66affSColin Finck {
62c2c66affSColin Finck // We alloc heap here because this will be stored in the lParam of the TV
63c2c66affSColin Finck m_DeviceId = new WCHAR[ulLength + 1];
64c2c66affSColin Finck
65c2c66affSColin Finck // Now get the actual device id
66c2c66affSColin Finck cr = CM_Get_Device_IDW(m_DevInst,
67c2c66affSColin Finck m_DeviceId,
68c2c66affSColin Finck ulLength + 1,
69c2c66affSColin Finck 0);
70c2c66affSColin Finck if (cr != CR_SUCCESS || wcscmp(m_DeviceId, L"HTREE\\ROOT\\0") == 0)
71c2c66affSColin Finck {
72c2c66affSColin Finck delete[] m_DeviceId;
73c2c66affSColin Finck m_DeviceId = NULL;
74c2c66affSColin Finck }
75c2c66affSColin Finck }
76c2c66affSColin Finck
77c2c66affSColin Finck // Make sure we got the string
78c2c66affSColin Finck if (m_DeviceId == NULL)
79c2c66affSColin Finck return false;
80c2c66affSColin Finck
81c2c66affSColin Finck // Build up a handle a and devinfodata struct
82c2c66affSColin Finck m_hDevInfo = SetupDiCreateDeviceInfoListExW(NULL,
83c2c66affSColin Finck NULL,
84c2c66affSColin Finck NULL,
85c2c66affSColin Finck NULL);
86c2c66affSColin Finck if (m_hDevInfo != INVALID_HANDLE_VALUE)
87c2c66affSColin Finck {
88c2c66affSColin Finck m_DevinfoData.cbSize = sizeof(SP_DEVINFO_DATA);
89c2c66affSColin Finck SetupDiOpenDeviceInfoW(m_hDevInfo,
90c2c66affSColin Finck m_DeviceId,
91c2c66affSColin Finck NULL,
92c2c66affSColin Finck 0,
93c2c66affSColin Finck &m_DevinfoData);
94c2c66affSColin Finck }
95c2c66affSColin Finck
96c2c66affSColin Finck // Check if the device has a problem
97c2c66affSColin Finck if (HasProblem())
98c2c66affSColin Finck {
99c2c66affSColin Finck if (IsDisabled())
100c2c66affSColin Finck {
101c2c66affSColin Finck m_OverlayImage = OverlayDisabled;
102c2c66affSColin Finck }
103c2c66affSColin Finck else
104c2c66affSColin Finck {
105c2c66affSColin Finck m_OverlayImage = OverlayProblem;
106c2c66affSColin Finck }
107c2c66affSColin Finck }
108c2c66affSColin Finck
109c2c66affSColin Finck // Get the class guid for this device
110c2c66affSColin Finck ulLength = MAX_GUID_STRING_LEN * sizeof(WCHAR);
111c2c66affSColin Finck cr = CM_Get_DevNode_Registry_PropertyW(m_DevInst,
112c2c66affSColin Finck CM_DRP_CLASSGUID,
113c2c66affSColin Finck NULL,
114c2c66affSColin Finck ClassGuidString,
115c2c66affSColin Finck &ulLength,
116c2c66affSColin Finck 0);
117c2c66affSColin Finck if (cr == CR_SUCCESS)
118c2c66affSColin Finck {
119c2c66affSColin Finck // Convert the string to a proper guid
120c2c66affSColin Finck CLSIDFromString(ClassGuidString, &m_ClassGuid);
121c2c66affSColin Finck }
122c2c66affSColin Finck else
123c2c66affSColin Finck {
124c2c66affSColin Finck // It's a device with no driver
125c2c66affSColin Finck m_ClassGuid = GUID_DEVCLASS_UNKNOWN;
126c2c66affSColin Finck }
127c2c66affSColin Finck
128c2c66affSColin Finck // Get the image for the class this device is in
129c2c66affSColin Finck SetupDiGetClassImageIndex(m_ImageListData,
130c2c66affSColin Finck &m_ClassGuid,
131c2c66affSColin Finck &m_ClassImage);
132c2c66affSColin Finck
133c2c66affSColin Finck // Get the description for the device
134*9c82d16bSSerge Gautherie ulLength = sizeof(m_DisplayName);
135c2c66affSColin Finck cr = CM_Get_DevNode_Registry_PropertyW(m_DevInst,
136c2c66affSColin Finck CM_DRP_FRIENDLYNAME,
137c2c66affSColin Finck NULL,
138c2c66affSColin Finck m_DisplayName,
139c2c66affSColin Finck &ulLength,
140c2c66affSColin Finck 0);
141c2c66affSColin Finck if (cr != CR_SUCCESS)
142c2c66affSColin Finck {
143*9c82d16bSSerge Gautherie ulLength = sizeof(m_DisplayName);
144c2c66affSColin Finck cr = CM_Get_DevNode_Registry_PropertyW(m_DevInst,
145c2c66affSColin Finck CM_DRP_DEVICEDESC,
146c2c66affSColin Finck NULL,
147c2c66affSColin Finck m_DisplayName,
148c2c66affSColin Finck &ulLength,
149c2c66affSColin Finck 0);
150c2c66affSColin Finck }
151c2c66affSColin Finck
152c2c66affSColin Finck if (cr != CR_SUCCESS)
153c2c66affSColin Finck {
154c2c66affSColin Finck CAtlStringW str;
155c2c66affSColin Finck if (str.LoadStringW(g_hThisInstance, IDS_UNKNOWNDEVICE))
156c2c66affSColin Finck StringCchCopyW(m_DisplayName, MAX_PATH, str.GetBuffer());
157c2c66affSColin Finck }
158c2c66affSColin Finck
159c2c66affSColin Finck return true;
160c2c66affSColin Finck }
161c2c66affSColin Finck
162c2c66affSColin Finck bool
HasProblem()163c2c66affSColin Finck CDeviceNode::HasProblem()
164c2c66affSColin Finck {
165c2c66affSColin Finck CONFIGRET cr;
166c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
167c2c66affSColin Finck &m_ProblemNumber,
168c2c66affSColin Finck m_DevInst,
169c2c66affSColin Finck 0,
170c2c66affSColin Finck NULL);
171c2c66affSColin Finck if (cr == CR_SUCCESS)
172c2c66affSColin Finck {
173c2c66affSColin Finck return ((m_Status & (DN_HAS_PROBLEM | DN_PRIVATE_PROBLEM)) != 0);
174c2c66affSColin Finck }
175c2c66affSColin Finck
176c2c66affSColin Finck return false;
177c2c66affSColin Finck }
178c2c66affSColin Finck
179c2c66affSColin Finck bool
IsHidden()180c2c66affSColin Finck CDeviceNode::IsHidden()
181c2c66affSColin Finck {
182c2c66affSColin Finck CONFIGRET cr;
183c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
184c2c66affSColin Finck &m_ProblemNumber,
185c2c66affSColin Finck m_DevInst,
186c2c66affSColin Finck 0,
187c2c66affSColin Finck NULL);
188c2c66affSColin Finck if (cr == CR_SUCCESS)
189c2c66affSColin Finck {
190c2c66affSColin Finck if (m_Status & DN_NO_SHOW_IN_DM)
191c2c66affSColin Finck return true;
192c2c66affSColin Finck }
193c2c66affSColin Finck
194c2c66affSColin Finck if (IsEqualGUID(*GetClassGuid(), GUID_DEVCLASS_LEGACYDRIVER) ||
195c2c66affSColin Finck IsEqualGUID(*GetClassGuid(), GUID_DEVCLASS_VOLUME))
196c2c66affSColin Finck return true;
197c2c66affSColin Finck
198c2c66affSColin Finck return false;
199c2c66affSColin Finck }
200c2c66affSColin Finck
201c2c66affSColin Finck bool
CanDisable()202c2c66affSColin Finck CDeviceNode::CanDisable()
203c2c66affSColin Finck {
204c2c66affSColin Finck CONFIGRET cr;
205c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
206c2c66affSColin Finck &m_ProblemNumber,
207c2c66affSColin Finck m_DevInst,
208c2c66affSColin Finck 0,
209c2c66affSColin Finck NULL);
210c2c66affSColin Finck if (cr == CR_SUCCESS)
211c2c66affSColin Finck {
212c2c66affSColin Finck return ((m_Status & DN_DISABLEABLE) != 0);
213c2c66affSColin Finck }
214c2c66affSColin Finck
215c2c66affSColin Finck return false;
216c2c66affSColin Finck }
217c2c66affSColin Finck
218c2c66affSColin Finck bool
IsDisabled()219c2c66affSColin Finck CDeviceNode::IsDisabled()
220c2c66affSColin Finck {
221c2c66affSColin Finck CONFIGRET cr;
222c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
223c2c66affSColin Finck &m_ProblemNumber,
224c2c66affSColin Finck m_DevInst,
225c2c66affSColin Finck 0,
226c2c66affSColin Finck NULL);
227c2c66affSColin Finck if (cr == CR_SUCCESS)
228c2c66affSColin Finck {
229c2c66affSColin Finck return ((m_ProblemNumber == CM_PROB_DISABLED) || (m_ProblemNumber == CM_PROB_HARDWARE_DISABLED));
230c2c66affSColin Finck }
231c2c66affSColin Finck
232c2c66affSColin Finck return false;
233c2c66affSColin Finck }
234c2c66affSColin Finck
235c2c66affSColin Finck bool
IsStarted()236c2c66affSColin Finck CDeviceNode::IsStarted()
237c2c66affSColin Finck {
238c2c66affSColin Finck CONFIGRET cr;
239c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
240c2c66affSColin Finck &m_ProblemNumber,
241c2c66affSColin Finck m_DevInst,
242c2c66affSColin Finck 0,
243c2c66affSColin Finck NULL);
244c2c66affSColin Finck if (cr == CR_SUCCESS)
245c2c66affSColin Finck {
246c2c66affSColin Finck return ((m_Status & DN_STARTED) != 0);
247c2c66affSColin Finck }
248c2c66affSColin Finck
249c2c66affSColin Finck return false;
250c2c66affSColin Finck }
251c2c66affSColin Finck
252c2c66affSColin Finck bool
IsInstalled()253c2c66affSColin Finck CDeviceNode::IsInstalled()
254c2c66affSColin Finck {
255c2c66affSColin Finck CONFIGRET cr;
256c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
257c2c66affSColin Finck &m_ProblemNumber,
258c2c66affSColin Finck m_DevInst,
259c2c66affSColin Finck 0,
260c2c66affSColin Finck NULL);
261c2c66affSColin Finck if (cr == CR_SUCCESS)
262c2c66affSColin Finck {
263c2c66affSColin Finck return ((m_Status & DN_HAS_PROBLEM) != 0 ||
264c2c66affSColin Finck (m_Status & (DN_DRIVER_LOADED | DN_STARTED)) != 0);
265c2c66affSColin Finck }
266c2c66affSColin Finck
267c2c66affSColin Finck return false;
268c2c66affSColin Finck }
269c2c66affSColin Finck
270c2c66affSColin Finck bool
CanUninstall()271c2c66affSColin Finck CDeviceNode::CanUninstall()
272c2c66affSColin Finck {
273c2c66affSColin Finck CONFIGRET cr;
274c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&m_Status,
275c2c66affSColin Finck &m_ProblemNumber,
276c2c66affSColin Finck m_DevInst,
277c2c66affSColin Finck 0,
278c2c66affSColin Finck NULL);
279c2c66affSColin Finck if (cr == CR_SUCCESS)
280c2c66affSColin Finck {
281c2c66affSColin Finck if ((m_Status & DN_ROOT_ENUMERATED) != 0 &&
282c2c66affSColin Finck (m_Status & DN_DISABLEABLE) == 0)
283c2c66affSColin Finck return false;
284c2c66affSColin Finck }
285c2c66affSColin Finck
286c2c66affSColin Finck return true;
287c2c66affSColin Finck }
288c2c66affSColin Finck
289c2c66affSColin Finck bool
EnableDevice(_In_ bool Enable,_Out_ bool & NeedsReboot)290c2c66affSColin Finck CDeviceNode::EnableDevice(
291c2c66affSColin Finck _In_ bool Enable,
292c2c66affSColin Finck _Out_ bool &NeedsReboot
293c2c66affSColin Finck )
294c2c66affSColin Finck {
295c2c66affSColin Finck bool Canceled = false;
296c2c66affSColin Finck
297c2c66affSColin Finck SetFlags(DI_NODI_DEFAULTACTION, 0);
298c2c66affSColin Finck
299c2c66affSColin Finck SP_PROPCHANGE_PARAMS pcp;
300c2c66affSColin Finck pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
301c2c66affSColin Finck pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
302c2c66affSColin Finck pcp.StateChange = (Enable ? DICS_ENABLE : DICS_DISABLE);
303c2c66affSColin Finck pcp.HwProfile = 0;
304c2c66affSColin Finck
305c2c66affSColin Finck // check both scopes to make sure we can make the change
306c2c66affSColin Finck for (int i = 0; i < 2; i++)
307c2c66affSColin Finck {
308c2c66affSColin Finck // Check globally first, then check config specific
309c2c66affSColin Finck pcp.Scope = (i == 0) ? DICS_FLAG_CONFIGGENERAL : DICS_FLAG_CONFIGSPECIFIC;
310c2c66affSColin Finck
311c2c66affSColin Finck if (SetupDiSetClassInstallParamsW(m_hDevInfo,
312c2c66affSColin Finck &m_DevinfoData,
313c2c66affSColin Finck &pcp.ClassInstallHeader,
314c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS)))
315c2c66affSColin Finck {
316c2c66affSColin Finck SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
317c2c66affSColin Finck m_hDevInfo,
318c2c66affSColin Finck &m_DevinfoData);
319c2c66affSColin Finck }
320c2c66affSColin Finck
321c2c66affSColin Finck if (GetLastError() == ERROR_CANCELLED)
322c2c66affSColin Finck {
323c2c66affSColin Finck Canceled = true;
324c2c66affSColin Finck break;
325c2c66affSColin Finck }
326c2c66affSColin Finck }
327c2c66affSColin Finck
328c2c66affSColin Finck if (Canceled == false)
329c2c66affSColin Finck {
330c2c66affSColin Finck pcp.Scope = DICS_FLAG_CONFIGSPECIFIC;
331c2c66affSColin Finck if (SetupDiSetClassInstallParamsW(m_hDevInfo,
332c2c66affSColin Finck &m_DevinfoData,
333c2c66affSColin Finck &pcp.ClassInstallHeader,
334c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS)))
335c2c66affSColin Finck {
336c2c66affSColin Finck SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
337c2c66affSColin Finck }
338c2c66affSColin Finck
339c2c66affSColin Finck
340c2c66affSColin Finck if (Enable)
341c2c66affSColin Finck {
342c2c66affSColin Finck // config specific enabling first, then global enabling.
343c2c66affSColin Finck // The global appears to be the one that starts the device
344c2c66affSColin Finck pcp.Scope = DICS_FLAG_GLOBAL;
345c2c66affSColin Finck if (SetupDiSetClassInstallParamsW(m_hDevInfo,
346c2c66affSColin Finck &m_DevinfoData,
347c2c66affSColin Finck &pcp.ClassInstallHeader,
348c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS)))
349c2c66affSColin Finck {
350c2c66affSColin Finck SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
351c2c66affSColin Finck }
352c2c66affSColin Finck }
353c2c66affSColin Finck
354c2c66affSColin Finck SetFlags(DI_PROPERTIES_CHANGE, 0);
355c2c66affSColin Finck
356c2c66affSColin Finck NeedsReboot = ((GetFlags() & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0);
357c2c66affSColin Finck }
358c2c66affSColin Finck
359c2c66affSColin Finck RemoveFlags(DI_NODI_DEFAULTACTION, 0);
360c2c66affSColin Finck
361c2c66affSColin Finck return true;
362c2c66affSColin Finck }
363c2c66affSColin Finck
364c2c66affSColin Finck bool
UninstallDevice()365c2c66affSColin Finck CDeviceNode::UninstallDevice()
366c2c66affSColin Finck {
367c2c66affSColin Finck if (CanUninstall() == false)
368c2c66affSColin Finck return false;
369c2c66affSColin Finck
370c2c66affSColin Finck SP_REMOVEDEVICE_PARAMS RemoveDevParams;
371c2c66affSColin Finck RemoveDevParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
372c2c66affSColin Finck RemoveDevParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
373c2c66affSColin Finck RemoveDevParams.Scope = DI_REMOVEDEVICE_GLOBAL;
374c2c66affSColin Finck RemoveDevParams.HwProfile = 0;
375c2c66affSColin Finck
376c2c66affSColin Finck //
377c2c66affSColin Finck // We probably need to walk all the siblings of this
378c2c66affSColin Finck // device and ask if they're happy with the uninstall
379c2c66affSColin Finck //
380c2c66affSColin Finck
381c2c66affSColin Finck // Remove it
382c2c66affSColin Finck SetupDiSetClassInstallParamsW(m_hDevInfo,
383c2c66affSColin Finck &m_DevinfoData,
384c2c66affSColin Finck &RemoveDevParams.ClassInstallHeader,
385c2c66affSColin Finck sizeof(SP_REMOVEDEVICE_PARAMS));
386c2c66affSColin Finck SetupDiCallClassInstaller(DIF_REMOVE, m_hDevInfo, &m_DevinfoData);
387c2c66affSColin Finck
388c2c66affSColin Finck // Clear the install params
389c2c66affSColin Finck SetupDiSetClassInstallParamsW(m_hDevInfo,
390c2c66affSColin Finck &m_DevinfoData,
391c2c66affSColin Finck NULL,
392c2c66affSColin Finck 0);
393c2c66affSColin Finck
394c2c66affSColin Finck return true;
395c2c66affSColin Finck }
396c2c66affSColin Finck
397c2c66affSColin Finck /* PRIVATE METHODS ******************************************************/
398c2c66affSColin Finck
399c2c66affSColin Finck void
Cleanup()400c2c66affSColin Finck CDeviceNode::Cleanup()
401c2c66affSColin Finck {
402c2c66affSColin Finck if (m_DeviceId)
403c2c66affSColin Finck {
404c2c66affSColin Finck delete[] m_DeviceId;
405c2c66affSColin Finck m_DeviceId = NULL;
406c2c66affSColin Finck }
407c2c66affSColin Finck if (m_hDevInfo)
408c2c66affSColin Finck {
409c2c66affSColin Finck SetupDiDestroyDeviceInfoList(m_hDevInfo);
410c2c66affSColin Finck m_hDevInfo = NULL;
411c2c66affSColin Finck }
412c2c66affSColin Finck }
413c2c66affSColin Finck
414c2c66affSColin Finck DWORD
GetFlags()415c2c66affSColin Finck CDeviceNode::GetFlags()
416c2c66affSColin Finck {
417c2c66affSColin Finck SP_DEVINSTALL_PARAMS DevInstallParams;
418c2c66affSColin Finck DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
419c2c66affSColin Finck if (SetupDiGetDeviceInstallParamsW(m_hDevInfo,
420c2c66affSColin Finck &m_DevinfoData,
421c2c66affSColin Finck &DevInstallParams))
422c2c66affSColin Finck {
423c2c66affSColin Finck return DevInstallParams.Flags;
424c2c66affSColin Finck }
425c2c66affSColin Finck return 0;
426c2c66affSColin Finck }
427c2c66affSColin Finck
428c2c66affSColin Finck bool
SetFlags(_In_ DWORD Flags,_In_ DWORD FlagsEx)429c2c66affSColin Finck CDeviceNode::SetFlags(
430c2c66affSColin Finck _In_ DWORD Flags,
431c2c66affSColin Finck _In_ DWORD FlagsEx
432c2c66affSColin Finck )
433c2c66affSColin Finck {
434c2c66affSColin Finck SP_DEVINSTALL_PARAMS DevInstallParams;
435c2c66affSColin Finck DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
436c2c66affSColin Finck if (SetupDiGetDeviceInstallParamsW(m_hDevInfo,
437c2c66affSColin Finck &m_DevinfoData,
438c2c66affSColin Finck &DevInstallParams))
439c2c66affSColin Finck {
440c2c66affSColin Finck DevInstallParams.Flags |= Flags;
441c2c66affSColin Finck DevInstallParams.FlagsEx |= FlagsEx;
442c2c66affSColin Finck return (SetupDiSetDeviceInstallParamsW(m_hDevInfo,
443c2c66affSColin Finck &m_DevinfoData,
444c2c66affSColin Finck &DevInstallParams) != 0);
445c2c66affSColin Finck }
446c2c66affSColin Finck return false;
447c2c66affSColin Finck }
448c2c66affSColin Finck
449c2c66affSColin Finck bool
RemoveFlags(_In_ DWORD Flags,_In_ DWORD FlagsEx)450c2c66affSColin Finck CDeviceNode::RemoveFlags(
451c2c66affSColin Finck _In_ DWORD Flags,
452c2c66affSColin Finck _In_ DWORD FlagsEx
453c2c66affSColin Finck )
454c2c66affSColin Finck {
455c2c66affSColin Finck SP_DEVINSTALL_PARAMS DevInstallParams;
456c2c66affSColin Finck DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
457c2c66affSColin Finck if (SetupDiGetDeviceInstallParamsW(m_hDevInfo,
458c2c66affSColin Finck &m_DevinfoData,
459c2c66affSColin Finck &DevInstallParams))
460c2c66affSColin Finck {
461c2c66affSColin Finck DevInstallParams.Flags &= ~Flags;
462c2c66affSColin Finck DevInstallParams.FlagsEx &= ~FlagsEx;
463c2c66affSColin Finck return (SetupDiSetDeviceInstallParamsW(m_hDevInfo,
464c2c66affSColin Finck &m_DevinfoData,
465c2c66affSColin Finck &DevInstallParams) != 0);
466c2c66affSColin Finck }
467c2c66affSColin Finck return false;
468c2c66affSColin Finck }
469