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();
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,
SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
}
+
if (Enable)
{
// config specific enabling first, then global enabling.
CDeviceView *This;
BOOL ScanForChanges;
BOOL UpdateView;
- LPWSTR DeviceId;
};
// 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();
}
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;
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<CClassNode *>(LastSelectedNode));
+ }
+ else if (LastSelectedNode->GetNodeType() == DeviceNode)
+ {
+ LastSelectedNode = new CDeviceNode(*dynamic_cast<CDeviceNode *>(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();
}
- This->SelectNode(ThreadData->DeviceId);
+ This->SelectNode(LastSelectedNode);
- if (ThreadData->DeviceId)
- delete[] ThreadData->DeviceId;
delete ThreadData;
return 0;
INT ClassIndex;
BOOL bClassSuccess, bSuccess;
- // Start by adding the root node to the tree
- bSuccess = AddRootDevice();
- if (bSuccess == false) return false;
-
ClassIndex = 0;
do
{
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);
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);
if (TreeView_GetItem(m_hTreeView, &tvItem) &&
tvItem.lParam != NULL)
{
- // check for a matching deviceid
- Node = reinterpret_cast<CNode *>(tvItem.lParam);
- if (Node->GetDeviceId() &&
- (wcscmp(Node->GetDeviceId(), DeviceId) == 0))
+ // check for a matching node
+ FoundNode = reinterpret_cast<CNode *>(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
tvItem.mask = TVIF_PARAM;
if (TreeView_GetItem(m_hTreeView, &tvItem))
{
- // check for a matching deviceid
- Node = reinterpret_cast<CNode *>(tvItem.lParam);
- if (Node->GetDeviceId() &&
- wcscmp(Node->GetDeviceId(), DeviceId) == 0)
+ // check for a matching class
+ FoundNode = reinterpret_cast<CNode *>(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;
}
void
CDeviceView::SelectNode(
- _In_ LPWSTR DeviceId
+ _In_ CNode *Node
)
{
HTREEITEM hRoot, hItem;
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
{
)
{
POSITION Pos;
- CClassNode *Node;
+ CClassNode *Node = nullptr;
Pos = m_ClassNodeList.GetHeadPosition();
if (Pos == NULL) return nullptr;
break;
}
- Node = NULL;
+ Node = nullptr;
} while (Pos != NULL);
)
{
POSITION Pos;
- CDeviceNode *Node;
+ CDeviceNode *Node = nullptr;
Pos = m_DeviceNodeList.GetHeadPosition();
if (Pos == NULL) return nullptr;
break;
}
- Node = NULL;
+ Node = nullptr;
} while (Pos != NULL);
{
return (CNode *)TvItem->lParam;
}
- return NULL;
+ return nullptr;
}
void