Author: gedmurphy Date: Fri Jun 26 08:45:49 2015 New Revision: 68272
URL: http://svn.reactos.org/svn/reactos?rev=68272&view=rev Log: [DEVMGR] - Add support for selecting any device when refreshing the view. This allows us to re-select a device after it's been enabled instead of collapsing the tree and losing track of what you did. - Plug some memory leaks - HeapAlloc -> new
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp [iso-8859-1] Fri Jun 26 08:45:49 2015 @@ -18,6 +18,7 @@ ) : CNode(ImageListData), m_DevInst(Device), + m_hDevInfo(NULL), m_Status(0), m_ProblemNumber(0), m_OverlayImage(0) @@ -27,7 +28,7 @@
CDeviceNode::~CDeviceNode() { - SetupDiDestroyDeviceInfoList(m_hDevInfo); + Cleanup(); }
bool @@ -37,37 +38,31 @@ ULONG ulLength; CONFIGRET cr;
- // ATLASSERT(m_DeviceId == NULL); - - // Get the length of the device id string cr = CM_Get_Device_ID_Size(&ulLength, m_DevInst, 0); if (cr == CR_SUCCESS) { // We alloc heap here because this will be stored in the lParam of the TV - m_DeviceId = (LPWSTR)HeapAlloc(GetProcessHeap(), - 0, - (ulLength + 1) * sizeof(WCHAR)); - if (m_DeviceId) + m_DeviceId = new WCHAR[ulLength + 1]; + + // Now get the actual device id + cr = CM_Get_Device_IDW(m_DevInst, + m_DeviceId, + ulLength + 1, + 0); + if (cr != CR_SUCCESS) { - // Now get the actual device id - cr = CM_Get_Device_IDW(m_DevInst, - m_DeviceId, - ulLength + 1, - 0); - if (cr != CR_SUCCESS) - { - HeapFree(GetProcessHeap(), 0, m_DeviceId); - m_DeviceId = NULL; - } + delete[] m_DeviceId; + m_DeviceId = NULL; } + }
// Make sure we got the string if (m_DeviceId == NULL) return false;
- //SP_DEVINFO_DATA DevinfoData; + // Build up a handle a and devinfodata struct m_hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, @@ -83,28 +78,14 @@ }
- - // Get the current status of the device - cr = CM_Get_DevNode_Status_Ex(&m_Status, - &m_ProblemNumber, - m_DevInst, - 0, - NULL); - if (cr != CR_SUCCESS) - { - HeapFree(GetProcessHeap(), 0, m_DeviceId); - m_DeviceId = NULL; - return false; - } - - // Check if the device has a problem - if (m_Status & DN_HAS_PROBLEM) + // Set the overlay if the device has a problem + if (HasProblem()) { m_OverlayImage = 1; }
// The disabled overlay takes precidence over the problem overlay - if (m_ProblemNumber & (CM_PROB_DISABLED | CM_PROB_HARDWARE_DISABLED)) + if (IsDisabled()) { m_OverlayImage = 2; } @@ -158,11 +139,11 @@ // Cleanup if something failed if (cr != CR_SUCCESS) { - HeapFree(GetProcessHeap(), 0, m_DeviceId); - m_DeviceId = NULL; - } - - return (cr == CR_SUCCESS ? true : false); + Cleanup(); + return false; + } + + return true; }
bool @@ -340,7 +321,7 @@
if (Enable) { - // config specific enablling first, then global enabling. + // config specific enabling first, then global enabling. // The global appears to be the one that starts the device pcp.Scope = DICS_FLAG_GLOBAL; if (SetupDiSetClassInstallParamsW(m_hDevInfo, @@ -362,6 +343,23 @@ return true; }
+/* PRIVATE METHODS ******************************************************/ + +void +CDeviceNode::Cleanup() +{ + if (m_DeviceId) + { + delete[] m_DeviceId; + m_DeviceId = NULL; + } + if (m_hDevInfo) + { + SetupDiDestroyDeviceInfoList(m_hDevInfo); + m_hDevInfo = NULL; + } +} + DWORD CDeviceNode::GetFlags( )
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h [iso-8859-1] Fri Jun 26 08:45:49 2015 @@ -38,6 +38,9 @@ );
private: + void Cleanup( + ); + bool SetFlags( _In_ DWORD Flags, _In_ DWORD FlagsEx
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp [iso-8859-1] Fri Jun 26 08:45:49 2015 @@ -36,6 +36,7 @@ CDeviceView *This; BOOL ScanForChanges; BOOL UpdateView; + LPWSTR DeviceId; };
@@ -198,7 +199,8 @@ CDeviceView::Refresh( _In_ ViewType Type, _In_ bool ScanForChanges, - _In_ bool UpdateView + _In_ bool UpdateView, + _In_opt_ LPWSTR DeviceId ) { // Enum devices on a seperate thread to keep the gui responsive @@ -210,6 +212,16 @@ 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]; + wcscpy_s(ThreadData->DeviceId, Length, DeviceId); + } +
HANDLE hThread; hThread = (HANDLE)_beginthreadex(NULL, @@ -309,29 +321,29 @@ ) { CDeviceNode *Node = dynamic_cast<CDeviceNode *>(GetSelectedNode()); - if (Node) - { - if (Enable == false) - { - CAtlStringW str; - if (str.LoadStringW(g_hInstance, IDS_CONFIRM_DISABLE)) + if (Node == nullptr) return false; + + if (Enable == false) + { + CAtlStringW str; + if (str.LoadStringW(g_hInstance, IDS_CONFIRM_DISABLE)) + { + if (MessageBoxW(m_hMainWnd, + str, + Node->GetDisplayName(), + MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES) { - if (MessageBoxW(m_hMainWnd, - str, - Node->GetDisplayName(), - MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES) - { - return false; - } + return false; } } - - if (Node->EnableDevice(Enable, NeedsReboot)) - { - Refresh(m_ViewType, true, true); - return true; - } - } + } + + if (Node->EnableDevice(Enable, NeedsReboot)) + { + Refresh(m_ViewType, true, true, Node->GetDeviceId()); + return true; + } + return false; }
@@ -462,6 +474,11 @@ break; }
+ + This->SelectNode(ThreadData->DeviceId); + + if (ThreadData->DeviceId) + delete[] ThreadData->DeviceId; delete ThreadData;
return 0; @@ -650,7 +667,7 @@ // Get the cached device node CDeviceNode *DeviceNode; DeviceNode = dynamic_cast<CDeviceNode *>(GetDeviceNode(Device)); - if (DeviceNode == NULL) + if (DeviceNode == nullptr) { ATLASSERT(FALSE); return false; @@ -684,7 +701,7 @@ if (bSuccess == FALSE) break;
DeviceNode = dynamic_cast<CDeviceNode *>(GetDeviceNode(Device)); - if (DeviceNode == NULL) + if (DeviceNode == nullptr) { ATLASSERT(FALSE); } @@ -790,17 +807,20 @@ return TreeView_InsertItem(m_hTreeView, &tvins); }
-void -CDeviceView::RecurseDeviceView( - _In_ HTREEITEM hParentItem - ) -{ +HTREEITEM +CDeviceView::RecurseFindDevice( + _In_ HTREEITEM hParentItem, + _In_ LPWSTR DeviceId + ) +{ + HTREEITEM FoundItem; HTREEITEM hItem; TVITEMW tvItem; + CNode *Node;
// Check if this node has any children hItem = TreeView_GetChild(m_hTreeView, hParentItem); - if (hItem == NULL) return; + if (hItem == NULL) return NULL;
// The lParam contains the node pointer data tvItem.hItem = hItem; @@ -808,12 +828,17 @@ if (TreeView_GetItem(m_hTreeView, &tvItem) && tvItem.lParam != NULL) { - // Delete the node class - //delete reinterpret_cast<CNode *>(tvItem.lParam); + Node = reinterpret_cast<CNode *>(tvItem.lParam); + if (Node->GetDeviceId() && + (wcscmp(Node->GetDeviceId(), DeviceId) == 0)) + { + return hItem; + } }
// This node may have its own children - RecurseDeviceView(hItem); + FoundItem = RecurseFindDevice(hItem, DeviceId); + if (FoundItem) return FoundItem;
// Delete all the siblings for (;;) @@ -827,12 +852,45 @@ tvItem.mask = TVIF_PARAM; if (TreeView_GetItem(m_hTreeView, &tvItem)) { - //if (tvItem.lParam != NULL) - // delete reinterpret_cast<CNode *>(tvItem.lParam); + Node = reinterpret_cast<CNode *>(tvItem.lParam); + if (Node->GetDeviceId() && + wcscmp(Node->GetDeviceId(), DeviceId) == 0) + { + return hItem; + } }
// This node may have its own children - RecurseDeviceView(hItem); + FoundItem = RecurseFindDevice(hItem, DeviceId); + if (FoundItem) return FoundItem; + } + + return hItem; +} + +void +CDeviceView::SelectNode( + _In_ LPWSTR DeviceId + ) +{ + HTREEITEM hRoot, hItem; + + // Check if there are any items in the tree + hRoot = TreeView_GetRoot(m_hTreeView); + if (hRoot == NULL) return; + + if (DeviceId) + { + hItem = RecurseFindDevice(hRoot, DeviceId); + if (hItem) + { + TreeView_SelectItem(m_hTreeView, hItem); + TreeView_Expand(m_hTreeView, hItem, TVM_EXPAND); + } + } + else + { + TreeView_SelectItem(m_hTreeView, hRoot); } }
@@ -840,20 +898,8 @@ void CDeviceView::EmptyDeviceView() { - HTREEITEM hItem; - - // Check if there are any items in the tree - hItem = TreeView_GetRoot(m_hTreeView); - if (hItem == NULL) return; - - // Free all the class nodes - //RecurseDeviceView(hItem); - - // Delete all the items (VOID)TreeView_DeleteAllItems(m_hTreeView); } - -
CClassNode* @@ -972,6 +1018,8 @@ { m_ClassNodeList.AddTail(ClassNode); } + + SetupDiDestroyDeviceInfoList(hDevInfo); } ClassIndex++; } while (Success);
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h [iso-8859-1] Fri Jun 26 08:45:49 2015 @@ -55,7 +55,8 @@ VOID Refresh( _In_ ViewType Type, _In_ bool ScanForChanges, - _In_ bool UpdateView + _In_ bool UpdateView, + _In_opt_ LPWSTR DeviceId );
VOID DisplayPropertySheet(); @@ -127,11 +128,16 @@ _In_ CNode *Node );
- VOID RecurseDeviceView( - _In_ HTREEITEM hParentItem + HTREEITEM RecurseFindDevice( + _In_ HTREEITEM hParentItem, + _In_ LPWSTR DeviceId );
- VOID EmptyDeviceView( + void SelectNode( + _In_ LPWSTR DeviceId + ); + + void EmptyDeviceView( );
CNode* GetNode( @@ -145,6 +151,7 @@ CDeviceNode* GetDeviceNode( _In_ DEVINST Device ); - void EmptyLists(); + void EmptyLists( + ); };
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/Ma... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp [iso-8859-1] Fri Jun 26 08:45:49 2015 @@ -212,7 +212,7 @@ BOOL bSuccess;
// Refreshed the cached view - m_DeviceView->Refresh(Type, FALSE, TRUE); + m_DeviceView->Refresh(Type, FALSE, TRUE, NULL);
// Get the menu item id switch (Type) @@ -240,7 +240,8 @@ // Refresh the cache and and display m_DeviceView->Refresh(m_DeviceView->GetCurrentView(), true, - true); + true, + NULL); return true; }
@@ -618,7 +619,8 @@ // Refresh the device view m_DeviceView->Refresh(m_DeviceView->GetCurrentView(), false, - true); + true, + NULL); break; }
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/No... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp [iso-8859-1] Fri Jun 26 08:45:49 2015 @@ -24,19 +24,4 @@
CNode::~CNode() { - Cleanup(); } - - -/* PRIVATE METHODS ******************************************/ - - -void -CNode::Cleanup() -{ - if (m_DeviceId) - { - HeapFree(GetProcessHeap(), 0, m_DeviceId); - m_DeviceId = NULL; - } -}