[DEVMGR]
[reactos.git] / reactos / dll / win32 / devmgr / devmgmt / DeviceNode.cpp
index a4f46a8..bcd471d 100644 (file)
@@ -1,13 +1,13 @@
 /*
 * PROJECT:     ReactOS Device Manager
 * LICENSE:     GPL - See COPYING in the top level directory
-* FILE:        dll/win32/devmgr/devmgr/ClassNode.cpp
+* FILE:        dll/win32/devmgr/devmgmt/ClassNode.cpp
 * PURPOSE:     Class object for
 * COPYRIGHT:   Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
 *
 */
 
-#include "stdafx.h"
+#include "precomp.h"
 #include "devmgmt.h"
 #include "DeviceNode.h"
 
@@ -16,7 +16,7 @@ CDeviceNode::CDeviceNode(
     _In_opt_ DEVINST Device,
     _In_ PSP_CLASSIMAGELIST_DATA ImageListData
     ) :
-    CNode(ImageListData),
+    CNode(DeviceNode, ImageListData),
     m_DevInst(Device),
     m_hDevInfo(NULL),
     m_Status(0),
@@ -26,6 +26,24 @@ CDeviceNode::CDeviceNode(
     ZeroMemory(&m_DevinfoData, sizeof(SP_DEVINFO_DATA));
 }
 
+CDeviceNode::CDeviceNode(
+    _In_ const CDeviceNode &Node
+    ) :
+    CNode(Node)
+{
+    m_DevInst = Node.m_DevInst;
+    m_hDevInfo = Node.m_hDevInfo;
+    m_Status = Node.m_Status;
+    m_ProblemNumber = Node.m_ProblemNumber;
+    m_OverlayImage = Node.m_OverlayImage;
+    CopyMemory(&m_DevinfoData, &Node.m_DevinfoData, sizeof(SP_DEVINFO_DATA));
+
+    size_t size = wcslen(Node.m_DeviceId) + 1;
+    m_DeviceId = new WCHAR[size];
+    StringCbCopyW(m_DeviceId, size * sizeof(WCHAR), Node.m_DeviceId);
+
+}
+
 CDeviceNode::~CDeviceNode()
 {
     Cleanup();
@@ -50,7 +68,7 @@ CDeviceNode::SetupNode()
                                 m_DeviceId,
                                 ulLength + 1,
                                 0);
-        if (cr != CR_SUCCESS)
+        if (cr != CR_SUCCESS || wcscmp(m_DeviceId, L"HTREE\\ROOT\\0") == 0)
         {
             delete[] m_DeviceId;
             m_DeviceId = NULL;
@@ -78,17 +96,20 @@ CDeviceNode::SetupNode()
     }
 
 
-    // Set the overlay if the device has a problem
+    // Check if the device has a problem
     if (HasProblem())
     {
-        m_OverlayImage = 1;
+        if (IsDisabled())
+        {
+            m_OverlayImage = OverlayDisabled;
+        }
+        else
+        {
+            m_OverlayImage = OverlayProblem;
+        }
     }
 
-    // The disabled overlay takes precidence over the problem overlay
-    if (IsDisabled())
-    {
-        m_OverlayImage = 2;
-    }
+
 
 
     // Get the class guid for this device
@@ -116,6 +137,7 @@ CDeviceNode::SetupNode()
                               &m_ClassGuid,
                               &m_ClassImage);
 
+
     // Get the description for the device
     ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
     cr = CM_Get_DevNode_Registry_PropertyW(m_DevInst,
@@ -136,11 +158,11 @@ CDeviceNode::SetupNode()
 
     }
 
-    // Cleanup if something failed
     if (cr != CR_SUCCESS)
     {
-        Cleanup();
-        return false;
+        CAtlStringW str;
+        if (str.LoadStringW(g_hThisInstance, IDS_UNKNOWNDEVICE))
+            StringCchCopyW(m_DisplayName, MAX_PATH, str.GetBuffer());
     }
 
     return true;
@@ -174,9 +196,14 @@ CDeviceNode::IsHidden()
                                   NULL);
     if (cr == CR_SUCCESS)
     {
-        return ((m_Status & DN_NO_SHOW_IN_DM) != 0);
+        if (m_Status & DN_NO_SHOW_IN_DM)
+            return true;
     }
 
+    if (IsEqualGUID(*GetClassGuid(), GUID_DEVCLASS_LEGACYDRIVER) ||
+        IsEqualGUID(*GetClassGuid(), GUID_DEVCLASS_VOLUME))
+        return true;
+
     return false;
 }
 
