diff --git a/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp b/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp index 96d6a397d39..eff0d5c5cdf 100644 --- a/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp +++ b/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp @@ -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(); @@ -290,7 +308,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, @@ -320,6 +338,7 @@ CDeviceNode::EnableDevice( SetupDiChangeState(m_hDevInfo, &m_DevinfoData); } + if (Enable) { // config specific enabling first, then global enabling. diff --git a/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h b/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h index 3c5ddc5c0c3..58520b616b0 100644 --- a/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h +++ b/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h @@ -20,6 +20,10 @@ public: ~CDeviceNode(); + CDeviceNode( + _In_ const CDeviceNode &Node + ); + virtual bool SetupNode(); DEVINST GetDeviceInst() { return m_DevInst; } diff --git a/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp b/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp index 388a258e30c..13b14d4a286 100644 --- a/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp +++ b/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp @@ -27,7 +27,6 @@ struct RefreshThreadData CDeviceView *This; BOOL ScanForChanges; BOOL UpdateView; - LPWSTR DeviceId; }; @@ -79,6 +78,10 @@ CDeviceView::Initialize() // Give the treeview arrows instead of +/- boxes (on Win7) SetWindowTheme(m_hTreeView, L"explorer", NULL); + + // Create the root node + m_RootNode = new CRootNode(&m_ImageListData); + m_RootNode->SetupNode(); } @@ -198,15 +201,6 @@ CDeviceView::Refresh( ThreadData->This = this; ThreadData->ScanForChanges = ScanForChanges; ThreadData->UpdateView = UpdateView; - ThreadData->DeviceId = NULL; - - if (DeviceId) - { - // Node gets deleted on refresh so we copy it to another block - size_t Length = wcslen(DeviceId) + 1; - ThreadData->DeviceId = new WCHAR[Length]; - StringCbCopyW(ThreadData->DeviceId, Length, DeviceId); - } HANDLE hThread; @@ -377,13 +371,29 @@ unsigned int __stdcall CDeviceView::RefreshThread(void *Param) RefreshThreadData *ThreadData = (RefreshThreadData *)Param; CDeviceView *This = ThreadData->This; + // Get a copy of the currently selected node + CNode *LastSelectedNode = This->GetSelectedNode(); + if (LastSelectedNode == nullptr || (LastSelectedNode->GetNodeType() == RootNode)) + { + LastSelectedNode = new CRootNode(*This->m_RootNode); + } + else if (LastSelectedNode->GetNodeType() == ClassNode) + { + LastSelectedNode = new CClassNode(*dynamic_cast(LastSelectedNode)); + } + else if (LastSelectedNode->GetNodeType() == DeviceNode) + { + LastSelectedNode = new CDeviceNode(*dynamic_cast(LastSelectedNode)); + } // Empty the treeview This->EmptyDeviceView(); - This->m_hTreeRoot = NULL; - // Refresh the devices only if requested. This means - // switching views uses the cache and remains fast + // Re-add the root node to the tree + if (This->AddRootDevice() == false) + return 0; + + // Refresh the devices only if requested if (ThreadData->ScanForChanges) { This->RefreshDeviceList(); @@ -408,10 +418,8 @@ unsigned int __stdcall CDeviceView::RefreshThread(void *Param) } - This->SelectNode(ThreadData->DeviceId); + This->SelectNode(LastSelectedNode); - if (ThreadData->DeviceId) - delete[] ThreadData->DeviceId; delete ThreadData; return 0; @@ -429,10 +437,6 @@ CDeviceView::ListDevicesByType() INT ClassIndex; BOOL bClassSuccess, bSuccess; - // Start by adding the root node to the tree - bSuccess = AddRootDevice(); - if (bSuccess == false) return false; - ClassIndex = 0; do { @@ -564,12 +568,6 @@ CDeviceView::ListDevicesByType() bool CDeviceView::ListDevicesByConnection() { - bool bSuccess; - - // Start by adding the root node to the tree - bSuccess = AddRootDevice(); - if (bSuccess == false) return false; - // Walk the device tree and add all the devices (void)RecurseChildDevices(m_RootNode->GetDeviceInst(), m_hTreeRoot); @@ -928,13 +926,13 @@ CDeviceView::BuildActionMenuForNode( HTREEITEM CDeviceView::RecurseFindDevice( _In_ HTREEITEM hParentItem, - _In_ LPWSTR DeviceId + _In_ CNode *Node ) { HTREEITEM FoundItem; HTREEITEM hItem; TVITEMW tvItem; - CNode *Node; + CNode *FoundNode; // Check if this node has any children hItem = TreeView_GetChild(m_hTreeView, hParentItem); @@ -946,17 +944,22 @@ CDeviceView::RecurseFindDevice( if (TreeView_GetItem(m_hTreeView, &tvItem) && tvItem.lParam != NULL) { - // check for a matching deviceid - Node = reinterpret_cast(tvItem.lParam); - if (Node->GetDeviceId() && - (wcscmp(Node->GetDeviceId(), DeviceId) == 0)) + // check for a matching node + FoundNode = reinterpret_cast(tvItem.lParam); + if ((FoundNode->GetNodeType() == Node->GetNodeType()) && + (IsEqualGUID(*FoundNode->GetClassGuid(), *Node->GetClassGuid()))) { - return hItem; + // check if this is a class node, or a device with matching ID's + if ((FoundNode->GetNodeType() == ClassNode) || + (wcscmp(FoundNode->GetDeviceId(), Node->GetDeviceId()) == 0)) + { + return hItem; + } } } // This node may have its own children - FoundItem = RecurseFindDevice(hItem, DeviceId); + FoundItem = RecurseFindDevice(hItem, Node); if (FoundItem) return FoundItem; // Loop all the siblings @@ -971,17 +974,22 @@ CDeviceView::RecurseFindDevice( tvItem.mask = TVIF_PARAM; if (TreeView_GetItem(m_hTreeView, &tvItem)) { - // check for a matching deviceid - Node = reinterpret_cast(tvItem.lParam); - if (Node->GetDeviceId() && - wcscmp(Node->GetDeviceId(), DeviceId) == 0) + // check for a matching class + FoundNode = reinterpret_cast(tvItem.lParam); + if ((FoundNode->GetNodeType() == Node->GetNodeType()) && + (IsEqualGUID(*FoundNode->GetClassGuid(), *Node->GetClassGuid()))) { - return hItem; + // check if this is a class node, or a device with matching ID's + if ((FoundNode->GetNodeType() == ClassNode) || + (wcscmp(FoundNode->GetDeviceId(), Node->GetDeviceId()) == 0)) + { + return hItem; + } } } // This node may have its own children - FoundItem = RecurseFindDevice(hItem, DeviceId); + FoundItem = RecurseFindDevice(hItem, Node); if (FoundItem) return FoundItem; } @@ -990,7 +998,7 @@ CDeviceView::RecurseFindDevice( void CDeviceView::SelectNode( - _In_ LPWSTR DeviceId + _In_ CNode *Node ) { HTREEITEM hRoot, hItem; @@ -1000,18 +1008,17 @@ CDeviceView::SelectNode( if (hRoot == NULL) return; // If we don't want to set select a node, just select root - if (DeviceId == NULL) + if (Node == nullptr || Node->GetNodeType() == RootNode) { TreeView_SelectItem(m_hTreeView, hRoot); return; } // Scan the tree looking for the node we want - hItem = RecurseFindDevice(hRoot, DeviceId); + hItem = RecurseFindDevice(hRoot, Node); if (hItem) { TreeView_SelectItem(m_hTreeView, hItem); - TreeView_Expand(m_hTreeView, hItem, TVM_EXPAND); } else { @@ -1033,7 +1040,7 @@ CDeviceView::GetClassNode( ) { POSITION Pos; - CClassNode *Node; + CClassNode *Node = nullptr; Pos = m_ClassNodeList.GetHeadPosition(); if (Pos == NULL) return nullptr; @@ -1047,7 +1054,7 @@ CDeviceView::GetClassNode( break; } - Node = NULL; + Node = nullptr; } while (Pos != NULL); @@ -1060,7 +1067,7 @@ CDeviceView::GetDeviceNode( ) { POSITION Pos; - CDeviceNode *Node; + CDeviceNode *Node = nullptr; Pos = m_DeviceNodeList.GetHeadPosition(); if (Pos == NULL) return nullptr; @@ -1074,7 +1081,7 @@ CDeviceView::GetDeviceNode( break; } - Node = NULL; + Node = nullptr; } while (Pos != NULL); @@ -1090,7 +1097,7 @@ CNode* CDeviceView::GetNode( { return (CNode *)TvItem->lParam; } - return NULL; + return nullptr; } void diff --git a/reactos/dll/win32/devmgr/devmgmt/DeviceView.h b/reactos/dll/win32/devmgr/devmgmt/DeviceView.h index 24973f05b75..eb0383e90fb 100644 --- a/reactos/dll/win32/devmgr/devmgmt/DeviceView.h +++ b/reactos/dll/win32/devmgr/devmgmt/DeviceView.h @@ -148,11 +148,11 @@ private: HTREEITEM RecurseFindDevice( _In_ HTREEITEM hParentItem, - _In_ LPWSTR DeviceId + _In_ CNode *Node ); void SelectNode( - _In_ LPWSTR DeviceId + _In_ CNode *Node ); void EmptyDeviceView( diff --git a/reactos/dll/win32/devmgr/devmgmt/Node.cpp b/reactos/dll/win32/devmgr/devmgmt/Node.cpp index 1925d2db756..6e7d761894a 100644 --- a/reactos/dll/win32/devmgr/devmgmt/Node.cpp +++ b/reactos/dll/win32/devmgr/devmgmt/Node.cpp @@ -25,6 +25,17 @@ CNode::CNode(_In_ NodeType Type, m_ClassGuid = GUID_NULL; } +CNode::CNode(const CNode &Node) +{ + m_NodeType = Node.m_NodeType; + m_ImageListData = Node.m_ImageListData; + m_DeviceId = Node.m_DeviceId; + m_ClassImage = Node.m_ClassImage; + + StringCbCopyW(m_DisplayName, DISPLAY_NAME_LEN, Node.m_DisplayName); + CopyMemory(&m_ClassGuid, &Node.m_ClassGuid, sizeof(GUID)); +} + CNode::~CNode() { -} +} \ No newline at end of file diff --git a/reactos/dll/win32/devmgr/devmgmt/Node.h b/reactos/dll/win32/devmgr/devmgmt/Node.h index 373d27bea97..c511112b8a5 100644 --- a/reactos/dll/win32/devmgr/devmgmt/Node.h +++ b/reactos/dll/win32/devmgr/devmgmt/Node.h @@ -25,6 +25,10 @@ public: _In_ PSP_CLASSIMAGELIST_DATA ImageListData ); + CNode( + _In_ const CNode& Node + ); + virtual ~CNode(); virtual bool SetupNode() = 0;