ReactOS 0.4.15-dev-7958-gcd0bb1a
DeviceView.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/DeviceView.cpp
5 * PURPOSE: Implements the tree view which contains the devices
6 * COPYRIGHT: Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
7 */
8
9
10
11#include "precomp.h"
12#include "devmgmt.h"
13#include "DeviceView.h"
14
15
16// DATA ********************************************/
17
18#define CLASS_NAME_LEN 256
19#define CLASS_DESC_LEN 256
20#define ROOT_NAME_SIZE MAX_COMPUTERNAME_LENGTH + 1
21
22
24
26{
30};
31
32
33// PUBLIC METHODS ************************************/
34
37 ) :
38 m_hMainWnd(hMainWnd),
39 m_hTreeView(NULL),
40 m_hPropertyDialog(NULL),
41 m_hMenu(NULL),
42 m_ViewType(DevicesByType),
43 m_ShowHidden(false),
44 m_RootNode(NULL)
45{
47}
48
50{
51}
52
53bool
55{
56 // Get the device image list
59 if (bSuccess == FALSE)
60 return false;
61
62 // Create the main treeview
65 NULL,
68 0, 0, 0, 0,
72 NULL);
73 if (m_hTreeView)
74 {
75 // Set the image list against the treeview
79
80 // Give the treeview arrows instead of +/- boxes (on Win7)
81 SetWindowTheme(m_hTreeView, L"explorer", NULL);
82
83 // Create the root node
86 }
87
88
89
90 return !!(m_hTreeView);
91}
92
93bool
95{
97
99 {
102 }
103
104 return true;
105}
106
109 _In_ int x,
110 _In_ int y,
111 _In_ int cx,
112 _In_ int cy
113 )
114{
115 // Resize the treeview
117 NULL,
118 x,
119 y,
120 cx,
121 cy,
123
124 return 0;
125}
126
129 _In_ LPNMHDR NmHdr
130 )
131{
132 TVHITTESTINFO hitInfo;
134
135 GetCursorPos(&hitInfo.pt);
136 ScreenToClient(m_hTreeView, &hitInfo.pt);
137
138 // Check if we are trying to double-click an item
140 if (hItem != NULL && (hitInfo.flags & (TVHT_ONITEM | TVHT_ONITEMICON)))
141 {
143 }
144
145 return 0;
146}
147
150 _In_ LPNMHDR NmHdr
151 )
152{
153 TVHITTESTINFO hitInfo;
155
156 GetCursorPos(&hitInfo.pt);
157 ScreenToClient(m_hTreeView, &hitInfo.pt);
158
160 if (hItem != NULL && (hitInfo.flags & (TVHT_ONITEM | TVHT_ONITEMICON)))
161 {
163 }
164
165 return 0;
166}
167
171 )
172{
174
175 RECT rc;
177 hSelected,
178 &rc,
179 TRUE))
180 {
181 POINT pt;
182 if (GetCursorPos(&pt) &&
184 PtInRect(&rc, pt))
185 {
187 if (Node)
188 {
189 // Create the context menu
190 HMENU hContextMenu = CreatePopupMenu();
191
192 // Add the actions for this node
193 BuildActionMenuForNode(hContextMenu, Node, false);
194
195 INT xPos = GET_X_LPARAM(lParam);
196 INT yPos = GET_Y_LPARAM(lParam);
197
198 // Display the menu
199 TrackPopupMenuEx(hContextMenu,
201 xPos,
202 yPos,
204 NULL);
205
206 DestroyMenu(hContextMenu);
207 }
208 }
209 }
210
211 return 0;
212}
213
214
215void
218 _In_ bool ScanForChanges,
219 _In_ bool UpdateView
220 )
221{
222 // Enum devices on a separate thread to keep the gui responsive
223
225
228 ThreadData->This = this;
229 ThreadData->ScanForChanges = ScanForChanges;
230 ThreadData->UpdateView = UpdateView;
231
234 0,
237 0,
238 NULL);
240}
241
245)
246{
247 switch (Action)
248 {
249 case IDM_PROPERTIES:
250 {
252 break;
253 }
254
256 {
258 true,
259 true);
260 break;
261 }
262
263 case IDM_ENABLE_DRV:
264 {
265 bool NeedsReboot;
266 if (EnableSelectedDevice(true, NeedsReboot) &&
267 NeedsReboot)
268 {
269 MessageBox(m_hMainWnd, L"Rebooting", L"Enable", MB_OK);
270 }
271 break;
272 }
273
274 case IDM_DISABLE_DRV:
275 {
276 bool NeedsReboot;
277 EnableSelectedDevice(false, NeedsReboot);
278 break;
279 }
280
281 case IDM_UPDATE_DRV:
282 {
283 bool NeedsReboot;
284 UpdateSelectedDevice(NeedsReboot);
285 break;
286 }
287
289 {
291 break;
292 }
293
294 case IDM_ADD_HARDWARE:
295 {
297 break;
298 }
299 }
300
301 return 0;
302}
303
304void
306{
308 if (Node && Node->HasProperties())
309 {
311 NULL,
312 Node->GetDeviceId(),
313 1,//DPF_EXTENDED,
314 FALSE);
315 }
316}
317
318void
320{
322}
323
324bool
326 _In_ HMENU OwnerMenu,
327 _In_ bool MainMenu
328 )
329{
331 if (Node)
332 {
333 BuildActionMenuForNode(OwnerMenu, Node, MainMenu);
334 return true;
335 }
336
337 return false;
338}
339
340CNode*
342{
343 TV_ITEM TvItem;
344 TvItem.hItem = TreeView_GetSelection(m_hTreeView);
345 return GetNode(&TvItem);
346}
347
348
349
350// PRIVATE METHODS *******************************************/
351
352bool
354{
356 return (m_hTreeRoot != NULL);
357}
358
359bool
361 _In_ ULONG ClassIndex,
362 _Out_ LPGUID ClassGuid,
363 _Out_ HDEVINFO *hDevInfo
364 )
365{
366 CONFIGRET cr;
367
368 // Get the next class in the list
369 cr = CM_Enumerate_Classes(ClassIndex,
370 ClassGuid,
371 0);
372 if (cr != CR_SUCCESS)
373 return false;
374
375 // We only want the devices for this class
376 *hDevInfo = SetupDiGetClassDevsW(ClassGuid,
377 NULL,
378 NULL,
380
381 return (hDevInfo != INVALID_HANDLE_VALUE);
382}
383
384unsigned int __stdcall CDeviceView::RefreshThread(void *Param)
385{
387 CDeviceView *This = ThreadData->This;
388
389 // Get a copy of the currently selected node
390 CNode *LastSelectedNode = This->GetSelectedNode();
391 if (LastSelectedNode == nullptr || (LastSelectedNode->GetNodeType() == RootNode))
392 {
393 LastSelectedNode = new CRootNode(*This->m_RootNode);
394 }
395 else if (LastSelectedNode->GetNodeType() == ClassNode)
396 {
397 LastSelectedNode = new CClassNode(*dynamic_cast<CClassNode *>(LastSelectedNode));
398 }
399 else if (LastSelectedNode->GetNodeType() == DeviceNode)
400 {
401 LastSelectedNode = new CDeviceNode(*dynamic_cast<CDeviceNode *>(LastSelectedNode));
402 }
403
404 // Empty the treeview
405 This->EmptyDeviceView();
406
407 // Re-add the root node to the tree
408 if (This->AddRootDevice() == false)
409 return 0;
410
411 // Refresh the devices only if requested
412 if (ThreadData->ScanForChanges)
413 {
414 This->RefreshDeviceList();
415 }
416
417 // display the type of view the user wants
418 switch (This->m_ViewType)
419 {
420 case DevicesByType:
421 (void)This->ListDevicesByType();
422 break;
423
425 (VOID)This->ListDevicesByConnection();
426 break;
427
428 case ResourcesByType:
429 break;
430
432 break;
433 }
434
435 This->SelectNode(LastSelectedNode);
436
437 delete ThreadData;
438
439 return 0;
440}
441
442
443bool
445{
448 HDEVINFO hDevInfo;
449 HTREEITEM hTreeItem = NULL;
450 GUID ClassGuid;
451 INT ClassIndex;
452 BOOL bClassSuccess, bSuccess;
453
454 ClassIndex = 0;
455 do
456 {
457 // Loop through all the device classes
458 bClassSuccess = GetNextClass(ClassIndex, &ClassGuid, &hDevInfo);
459 if (bClassSuccess)
460 {
461 bool AddedParent = false;
462 INT DeviceIndex = 0;
463 bool MoreItems = false;
464
465 // Get the cached class node
466 ClassNode = GetClassNode(&ClassGuid);
467 if (ClassNode == nullptr)
468 {
469 ClassIndex++;
470 continue;
471 }
472
473 // Check if this is a hidden class
474 if (IsEqualGUID(ClassGuid, GUID_DEVCLASS_LEGACYDRIVER) ||
475 IsEqualGUID(ClassGuid, GUID_DEVCLASS_VOLUME))
476 {
477 // Ignore this device if we aren't displaying hidden devices
478 if (m_ShowHidden == FALSE)
479 {
480 ClassIndex++;
481 continue;
482 }
483 }
484
485 do
486 {
487 // Get a handle to all the devices in this class
492 DeviceIndex,
495 MoreItems = false;
496
497 if (bSuccess)
498 {
499 MoreItems = true;
500
501 // Get the cached device node
503 if (DeviceNode == nullptr)
504 {
505 DeviceIndex++;
506 continue;
507 }
508
509 // Check if this is a hidden device
510 if (DeviceNode->IsHidden())
511 {
512 // Ignore this device if we aren't displaying hidden devices
513 if (m_ShowHidden == FALSE)
514 {
515 DeviceIndex++;
516 continue;
517 }
518 }
519
520 // We have a device, we need to add the parent if it hasn't yet been added
521 if (AddedParent == false)
522 {
523 // Insert the new class under the root item
525 ClassNode);
526 AddedParent = true;
527 }
528
529 // Add the device under the class item node
531
532 // Expand the class if it has a problem device
533 if (DeviceNode->HasProblem())
534 {
536 hTreeItem,
537 TVE_EXPAND);
538 }
539 }
540
541 DeviceIndex++;
542
543 } while (MoreItems);
544
545 // If this class has devices, sort them alphabetically
546 if (AddedParent == true)
547 {
549 hTreeItem,
550 0);
551 }
552 }
553
554 ClassIndex++;
555
556 } while (bClassSuccess);
557
558 // Sort the classes alphabetically
561 0);
562
563 // Expand the root item
566 TVE_EXPAND);
567
568 // Pre-select the root item
571
572 return 0;
573}
574
575bool
577{
578 // Walk the device tree and add all the devices
580
581 // Expand the root item
584 TVE_EXPAND);
585
586 return true;
587}
588
589bool
592 _In_ HTREEITEM hParentTreeItem
593 )
594{
595 HTREEITEM hDevItem = NULL;
597 bool HasProblem = false;
598 bool bSuccess;
599
600 // Check if the parent has any child devices
602 return true;
603
604 // Get the cached device node
606 DeviceNode = dynamic_cast<CDeviceNode *>(GetDeviceNode(Device));
607 if (DeviceNode == nullptr)
608 {
609 return false;
610 }
611
612 // Don't show hidden devices if not requested
613 if ((m_ShowHidden == TRUE) || (!(DeviceNode->IsHidden())))
614 {
615 // Add this device to the tree under its parent
616 hDevItem = InsertIntoTreeView(hParentTreeItem,
617 DeviceNode);
618 if (hDevItem)
619 {
620 // Check if this child has any children itself
621 if (!RecurseChildDevices(Device, hDevItem))
622 HasProblem = true;
623 }
624
625 if (DeviceNode->HasProblem())
626 {
627 HasProblem = true;
628 }
629 }
630
631
632 // Check for siblings
633 for (;;)
634 {
635 // Check if the parent device has anything at the same level
637 if (bSuccess == FALSE)
638 break;
639
640 DeviceNode = dynamic_cast<CDeviceNode *>(GetDeviceNode(Device));
641 if (DeviceNode == nullptr)
642 {
643 continue;
644 }
645
646 // Don't show hidden devices if not requested
647 if ((m_ShowHidden == TRUE) || (!(DeviceNode->IsHidden())))
648 {
649 if (DeviceNode->HasProblem())
650 {
651 HasProblem = true;
652 }
653
654 // Add this device to the tree under its parent
655 hDevItem = InsertIntoTreeView(hParentTreeItem,
656 DeviceNode);
657 if (hDevItem)
658 {
659 // Check if this child has any children itself
660 if (!RecurseChildDevices(Device, hDevItem))
661 HasProblem = true;
662 }
663 }
664 }
665
667 hParentTreeItem,
668 0);
669
670 // Expand the class if it has a problem device
671 if (HasProblem == true)
672 {
674 hParentTreeItem,
675 TVE_EXPAND);
676 }
677
678 // If there was a problem, expand the ancestors
679 if (HasProblem)
680 return false;
681
682 return true;
683}
684
685bool
687 _In_ bool Enable,
688 _Out_ bool &NeedsReboot
689 )
690{
691 CDeviceNode *Node = dynamic_cast<CDeviceNode *>(GetSelectedNode());
692 if (Node == nullptr)
693 return false;
694
695 if (Enable == false)
696 {
697 CAtlStringW str;
698 if (str.LoadStringW(g_hThisInstance, IDS_CONFIRM_DISABLE))
699 {
701 str,
702 Node->GetDisplayName(),
704 {
705 return false;
706 }
707 }
708 }
709
710 return Node->EnableDevice(Enable, NeedsReboot);
711}
712
713bool
715 _Out_ bool &NeedsReboot
716 )
717{
718 CDeviceNode *Node = dynamic_cast<CDeviceNode *>(GetSelectedNode());
719 if (Node == nullptr)
720 return false;
721
722 DWORD dwReboot;
723 if (InstallDevInst(m_hMainWnd, Node->GetDeviceId(), TRUE, &dwReboot))
724 {
725 NeedsReboot = false;
726 return true;
727 }
728
729 return false;
730}
731
732bool
734 )
735{
736 CDeviceNode *Node = dynamic_cast<CDeviceNode *>(GetSelectedNode());
737 if (Node == nullptr)
738 return false;
739
740 CAtlStringW str;
741 if (str.LoadStringW(g_hThisInstance, IDS_CONFIRM_UNINSTALL))
742 {
744 str,
745 Node->GetDisplayName(),
747 {
748 return false;
749 }
750 }
751
752 return Node->UninstallDevice();
753}
754
755bool
757{
758 PADDHARDWAREWIZARD pAddHardwareWizard;
760
761 hModule = LoadLibraryW(L"hdwwiz.cpl");
762 if (hModule == NULL)
763 return false;
764
765 pAddHardwareWizard = (PADDHARDWAREWIZARD)GetProcAddress(hModule,
766 "AddHardwareWizard");
767 if (pAddHardwareWizard == NULL)
768 {
770 return false;
771 }
772
773 pAddHardwareWizard(m_hMainWnd, NULL);
774
776 return true;
777}
778
779bool
781 _In_ DEVINST ParentDevInst,
782 _Out_ PDEVINST DevInst
783)
784{
785 CONFIGRET cr;
786 cr = CM_Get_Child(DevInst,
787 ParentDevInst,
788 0);
789 return (cr == CR_SUCCESS);
790}
791
792bool
794 _In_ DEVINST PrevDevice,
795 _Out_ PDEVINST DevInst
796)
797{
798 CONFIGRET cr;
799 cr = CM_Get_Sibling(DevInst,
800 PrevDevice,
801 0);
802 return (cr == CR_SUCCESS);
803}
804
807 _In_opt_ HTREEITEM hParent,
809 )
810{
811 LPWSTR lpLabel;
812 lpLabel = Node->GetDisplayName();
813
814 TV_ITEMW tvi;
815 TV_INSERTSTRUCT tvins;
816 ZeroMemory(&tvi, sizeof(tvi));
817 ZeroMemory(&tvins, sizeof(tvins));
818
820 tvi.pszText = lpLabel;
821 tvi.cchTextMax = wcslen(lpLabel);
822 tvi.lParam = (LPARAM)Node;
823 tvi.iImage = Node->GetClassImage();
824 tvi.iSelectedImage = Node->GetClassImage();
825
826 // try to cast it to a device node. This will only succeed if it's the correct type
827 CDeviceNode *DeviceNode = dynamic_cast<CDeviceNode *>(Node);
828 if (DeviceNode && DeviceNode->GetOverlayImage())
829 {
830 tvi.mask |= TVIF_STATE;
831 tvi.stateMask = TVIS_OVERLAYMASK;
832 tvi.state = INDEXTOOVERLAYMASK(DeviceNode->GetOverlayImage());
833 }
834
835 tvins.item = tvi;
836 tvins.hParent = hParent;
837
838 return TreeView_InsertItem(m_hTreeView, &tvins);
839}
840
841void
843 _In_ HMENU OwnerMenu,
844 _In_ CNode *Node,
845 _In_ bool MainMenu
846 )
847{
848 // Create a separator structure
849 MENUITEMINFOW MenuSeparator = { 0 };
850 MenuSeparator.cbSize = sizeof(MENUITEMINFOW);
851 MenuSeparator.fType = MFT_SEPARATOR;
852
853 // Setup the
854 MENUITEMINFOW MenuItemInfo = { 0 };
855 MenuItemInfo.cbSize = sizeof(MENUITEMINFOW);
856 MenuItemInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_SUBMENU;
857 MenuItemInfo.fType = MFT_STRING;
858
859 CAtlStringW String;
860 int i = 0;
861
862 // Device nodes have extra data
863 if (Node->GetNodeType() == DeviceNode)
864 {
865 CDeviceNode *DeviceNode = dynamic_cast<CDeviceNode *>(Node);
866
867 if (DeviceNode->CanUpdate())
868 {
870 MenuItemInfo.wID = IDM_UPDATE_DRV;
871 MenuItemInfo.dwTypeData = String.GetBuffer();
872 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
873 i++;
874 }
875
876 if (DeviceNode->IsDisabled())
877 {
879 MenuItemInfo.wID = IDM_ENABLE_DRV;
880 MenuItemInfo.dwTypeData = String.GetBuffer();
881 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
882 i++;
883 }
884
885 if (DeviceNode->CanDisable() && !DeviceNode->IsDisabled())
886 {
888 MenuItemInfo.wID = IDM_DISABLE_DRV;
889 MenuItemInfo.dwTypeData = String.GetBuffer();
890 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
891 i++;
892 }
893
894 if (DeviceNode->CanUninstall())
895 {
897 MenuItemInfo.wID = IDM_UNINSTALL_DRV;
898 MenuItemInfo.dwTypeData = String.GetBuffer();
899 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
900 i++;
901 }
902
903 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuSeparator);
904 i++;
905 }
906
907 // All nodes have the scan option
909 MenuItemInfo.wID = IDM_SCAN_HARDWARE;
910 MenuItemInfo.dwTypeData = String.GetBuffer();
911 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
912 i++;
913
914 if ((Node->GetNodeType() == RootNode) || (MainMenu == true))
915 {
916 String.LoadStringW(g_hThisInstance, IDS_MENU_ADD);
917 MenuItemInfo.wID = IDM_ADD_HARDWARE;
918 MenuItemInfo.dwTypeData = String.GetBuffer();
919 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
920 i++;
921 }
922
923 if (Node->HasProperties())
924 {
925 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuSeparator);
926 i++;
927
929 MenuItemInfo.wID = IDM_PROPERTIES;
930 MenuItemInfo.dwTypeData = String.GetBuffer();
931 InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
932 i++;
933
935 }
936}
937
940 _In_ HTREEITEM hParentItem,
942 )
943{
944 HTREEITEM FoundItem;
946 TVITEMW tvItem;
947 CNode *FoundNode;
948
949 // Check if this node has any children
950 hItem = TreeView_GetChild(m_hTreeView, hParentItem);
951 if (hItem == NULL)
952 return NULL;
953
954 // The lParam contains the node pointer data
955 tvItem.hItem = hItem;
956 tvItem.mask = TVIF_PARAM;
957 if (TreeView_GetItem(m_hTreeView, &tvItem) &&
958 tvItem.lParam != NULL)
959 {
960 // check for a matching node
961 FoundNode = reinterpret_cast<CNode *>(tvItem.lParam);
962 if ((FoundNode->GetNodeType() == Node->GetNodeType()) &&
963 (IsEqualGUID(*FoundNode->GetClassGuid(), *Node->GetClassGuid())))
964 {
965 // check if this is a class node, or a device with matching ID's
966 if ((FoundNode->GetNodeType() == ClassNode) ||
967 (wcscmp(FoundNode->GetDeviceId(), Node->GetDeviceId()) == 0))
968 {
969 return hItem;
970 }
971 }
972 }
973
974 // This node may have its own children
975 FoundItem = RecurseFindDevice(hItem, Node);
976 if (FoundItem)
977 return FoundItem;
978
979 // Loop all the siblings
980 for (;;)
981 {
982 // Get the next item at this level
984 if (hItem == NULL)
985 break;
986
987 // The lParam contains the node pointer data
988 tvItem.hItem = hItem;
989 tvItem.mask = TVIF_PARAM;
990 if (TreeView_GetItem(m_hTreeView, &tvItem))
991 {
992 // check for a matching class
993 FoundNode = reinterpret_cast<CNode *>(tvItem.lParam);
994 if ((FoundNode->GetNodeType() == Node->GetNodeType()) &&
995 (IsEqualGUID(*FoundNode->GetClassGuid(), *Node->GetClassGuid())))
996 {
997 // check if this is a class node, or a device with matching ID's
998 if ((FoundNode->GetNodeType() == ClassNode) ||
999 (wcscmp(FoundNode->GetDeviceId(), Node->GetDeviceId()) == 0))
1000 {
1001 return hItem;
1002 }
1003 }
1004 }
1005
1006 // This node may have its own children
1007 FoundItem = RecurseFindDevice(hItem, Node);
1008 if (FoundItem)
1009 return FoundItem;
1010 }
1011
1012 return hItem;
1013}
1014
1015void
1017 _In_ CNode *Node
1018 )
1019{
1021
1022 // Check if there are any items in the tree
1024 if (hRoot == NULL)
1025 return;
1026
1027 // If we don't want to set select a node, just select root
1028 if (Node == nullptr || Node->GetNodeType() == RootNode)
1029 {
1031 return;
1032 }
1033
1034 // Scan the tree looking for the node we want
1036 if (hItem)
1037 {
1039 }
1040 else
1041 {
1043 }
1044}
1045
1046
1047void
1049{
1051}
1052
1053
1056 _In_ LPGUID ClassGuid
1057 )
1058{
1059 POSITION Pos;
1060 CClassNode *Node = nullptr;
1061
1062 Pos = m_ClassNodeList.GetHeadPosition();
1063 if (Pos == NULL)
1064 return nullptr;
1065
1066 do
1067 {
1068 Node = m_ClassNodeList.GetNext(Pos);
1069 if (IsEqualGUID(*Node->GetClassGuid(), *ClassGuid))
1070 {
1071 ATLASSERT(Node->GetNodeType() == ClassNode);
1072 break;
1073 }
1074
1075 Node = nullptr;
1076
1077 } while (Pos != NULL);
1078
1079 return Node;
1080}
1081
1085 )
1086{
1087 POSITION Pos;
1088 CDeviceNode *Node = nullptr;
1089
1090 Pos = m_DeviceNodeList.GetHeadPosition();
1091 if (Pos == NULL)
1092 return nullptr;
1093
1094 do
1095 {
1096 Node = m_DeviceNodeList.GetNext(Pos);
1097 if (Node->GetDeviceInst() == Device)
1098 {
1099 ATLASSERT(Node->GetNodeType() == DeviceNode);
1100 break;
1101 }
1102
1103 Node = nullptr;
1104
1105 } while (Pos != NULL);
1106
1107 return Node;
1108}
1109
1111 _In_ LPTV_ITEMW TvItem
1112 )
1113{
1114 TvItem->mask = TVIF_PARAM;
1115 if (TreeView_GetItem(m_hTreeView, TvItem))
1116 {
1117 return (CNode *)TvItem->lParam;
1118 }
1119 return nullptr;
1120}
1121
1122void
1124{
1125 CNode *Node;
1126
1127 while (!m_ClassNodeList.IsEmpty())
1128 {
1129 Node = m_ClassNodeList.RemoveTail();
1130 delete Node;
1131 }
1132
1133 while (!m_DeviceNodeList.IsEmpty())
1134 {
1135 Node = m_DeviceNodeList.RemoveTail();
1136 delete Node;
1137 }
1138}
1139
1140bool
1142{
1143 GUID ClassGuid;
1146 HDEVINFO hDevInfo;
1148 DWORD i;
1149 BOOL Success;
1150
1151 ULONG ClassIndex = 0;
1152
1153 EmptyLists();
1154
1155 if (m_RootNode) delete m_RootNode;
1158
1159 // Loop through all the classes
1160 do
1161 {
1162 Success = GetNextClass(ClassIndex, &ClassGuid, &hDevInfo);
1163 if (Success)
1164 {
1165 // Create a new class node and add it to the list
1166 ClassNode = new CClassNode(&ClassGuid, &m_ImageListData);
1167 if (ClassNode->SetupNode())
1168 {
1169 m_ClassNodeList.AddTail(ClassNode);
1170 }
1171
1173 }
1174 ClassIndex++;
1175 } while (Success);
1176
1177 // Get all the devices on the local machine
1178 hDevInfo = SetupDiGetClassDevsW(NULL,
1179 0,
1180 0,
1182 if (hDevInfo == INVALID_HANDLE_VALUE)
1183 {
1184 return false;
1185 }
1186
1187 // loop though all the devices
1189 for (i = 0;; i++)
1190 {
1191 // Get the devinst for this device
1193 if (Success == FALSE)
1194 break;
1195
1196 // create a new device node and add it to the list
1198 if (DeviceNode->SetupNode())
1199 {
1201 }
1202 else
1203 {
1205 }
1206 }
1207
1209
1210 return TRUE;
1211}
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
VOID(WINAPI * PADDHARDWAREWIZARD)(HWND hwnd, LPWSTR lpName)
Definition: DeviceView.cpp:23
ViewType
Definition: DeviceView.h:7
@ DevicesByConnection
Definition: DeviceView.h:9
@ ResourcesByType
Definition: DeviceView.h:10
@ ResourcesByConnection
Definition: DeviceView.h:11
@ DevicesByType
Definition: DeviceView.h:8
@ ClassNode
Definition: Node.h:8
@ DeviceNode
Definition: Node.h:9
Type
Definition: Type.h:7
#define VOID
Definition: acefi.h:82
#define IDM_PROPERTIES
Definition: resources.h:9
DEVNODE * PDEVINST
Definition: cfgmgr32.h:77
DWORD DEVINST
Definition: cfgmgr32.h:76
RETURN_TYPE CONFIGRET
Definition: cfgmgr32.h:74
#define CR_SUCCESS
Definition: cfgmgr32.h:842
CONFIGRET WINAPI CM_Get_Child(_Out_ PDEVINST pdnDevInst, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags)
Definition: cfgmgr.c:2530
CONFIGRET WINAPI CM_Enumerate_Classes(_In_ ULONG ulClassIndex, _Out_ LPGUID ClassGuid, _In_ ULONG ulFlags)
Definition: cfgmgr.c:1992
CONFIGRET WINAPI CM_Get_Sibling(_Out_ PDEVINST pdnDevInst, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags)
Definition: cfgmgr.c:5529
~CDeviceView(void)
Definition: DeviceView.cpp:49
HWND m_hMainWnd
Definition: DeviceView.h:18
CAtlList< CClassNode * > m_ClassNodeList
Definition: DeviceView.h:27
bool RunAddHardwareWizard()
Definition: DeviceView.cpp:756
void EmptyLists()
void BuildActionMenuForNode(_In_ HMENU OwnerMenu, _In_ CNode *Node, _In_ bool MainMenu)
Definition: DeviceView.cpp:842
CNode * GetSelectedNode()
Definition: DeviceView.cpp:341
LRESULT OnSize(_In_ int x, _In_ int y, _In_ int cx, _In_ int cy)
Definition: DeviceView.cpp:108
HWND m_hTreeView
Definition: DeviceView.h:19
bool RecurseChildDevices(_In_ DEVINST ParentDevice, _In_ HTREEITEM hParentTreeItem)
Definition: DeviceView.cpp:590
VOID DisplayPropertySheet()
Definition: DeviceView.cpp:305
bool EnableSelectedDevice(_In_ bool Enable, _Out_ bool &NeedsReboot)
Definition: DeviceView.cpp:686
HTREEITEM RecurseFindDevice(_In_ HTREEITEM hParentItem, _In_ CNode *Node)
Definition: DeviceView.cpp:939
VOID SetFocus()
Definition: DeviceView.cpp:319
CNode * GetNode(_In_ LPTV_ITEMW TvItem)
bool RefreshDeviceList()
CRootNode * m_RootNode
Definition: DeviceView.h:26
bool ListDevicesByType()
Definition: DeviceView.cpp:444
bool GetChildDevice(_In_ DEVINST ParentDevInst, _Out_ PDEVINST DevInst)
Definition: DeviceView.cpp:780
void EmptyDeviceView()
bool UninstallSelectedDevice()
Definition: DeviceView.cpp:733
void SelectNode(_In_ CNode *Node)
ViewType GetCurrentView()
Definition: DeviceView.h:78
bool AddRootDevice()
Definition: DeviceView.cpp:353
bool GetNextClass(_In_ ULONG ClassIndex, _Out_ LPGUID ClassGuid, _Out_ HDEVINFO *hDevInfo)
Definition: DeviceView.cpp:360
CDeviceNode * GetDeviceNode(_In_ DEVINST Device)
HTREEITEM m_hTreeRoot
Definition: DeviceView.h:23
CAtlList< CDeviceNode * > m_DeviceNodeList
Definition: DeviceView.h:28
HTREEITEM InsertIntoTreeView(_In_opt_ HTREEITEM hParent, _In_ CNode *Node)
Definition: DeviceView.cpp:806
bool GetSiblingDevice(_In_ DEVINST PrevDevice, _Out_ PDEVINST DevInst)
Definition: DeviceView.cpp:793
ViewType m_ViewType
Definition: DeviceView.h:22
static unsigned int __stdcall RefreshThread(void *Param)
Definition: DeviceView.cpp:384
VOID Refresh(_In_ ViewType Type, _In_ bool ScanForChanges, _In_ bool UpdateView)
Definition: DeviceView.cpp:216
CClassNode * GetClassNode(_In_ LPGUID ClassGuid)
bool UpdateSelectedDevice(_Out_ bool &NeedsReboot)
Definition: DeviceView.cpp:714
CDeviceView(HWND hMainWnd)
Definition: DeviceView.cpp:35
bool Uninitialize()
Definition: DeviceView.cpp:94
LRESULT OnAction(UINT Action)
Definition: DeviceView.cpp:243
SP_CLASSIMAGELIST_DATA m_ImageListData
Definition: DeviceView.h:29
LRESULT OnRightClick(_In_ LPNMHDR NmHdr)
Definition: DeviceView.cpp:149
bool Initialize()
Definition: DeviceView.cpp:54
bool CreateActionMenu(_In_ HMENU OwnerMenu, _In_ bool MainMenu)
Definition: DeviceView.cpp:325
LRESULT OnContextMenu(_In_ LPARAM lParam)
Definition: DeviceView.cpp:169
bool m_ShowHidden
Definition: DeviceView.h:24
LRESULT OnDoubleClick(_In_ LPNMHDR NmHdr)
Definition: DeviceView.cpp:128
bool ListDevicesByConnection()
Definition: DeviceView.cpp:576
Definition: Node.h:13
LPGUID GetClassGuid()
Definition: Node.h:37
LPWSTR GetDeviceId()
Definition: Node.h:40
NodeType GetNodeType()
Definition: Node.h:36
virtual bool SetupNode()
Definition: RootNode.cpp:27
DEVINST GetDeviceInst()
Definition: RootNode.h:15
LPARAM lParam
Definition: combotst.c:139
ush Pos
Definition: deflate.h:92
HINSTANCE g_hThisInstance
Definition: MainWindow.cpp:25
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
#define IDC_PROPERTIES
Definition: resource.h:32
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define LoadLibraryW(x)
Definition: compat.h:747
INT_PTR WINAPI DevicePropertiesExW(IN HWND hWndParent OPTIONAL, IN LPCWSTR lpMachineName OPTIONAL, IN LPCWSTR lpDeviceID OPTIONAL, IN DWORD dwFlags OPTIONAL, IN BOOL bShowDevMgr)
Definition: api.cpp:272
BOOL WINAPI InstallDevInst(IN HWND hWndParent, IN LPCWSTR InstanceId, IN BOOL bUpdate, OUT LPDWORD lpReboot)
Definition: stubs.cpp:24
#define IDS_MENU_SCAN
Definition: resource.h:61
#define IDM_UPDATE_DRV
Definition: resource.h:26
#define IDC_TREEVIEW
Definition: resource.h:13
#define IDS_CONFIRM_DISABLE
Definition: resource.h:53
#define IDM_SCAN_HARDWARE
Definition: resource.h:23
#define IDS_MENU_DISABLE
Definition: resource.h:59
#define IDS_MENU_PROPERTIES
Definition: resource.h:63
#define IDM_UNINSTALL_DRV
Definition: resource.h:27
#define IDS_MENU_UNINSTALL
Definition: resource.h:60
#define IDM_ENABLE_DRV
Definition: resource.h:24
#define IDS_MENU_UPDATE
Definition: resource.h:57
#define IDM_DISABLE_DRV
Definition: resource.h:25
#define IDS_MENU_ENABLE
Definition: resource.h:58
#define IDS_MENU_ADD
Definition: resource.h:62
#define IDS_CONFIRM_UNINSTALL
Definition: resource.h:54
#define IDM_ADD_HARDWARE
Definition: resource.h:28
BOOL WINAPI SetupDiDestroyClassImageList(IN PSP_CLASSIMAGELIST_DATA ClassImageListData)
Definition: devclass.c:85
BOOL WINAPI SetupDiGetClassImageList(OUT PSP_CLASSIMAGELIST_DATA ClassImageListData)
Definition: devclass.c:322
BOOL WINAPI SetupDiEnumDeviceInfo(HDEVINFO devinfo, DWORD index, PSP_DEVINFO_DATA info)
Definition: devinst.c:1787
HDEVINFO WINAPI SetupDiGetClassDevsW(CONST GUID *class, LPCWSTR enumstr, HWND parent, DWORD flags)
Definition: devinst.c:2292
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2893
#define pt(x, y)
Definition: drawing.c:79
static BOOLEAN bSuccess
Definition: drive.cpp:433
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19
void Refresh(void)
Definition: magnifier.c:317
HWND hMainWnd
Definition: magnifier.c:32
static HTREEITEM hRoot
Definition: treeview.c:381
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define L(x)
Definition: ntvdm.h:50
#define WS_CHILD
Definition: pedump.c:617
#define WS_BORDER
Definition: pedump.c:625
#define WS_VISIBLE
Definition: pedump.c:620
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
#define TVS_LINESATROOT
Definition: commctrl.h:3249
#define TreeView_DeleteAllItems(hwnd)
Definition: commctrl.h:3417
#define TVIF_TEXT
Definition: commctrl.h:3266
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3481
#define TVHT_ONITEM
Definition: commctrl.h:3527
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3420
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3466
#define TreeView_SortChildren(hwnd, hitem, recurse)
Definition: commctrl.h:3542
#define TVIF_IMAGE
Definition: commctrl.h:3267
#define TVSIL_NORMAL
Definition: commctrl.h:3443
_Out_opt_ int * cx
Definition: commctrl.h:585
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3252
#define TreeView_GetSelection(hwnd)
Definition: commctrl.h:3473
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3490
#define TVS_HASLINES
Definition: commctrl.h:3248
#define TreeView_GetItemRect(hwnd, hitem, prc, code)
Definition: commctrl.h:3429
#define TVE_EXPAND
Definition: commctrl.h:3423
#define TV_INSERTSTRUCT
Definition: commctrl.h:3377
#define TV_ITEMW
Definition: commctrl.h:3297
#define WC_TREEVIEW
Definition: commctrl.h:3245
#define TV_ITEM
Definition: commctrl.h:3300
#define TreeView_GetRoot(hwnd)
Definition: commctrl.h:3475
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3467
#define TVIS_OVERLAYMASK
Definition: commctrl.h:3287
#define TVS_HASBUTTONS
Definition: commctrl.h:3247
#define TVHT_ONITEMICON
Definition: commctrl.h:3525
#define LPTV_ITEMW
Definition: commctrl.h:3295
#define INDEXTOOVERLAYMASK(i)
Definition: commctrl.h:425
#define TVIF_PARAM
Definition: commctrl.h:3268
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3447
#define TreeView_HitTest(hwnd, lpht)
Definition: commctrl.h:3513
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3412
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3271
#define TVIF_STATE
Definition: commctrl.h:3269
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
const WCHAR * str
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
struct _SP_CLASSIMAGELIST_DATA SP_CLASSIMAGELIST_DATA
#define DIGCF_ALLCLASSES
Definition: setupapi.h:172
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1528
#define DIGCF_PRESENT
Definition: setupapi.h:171
struct _SP_DEVINFO_DATA SP_DEVINFO_DATA
#define false
Definition: stdbool.h:37
CDeviceView * This
Definition: DeviceView.cpp:27
LPWSTR dwTypeData
Definition: winuser.h:3269
HTREEITEM hItem
Definition: commctrl.h:3317
LPARAM lParam
Definition: commctrl.h:3325
UINT mask
Definition: commctrl.h:3316
static void UpdateView(TreeListData *pData)
Definition: treelist.c:1636
HTREEITEM hItem
Definition: treelist.h:37
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
#define __stdcall
Definition: typedefs.h:25
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
HRESULT WINAPI SetWindowTheme(_In_ HWND hwnd, _In_ LPCWSTR pszSubAppName, _In_ LPCWSTR pszSubIdList)
Definition: uxthemesupp.c:69
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_ WDFDEVICE ParentDevice
Definition: wdfpdo.h:220
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpName
Definition: winbase.h:2789
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
#define WINAPI
Definition: msvc.h:6
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:300
#define GET_X_LPARAM(lp)
Definition: windowsx.h:299
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define MIIM_STRING
Definition: winuser.h:727
#define MIIM_ID
Definition: winuser.h:722
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_RIGHTBUTTON
Definition: winuser.h:2380
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2670
#define MB_YESNO
Definition: winuser.h:817
#define MFT_SEPARATOR
Definition: winuser.h:744
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define MIIM_SUBMENU
Definition: winuser.h:723
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define MB_OK
Definition: winuser.h:790
#define MB_ICONWARNING
Definition: winuser.h:786
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MessageBox
Definition: winuser.h:5822
#define MB_DEFBUTTON2
Definition: winuser.h:799
#define MFT_STRING
Definition: winuser.h:746
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define IDYES
Definition: winuser.h:835
#define SWP_NOZORDER
Definition: winuser.h:1247
#define MIIM_DATA
Definition: winuser.h:726
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
struct tagMENUITEMINFOW MENUITEMINFOW
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
WCHAR * LPWSTR
Definition: xmlstorage.h:184