@@ -208,7 +235,7 @@ CDeviceNode::IsDisabled()
                                   NULL);
     if (cr == CR_SUCCESS)
     {
-        return ((m_ProblemNumber & (CM_PROB_DISABLED | CM_PROB_HARDWARE_DISABLED)) != 0);
+        return ((m_ProblemNumber == CM_PROB_DISABLED) || (m_ProblemNumber == CM_PROB_HARDWARE_DISABLED));
     }
 
     return false;
@@ -260,11 +287,12 @@ CDeviceNode::CanUninstall()
                                   NULL);
     if (cr == CR_SUCCESS)
     {
-        return ((m_Status & DN_DISABLEABLE) != 0 &&
-                (m_Status & DN_ROOT_ENUMERATED) == 0);
+        if ((m_Status & DN_ROOT_ENUMERATED) != 0 &&
+            (m_Status & DN_DISABLEABLE) == 0)
+                return false;
     }
 
-    return false;
+    return true;
 }
 
 bool
@@ -273,7 +301,6 @@ CDeviceNode::EnableDevice(
     _Out_ bool &NeedsReboot
     )
 {
-    bool Ret = false;
     bool Canceled = false;
 
     SetFlags(DI_NODI_DEFAULTACTION, 0);
@@ -289,7 +316,7 @@ CDeviceNode::EnableDevice(
     for (int i = 0; i < 2; i++)
     {
         // Check globally first, then check config specific
-        pcp.Scope = (i == 0) ? DICS_FLAG_GLOBAL : DICS_FLAG_CONFIGSPECIFIC;
+        pcp.Scope = (i == 0) ? DICS_FLAG_CONFIGGENERAL : DICS_FLAG_CONFIGSPECIFIC;
 
         if (SetupDiSetClassInstallParamsW(m_hDevInfo,
                                           &m_DevinfoData,
@@ -319,6 +346,7 @@ CDeviceNode::EnableDevice(
             SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
         }
 
+
         if (Enable)
         {
             // config specific enabling first, then global enabling.
@@ -343,6 +371,42 @@ CDeviceNode::EnableDevice(
     return true;
 }
 
+bool
+CDeviceNode::UninstallDevice()
+{
+
+    if (CanUninstall() == false)
+        return false;
+
+    SP_REMOVEDEVICE_PARAMS RemoveDevParams;
+    RemoveDevParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+    RemoveDevParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
+    RemoveDevParams.Scope = DI_REMOVEDEVICE_GLOBAL;
+    RemoveDevParams.HwProfile = 0;
+
+    //
+    // We probably need to walk all the siblings of this 
+    // device and ask if they're happy with the uninstall
+    //
+
+
+    // Remove it
+    SetupDiSetClassInstallParamsW(m_hDevInfo,
+                                  &m_DevinfoData,
+                                  &RemoveDevParams.ClassInstallHeader,
+                                  sizeof(SP_REMOVEDEVICE_PARAMS));
+    SetupDiCallClassInstaller(DIF_REMOVE, m_hDevInfo, &m_DevinfoData);
+
+    // Clear the install params
+    SetupDiSetClassInstallParamsW(m_hDevInfo,
+                                  &m_DevinfoData,
+                                  NULL,
+                                  0);
+
+    return true;
+
+}
+
 /* PRIVATE METHODS ******************************************************/
 
 void
@@ -389,9 +453,9 @@ CDeviceNode::SetFlags(
     {
         DevInstallParams.Flags |= Flags;
         DevInstallParams.FlagsEx |= FlagsEx;
-        return SetupDiSetDeviceInstallParamsW(m_hDevInfo,
-                                              &m_DevinfoData,
-                                              &DevInstallParams);
+        return (SetupDiSetDeviceInstallParamsW(m_hDevInfo,
+                                               &m_DevinfoData,
+                                               &DevInstallParams) != 0);
     }
     return false;
 }
@@ -410,9 +474,9 @@ CDeviceNode::RemoveFlags(
     {
         DevInstallParams.Flags &= ~Flags;
         DevInstallParams.FlagsEx &= ~FlagsEx;
-        return SetupDiSetDeviceInstallParamsW(m_hDevInfo,
-                                              &m_DevinfoData,
-                                              &DevInstallParams);
+        return (SetupDiSetDeviceInstallParamsW(m_hDevInfo,
+                                               &m_DevinfoData,
+                                               &DevInstallParams) != 0);
     }
     return false;
 }