ReactOS  0.4.14-dev-55-g2da92ac
DeviceNode.cpp
Go to the documentation of this file.
1 /*
2 * PROJECT: ReactOS Device Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/devmgr/devmgmt/ClassNode.cpp
5 * PURPOSE: Class object for
6 * COPYRIGHT: Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9 
10 #include "precomp.h"
11 #include "devmgmt.h"
12 #include "DeviceNode.h"
13 
14 
18  ) :
20  m_DevInst(Device),
21  m_hDevInfo(NULL),
22  m_Status(0),
23  m_ProblemNumber(0),
24  m_OverlayImage(0)
25 {
27 }
28 
30  _In_ const CDeviceNode &Node
31  ) :
32  CNode(Node)
33 {
34  m_DevInst = Node.m_DevInst;
35  m_hDevInfo = Node.m_hDevInfo;
36  m_Status = Node.m_Status;
37  m_ProblemNumber = Node.m_ProblemNumber;
38  m_OverlayImage = Node.m_OverlayImage;
39  CopyMemory(&m_DevinfoData, &Node.m_DevinfoData, sizeof(SP_DEVINFO_DATA));
40 
41  size_t size = wcslen(Node.m_DeviceId) + 1;
42  m_DeviceId = new WCHAR[size];
43  StringCbCopyW(m_DeviceId, size * sizeof(WCHAR), Node.m_DeviceId);
44 }
45 
47 {
48  Cleanup();
49 }
50 
51 bool
53 {
54  WCHAR ClassGuidString[MAX_GUID_STRING_LEN];
55  ULONG ulLength;
56  CONFIGRET cr;
57 
58  // Get the length of the device id string
59  cr = CM_Get_Device_ID_Size(&ulLength, m_DevInst, 0);
60  if (cr == CR_SUCCESS)
61  {
62  // We alloc heap here because this will be stored in the lParam of the TV
63  m_DeviceId = new WCHAR[ulLength + 1];
64 
65  // Now get the actual device id
67  m_DeviceId,
68  ulLength + 1,
69  0);
70  if (cr != CR_SUCCESS || wcscmp(m_DeviceId, L"HTREE\\ROOT\\0") == 0)
71  {
72  delete[] m_DeviceId;
73  m_DeviceId = NULL;
74  }
75  }
76 
77  // Make sure we got the string
78  if (m_DeviceId == NULL)
79  return false;
80 
81  // Build up a handle a and devinfodata struct
83  NULL,
84  NULL,
85  NULL);
87  {
90  m_DeviceId,
91  NULL,
92  0,
93  &m_DevinfoData);
94  }
95 
96  // Check if the device has a problem
97  if (HasProblem())
98  {
99  if (IsDisabled())
100  {
102  }
103  else
104  {
106  }
107  }
108 
109  // Get the class guid for this device
110  ulLength = MAX_GUID_STRING_LEN * sizeof(WCHAR);
113  NULL,
114  ClassGuidString,
115  &ulLength,
116  0);
117  if (cr == CR_SUCCESS)
118  {
119  // Convert the string to a proper guid
120  CLSIDFromString(ClassGuidString, &m_ClassGuid);
121  }
122  else
123  {
124  // It's a device with no driver
125  m_ClassGuid = GUID_DEVCLASS_UNKNOWN;
126  }
127 
128  // Get the image for the class this device is in
130  &m_ClassGuid,
131  &m_ClassImage);
132 
133  // Get the description for the device
134  ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
137  NULL,
139  &ulLength,
140  0);
141  if (cr != CR_SUCCESS)
142  {
143  ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
146  NULL,
148  &ulLength,
149  0);
150  }
151 
152  if (cr != CR_SUCCESS)
153  {
155  if (str.LoadStringW(g_hThisInstance, IDS_UNKNOWNDEVICE))
156  StringCchCopyW(m_DisplayName, MAX_PATH, str.GetBuffer());
157  }
158 
159  return true;
160 }
161 
162 bool
164 {
165  CONFIGRET cr;
168  m_DevInst,
169  0,
170  NULL);
171  if (cr == CR_SUCCESS)
172  {
173  return ((m_Status & (DN_HAS_PROBLEM | DN_PRIVATE_PROBLEM)) != 0);
174  }
175 
176  return false;
177 }
178 
179 bool
181 {
182  CONFIGRET cr;
185  m_DevInst,
186  0,
187  NULL);
188  if (cr == CR_SUCCESS)
189  {
191  return true;
192  }
193 
194  if (IsEqualGUID(*GetClassGuid(), GUID_DEVCLASS_LEGACYDRIVER) ||
195  IsEqualGUID(*GetClassGuid(), GUID_DEVCLASS_VOLUME))
196  return true;
197 
198  return false;
199 }
200 
201 bool
203 {
204  CONFIGRET cr;
207  m_DevInst,
208  0,
209  NULL);
210  if (cr == CR_SUCCESS)
211  {
212  return ((m_Status & DN_DISABLEABLE) != 0);
213  }
214 
215  return false;
216 }
217 
218 bool
220 {
221  CONFIGRET cr;
224  m_DevInst,
225  0,
226  NULL);
227  if (cr == CR_SUCCESS)
228  {
230  }
231 
232  return false;
233 }
234 
235 bool
237 {
238  CONFIGRET cr;
241  m_DevInst,
242  0,
243  NULL);
244  if (cr == CR_SUCCESS)
245  {
246  return ((m_Status & DN_STARTED) != 0);
247  }
248 
249  return false;
250 }
251 
252 bool
254 {
255  CONFIGRET cr;
258  m_DevInst,
259  0,
260  NULL);
261  if (cr == CR_SUCCESS)
262  {
263  return ((m_Status & DN_HAS_PROBLEM) != 0 ||
264  (m_Status & (DN_DRIVER_LOADED | DN_STARTED)) != 0);
265  }
266 
267  return false;
268 }
269 
270 bool
272 {
273  CONFIGRET cr;
276  m_DevInst,
277  0,
278  NULL);
279  if (cr == CR_SUCCESS)
280  {
281  if ((m_Status & DN_ROOT_ENUMERATED) != 0 &&
282  (m_Status & DN_DISABLEABLE) == 0)
283  return false;
284  }
285 
286  return true;
287 }
288 
289 bool
291  _In_ bool Enable,
292  _Out_ bool &NeedsReboot
293  )
294 {
295  bool Canceled = false;
296 
298 
303  pcp.HwProfile = 0;
304 
305  // check both scopes to make sure we can make the change
306  for (int i = 0; i < 2; i++)
307  {
308  // Check globally first, then check config specific
310 
312  &m_DevinfoData,
313  &pcp.ClassInstallHeader,
314  sizeof(SP_PROPCHANGE_PARAMS)))
315  {
317  m_hDevInfo,
318  &m_DevinfoData);
319  }
320 
321  if (GetLastError() == ERROR_CANCELLED)
322  {
323  Canceled = true;
324  break;
325  }
326  }
327 
328  if (Canceled == false)
329  {
332  &m_DevinfoData,
333  &pcp.ClassInstallHeader,
334  sizeof(SP_PROPCHANGE_PARAMS)))
335  {
337  }
338 
339 
340  if (Enable)
341  {
342  // config specific enabling first, then global enabling.
343  // The global appears to be the one that starts the device
344  pcp.Scope = DICS_FLAG_GLOBAL;
346  &m_DevinfoData,
347  &pcp.ClassInstallHeader,
348  sizeof(SP_PROPCHANGE_PARAMS)))
349  {
351  }
352  }
353 
355 
356  NeedsReboot = ((GetFlags() & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0);
357  }
358 
360 
361  return true;
362 }
363 
364 bool
366 {
367  if (CanUninstall() == false)
368  return false;
369 
370  SP_REMOVEDEVICE_PARAMS RemoveDevParams;
371  RemoveDevParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
373  RemoveDevParams.Scope = DI_REMOVEDEVICE_GLOBAL;
374  RemoveDevParams.HwProfile = 0;
375 
376  //
377  // We probably need to walk all the siblings of this
378  // device and ask if they're happy with the uninstall
379  //
380 
381  // Remove it
383  &m_DevinfoData,
384  &RemoveDevParams.ClassInstallHeader,
385  sizeof(SP_REMOVEDEVICE_PARAMS));
387 
388  // Clear the install params
390  &m_DevinfoData,
391  NULL,
392  0);
393 
394  return true;
395 }
396 
397 /* PRIVATE METHODS ******************************************************/
398 
399 void
401 {
402  if (m_DeviceId)
403  {
404  delete[] m_DeviceId;
405  m_DeviceId = NULL;
406  }
407  if (m_hDevInfo)
408  {
410  m_hDevInfo = NULL;
411  }
412 }
413 
414 DWORD
416 {
417  SP_DEVINSTALL_PARAMS DevInstallParams;
418  DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
420  &m_DevinfoData,
421  &DevInstallParams))
422  {
423  return DevInstallParams.Flags;
424  }
425  return 0;
426 }
427 
428 bool
430  _In_ DWORD Flags,
431  _In_ DWORD FlagsEx
432  )
433 {
434  SP_DEVINSTALL_PARAMS DevInstallParams;
435  DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
437  &m_DevinfoData,
438  &DevInstallParams))
439  {
440  DevInstallParams.Flags |= Flags;
441  DevInstallParams.FlagsEx |= FlagsEx;
443  &m_DevinfoData,
444  &DevInstallParams) != 0);
445  }
446  return false;
447 }
448 
449 bool
451  _In_ DWORD Flags,
452  _In_ DWORD FlagsEx
453  )
454 {
455  SP_DEVINSTALL_PARAMS DevInstallParams;
456  DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
458  &m_DevinfoData,
459  &DevInstallParams))
460  {
461  DevInstallParams.Flags &= ~Flags;
462  DevInstallParams.FlagsEx &= ~FlagsEx;
464  &m_DevinfoData,
465  &DevInstallParams) != 0);
466  }
467  return false;
468 }
CONFIGRET WINAPI CM_Get_DevNode_Status_Ex(_Out_ PULONG pulStatus, _Out_ PULONG pulProblemNumber, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:3580
void Cleanup()
Definition: DeviceNode.cpp:400
DEVINST m_DevInst
Definition: DeviceNode.h:15
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
#define DI_NEEDREBOOT
Definition: setupapi.h:54
bool HasProblem()
Definition: DeviceNode.cpp:163
BOOL WINAPI SetupDiSetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4563
#define DN_ROOT_ENUMERATED
Definition: cfg.h:118
HDEVINFO WINAPI SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, HWND hwndParent, PCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:1268
#define CM_DRP_FRIENDLYNAME
Definition: cfgmgr32.h:688
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
#define DN_DRIVER_LOADED
Definition: cfg.h:119
HDEVINFO m_hDevInfo
Definition: DeviceNode.h:16
#define DN_DISABLEABLE
Definition: cfg.h:131
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
HINSTANCE g_hThisInstance
Definition: MainWindow.cpp:26
BOOL WINAPI SetupDiCallClassInstaller(DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4029
DWORD GetFlags()
Definition: DeviceNode.cpp:415
#define DIF_PROPERTYCHANGE
Definition: setupapi.h:137
#define DICS_ENABLE
Definition: setupapi.h:112
LPWSTR m_DeviceId
Definition: Node.h:17
bool RemoveFlags(_In_ DWORD Flags, _In_ DWORD FlagsEx)
Definition: DeviceNode.cpp:450
#define _In_opt_
Definition: no_sal2.h:213
INT m_ClassImage
Definition: Node.h:20
SP_DEVINFO_DATA m_DevinfoData
Definition: DeviceNode.h:14
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CM_PROB_DISABLED
Definition: cfg.h:52
#define DI_REMOVEDEVICE_GLOBAL
Definition: setupapi.h:42
#define DICS_DISABLE
Definition: setupapi.h:114
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
BOOL WINAPI SetupDiGetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4456
#define CR_SUCCESS
Definition: cfgmgr32.h:842
const WCHAR * str
CONFIGRET WINAPI CM_Get_Device_IDW(_In_ DEVINST dnDevInst, _Out_writes_(BufferLen) PWCHAR Buffer, _In_ ULONG BufferLen, _In_ ULONG ulFlags)
Definition: cfgmgr.c:3665
smooth NULL
Definition: ftsmooth.c:416
#define DI_PROPERTIES_CHANGE
Definition: setupapi.h:60
#define _Out_
Definition: no_sal2.h:323
#define CM_DRP_CLASSGUID
Definition: cfgmgr32.h:684
int m_OverlayImage
Definition: DeviceNode.h:20
#define DN_NO_SHOW_IN_DM
Definition: cfg.h:148
CDeviceNode(_In_opt_ DEVINST Device, _In_ PSP_CLASSIMAGELIST_DATA ImageListData)
Definition: DeviceNode.cpp:15
Definition: Node.h:12
struct _SP_DEVINFO_DATA SP_DEVINFO_DATA
CStringT< wchar_t, StrTraitATL< wchar_t, ChTraitsCRT< wchar_t > > > CAtlStringW
Definition: atlstr.h:126
virtual bool SetupNode()
Definition: DeviceNode.cpp:52
bool CanUninstall()
Definition: DeviceNode.cpp:271
SP_CLASSINSTALL_HEADER ClassInstallHeader
Definition: setupapi.h:911
#define CM_PROB_HARDWARE_DISABLED
Definition: cfg.h:59
BOOL WINAPI SetupDiSetClassInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL, IN DWORD ClassInstallParamsSize)
Definition: devclass.c:1091
GLsizeiptr size
Definition: glext.h:5919
#define DI_NODI_DEFAULTACTION
Definition: setupapi.h:67
#define DN_PRIVATE_PROBLEM
Definition: cfg.h:133
LPGUID GetClassGuid()
Definition: Node.h:37
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_GUID_STRING_LEN
Definition: apphelp.c:29
#define DICS_FLAG_CONFIGSPECIFIC
Definition: setupapi.h:115
virtual bool IsDisabled()
Definition: DeviceNode.cpp:219
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2898
#define MAX_PATH
Definition: compat.h:26
#define CopyMemory
Definition: winbase.h:1633
#define DN_HAS_PROBLEM
Definition: cfg.h:128
GUID m_ClassGuid
Definition: Node.h:19
unsigned long DWORD
Definition: ntddk_ex.h:95
SP_DEVINSTALL_PARAMS_A SP_DEVINSTALL_PARAMS
Definition: setupapi.h:1150
CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(_In_ DEVINST dnDevInst, _In_ ULONG ulProperty, _Out_opt_ PULONG pulRegDataType, _Out_writes_bytes_opt_(*pulLength) PVOID Buffer, _Inout_ PULONG pulLength, _In_ ULONG ulFlags)
Definition: cfgmgr.c:3366
BOOL WINAPI SetupDiGetClassImageIndex(IN PSP_CLASSIMAGELIST_DATA ClassImageListData, IN CONST GUID *ClassGuid, OUT PINT ImageIndex)
Definition: devclass.c:396
Definition: Node.h:9
bool IsStarted()
Definition: DeviceNode.cpp:236
ULONG m_ProblemNumber
Definition: DeviceNode.h:19
bool CanDisable()
Definition: DeviceNode.cpp:202
static const WCHAR L[]
Definition: oid.c:1250
#define CM_DRP_DEVICEDESC
Definition: cfgmgr32.h:676
PSP_CLASSIMAGELIST_DATA m_ImageListData
Definition: Node.h:16
BOOL WINAPI SetupDiChangeState(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5060
#define _In_
Definition: no_sal2.h:204
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define DICS_FLAG_GLOBAL
Definition: setupapi.h:113
bool IsInstalled()
Definition: DeviceNode.cpp:253
DWORD DEVINST
Definition: cfgmgr32.h:76
#define ERROR_CANCELLED
Definition: winerror.h:726
bool UninstallDevice()
Definition: DeviceNode.cpp:365
#define IDS_UNKNOWNDEVICE
Definition: resource.h:111
WCHAR m_DisplayName[DISPLAY_NAME_LEN]
Definition: Node.h:18
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
CONFIGRET WINAPI CM_Get_Device_ID_Size(_Out_ PULONG pulLen, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags)
Definition: cfgmgr.c:4062
bool SetFlags(_In_ DWORD Flags, _In_ DWORD FlagsEx)
Definition: DeviceNode.cpp:429
RETURN_TYPE CONFIGRET
Definition: cfgmgr32.h:74
struct _SP_CLASSINSTALL_HEADER SP_CLASSINSTALL_HEADER
#define DN_STARTED
Definition: cfg.h:121
BOOL WINAPI SetupDiOpenDeviceInfoW(IN HDEVINFO DeviceInfoSet, IN PCWSTR DeviceInstanceId, IN HWND hwndParent OPTIONAL, IN DWORD OpenFlags, OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: devinst.c:4779
#define DIF_REMOVE
Definition: setupapi.h:124
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2247
unsigned int ULONG
Definition: retypes.h:1
bool EnableDevice(_In_ bool Enable, _Out_ bool &NeedsReboot)
Definition: DeviceNode.cpp:290
#define DI_NEEDRESTART
Definition: setupapi.h:53
ULONG m_Status
Definition: DeviceNode.h:18
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
SP_CLASSINSTALL_HEADER ClassInstallHeader
Definition: setupapi.h:917
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
SP_CLASSIMAGELIST_DATA ImageListData
Definition: hdwwiz.c:34
DI_FUNCTION InstallFunction
Definition: setupapi.h:899
#define DICS_FLAG_CONFIGGENERAL
Definition: setupapi.h:118
Definition: dlist.c:348
#define DISPLAY_NAME_LEN
Definition: hotplug.cpp:16
bool IsHidden()
Definition: DeviceNode.cpp:180