2 * PROJECT: ReactOS Device Managment
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/devmgmt/enumdevices.c
5 * PURPOSE: Enumerates all devices on the local machine
6 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
13 #include <dll/devmgr/devmgr.h>
17 static SP_CLASSIMAGELIST_DATA ImageListData
;
21 FreeDeviceStrings(HWND hTreeView
)
25 hItem
= TreeView_GetRoot(hTreeView
);
29 hItem
= TreeView_GetChild(hTreeView
,
31 /* loop the parent items */
34 hItem
= TreeView_GetChild(hTreeView
,
39 /* loop the child items and free the DeviceID */
47 tvItem
.mask
= TVIF_PARAM
;// | TVIF_TEXT;
48 //tvItem.pszText = Buf;
49 //tvItem.cchTextMax = 99;
51 (void)TreeView_GetItem(hTreeView
, &tvItem
);
53 //MessageBox(NULL, Buf, NULL, 0);
55 HeapFree(GetProcessHeap(),
57 (LPTSTR
)tvItem
.lParam
);
61 hItem
= TreeView_GetNextSibling(hTreeView
,
70 hItem
= TreeView_GetParent(hTreeView
,
72 hItem
= TreeView_GetNextSibling(hTreeView
,
80 OpenPropSheet(HWND hTreeView
,
86 tvItem
.mask
= TVIF_PARAM
;
88 if (TreeView_GetItem(hTreeView
, &tvItem
) &&
89 (LPTSTR
)tvItem
.lParam
!= NULL
)
91 DevicePropertiesExW(hTreeView
,
93 (LPTSTR
)tvItem
.lParam
,
101 InsertIntoTreeView(HWND hTreeView
,
109 TV_INSERTSTRUCT tvins
;
111 ZeroMemory(&tvi
, sizeof(tvi
));
112 ZeroMemory(&tvins
, sizeof(tvins
));
114 tvi
.mask
= TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
115 tvi
.pszText
= lpLabel
;
116 tvi
.cchTextMax
= lstrlen(lpLabel
);
117 tvi
.lParam
= (LPARAM
)DeviceID
;
118 tvi
.iImage
= DevImage
;
119 tvi
.iSelectedImage
= DevImage
;
121 if (OverlayImage
!= 0)
123 tvi
.mask
|= TVIF_STATE
;
124 tvi
.stateMask
= TVIS_OVERLAYMASK
;
125 tvi
.state
= INDEXTOOVERLAYMASK(OverlayImage
);
129 tvins
.hParent
= hRoot
;
131 return TreeView_InsertItem(hTreeView
, &tvins
);
143 for (ulClassIndex
= 0; ; ulClassIndex
++)
145 cr
= CM_Enumerate_Classes(ulClassIndex
,
148 if (cr
== CR_NO_SUCH_VALUE
)
156 GetClassFromClassGuid(
157 PDEVCLASS_ENTRY pClassArray
,
161 PDEVCLASS_ENTRY pClass
, pUnknownClass
= NULL
;
164 for (i
= 0; i
< ulClassCount
; i
++)
166 pClass
= &pClassArray
[i
];
168 if (IsEqualGUID(&pClass
->ClassGuid
, &GUID_DEVCLASS_UNKNOWN
))
169 pUnknownClass
= pClass
;
171 if (IsEqualGUID(&pClass
->ClassGuid
, pGuid
))
175 return pUnknownClass
;
184 PDEVCLASS_ENTRY pClassArray
,
187 WCHAR ClassName
[MAX_DEV_LEN
];
188 WCHAR ClassDesc
[MAX_DEV_LEN
];
189 PDEVCLASS_ENTRY pClass
;
196 for (ClassIndex
= 0; ClassIndex
< ClassCount
; ClassIndex
++)
198 pClass
= &pClassArray
[ClassIndex
];
200 cr
= CM_Enumerate_Classes(ClassIndex
,
203 if (cr
== CR_NO_SUCH_VALUE
)
206 dwSize
= MAX_CLASS_NAME_LEN
;
207 if (!SetupDiClassNameFromGuid(&pClass
->ClassGuid
,
212 ClassName
[0] = _T('\0');
215 if (!SetupDiGetClassImageIndex(&ImageListData
,
217 &pClass
->ClassImage
))
219 /* FIXME: can we do this?
220 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
221 * it'll be image 24 in the imagelist */
222 pClass
->ClassImage
= 24;
225 hKey
= SetupDiOpenClassRegKeyEx(&pClass
->ClassGuid
,
230 if (hKey
!= INVALID_HANDLE_VALUE
)
233 if (RegQueryValue(hKey
,
236 &lSize
) != ERROR_SUCCESS
)
238 ClassDesc
[0] = _T('\0');
244 pClass
->hItem
= InsertIntoTreeView(hTreeView
,
246 (ClassDesc
[0] != _T('\0')) ? ClassDesc
: ClassName
,
258 PDEVCLASS_ENTRY pClassArray
,
262 HDEVINFO hDevInfo
= INVALID_HANDLE_VALUE
;
263 SP_DEVINFO_DATA DeviceInfoData
;
264 ULONG Status
, Problem
;
266 TCHAR DeviceName
[MAX_DEV_LEN
];
269 PDEVCLASS_ENTRY pClass
;
274 /* Get device info for all devices of a particular class */
275 hDevInfo
= SetupDiGetClassDevs(NULL
,
278 DIGCF_PRESENT
| DIGCF_ALLCLASSES
);
279 if (hDevInfo
== INVALID_HANDLE_VALUE
)
282 for (DevIndex
= 0; ; DevIndex
++)
284 ZeroMemory(&DeviceInfoData
, sizeof(SP_DEVINFO_DATA
));
285 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
288 DeviceName
[0] = _T('\0');
291 if (!SetupDiEnumDeviceInfo(hDevInfo
,
296 if (bShowHidden
== FALSE
&&
297 (IsEqualGUID(&DeviceInfoData
.ClassGuid
, &GUID_DEVCLASS_LEGACYDRIVER
) ||
298 IsEqualGUID(&DeviceInfoData
.ClassGuid
, &GUID_DEVCLASS_VOLUME
)))
301 pClass
= GetClassFromClassGuid(pClassArray
,
303 &DeviceInfoData
.ClassGuid
);
305 /* get the device ID */
306 if (!SetupDiGetDeviceInstanceId(hDevInfo
,
312 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
314 InstanceId
= (LPTSTR
)HeapAlloc(GetProcessHeap(),
316 DevIdSize
* sizeof(TCHAR
));
317 if (InstanceId
!= NULL
)
319 if (!SetupDiGetDeviceInstanceId(hDevInfo
,
325 HeapFree(GetProcessHeap(),
334 /* Skip the root device */
335 if (InstanceId
!= NULL
&&
336 _tcscmp(InstanceId
, _T("HTREE\\ROOT\\0")) == 0)
338 HeapFree(GetProcessHeap(),
345 /* Get the device's friendly name */
346 if (!SetupDiGetDeviceRegistryProperty(hDevInfo
,
354 /* If the friendly name fails, try the description instead */
355 SetupDiGetDeviceRegistryProperty(hDevInfo
,
364 cr
= CM_Get_DevNode_Status_Ex(&Status
,
366 DeviceInfoData
.DevInst
,
369 if ((cr
== CR_SUCCESS
) &&
370 (Status
& DN_HAS_PROBLEM
))
372 if (Problem
== CM_PROB_DISABLED
||
373 Problem
== CM_PROB_HARDWARE_DISABLED
)
379 InsertIntoTreeView(hTreeView
,
386 if (OverlayImage
!= 0)
388 /* Expand the class if the device has a problem */
389 (void)TreeView_Expand(hTreeView
,
394 pClass
->bUsed
= TRUE
;
397 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
398 SetupDiDestroyDeviceInfoList(hDevInfo
);
404 CleanupDeviceClasses(
406 PDEVCLASS_ENTRY pClassArray
,
409 PDEVCLASS_ENTRY pClass
;
412 for (i
= 0; i
< ulClassCount
; i
++)
414 pClass
= &pClassArray
[i
];
416 if (pClass
->bUsed
== FALSE
)
417 (void)TreeView_DeleteItem(hTreeView
,
420 (void)TreeView_SortChildren(hTreeView
,
428 ListDevicesByType(HWND hTreeView
,
432 PDEVCLASS_ENTRY pClassArray
;
435 ulClassCount
= GetClassCount();
437 pClassArray
= HeapAlloc(GetProcessHeap(),
439 ulClassCount
* sizeof(DEVCLASS_ENTRY
));
440 if (pClassArray
== NULL
)
443 EnumDeviceClasses(hTreeView
,
448 EnumDevices(hTreeView
,
453 CleanupDeviceClasses(hTreeView
,
457 if (pClassArray
!= NULL
)
458 HeapFree(GetProcessHeap(), 0, pClassArray
);
460 (void)TreeView_Expand(hTreeView
,
464 (void)TreeView_SortChildren(hTreeView
,
468 (void)TreeView_SelectItem(hTreeView
,
474 AddDeviceToTree(HWND hTreeView
,
479 TCHAR DevName
[MAX_DEV_LEN
];
480 TCHAR FriendlyName
[MAX_DEV_LEN
];
481 TCHAR ClassGuidString
[MAX_GUID_STRING_LEN
];
484 LPTSTR DeviceID
= NULL
;
488 ulLength
= MAX_GUID_STRING_LEN
* sizeof(TCHAR
);
489 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
495 if (cr
== CR_SUCCESS
)
497 pSetupGuidFromString(ClassGuidString
, &ClassGuid
);
499 if (bShowHidden
== FALSE
&&
500 (IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_LEGACYDRIVER
) ||
501 IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_VOLUME
)))
506 /* It's a device with no driver */
507 ClassGuid
= GUID_DEVCLASS_UNKNOWN
;
510 cr
= CM_Get_Device_ID(dnDevInst
,
514 if (cr
!= CR_SUCCESS
)
517 ulLength
= MAX_DEV_LEN
* sizeof(TCHAR
);
518 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
524 if (cr
!= CR_SUCCESS
)
526 ulLength
= MAX_DEV_LEN
* sizeof(TCHAR
);
527 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
533 if (cr
!= CR_SUCCESS
)
537 if (!SetupDiGetClassImageIndex(&ImageListData
,
541 /* FIXME: can we do this?
542 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
543 * it'll be image 24 in the imagelist */
549 DeviceID
= HeapAlloc(GetProcessHeap(),
551 (lstrlen(DevName
) + 1) * sizeof(TCHAR
));
552 if (DeviceID
== NULL
)
557 lstrcpy(DeviceID
, DevName
);
560 return InsertIntoTreeView(hTreeView
,
570 EnumChildDevices(HWND hTreeView
,
572 DEVINST dnParentDevInst
,
579 cr
= CM_Get_Child(&dnDevInst
,
582 if (cr
!= CR_SUCCESS
)
585 hDevItem
= AddDeviceToTree(hTreeView
,
589 if (hDevItem
!= NULL
)
591 EnumChildDevices(hTreeView
,
597 while (cr
== CR_SUCCESS
)
599 cr
= CM_Get_Sibling(&dnDevInst
,
602 if (cr
!= CR_SUCCESS
)
605 hDevItem
= AddDeviceToTree(hTreeView
,
609 if (hDevItem
!= NULL
)
611 EnumChildDevices(hTreeView
,
618 (void)TreeView_SortChildren(hTreeView
,
625 ListDevicesByConnection(HWND hTreeView
,
632 cr
= CM_Locate_DevNode(&devInst
,
634 CM_LOCATE_DEVNODE_NORMAL
);
635 if (cr
== CR_SUCCESS
)
636 EnumChildDevices(hTreeView
,
641 (void)TreeView_Expand(hTreeView
,
645 (void)TreeView_SelectItem(hTreeView
,
651 InitTreeView(HWND hTreeView
)
654 TCHAR ComputerName
[MAX_PATH
];
655 DWORD dwSize
= MAX_PATH
;
658 (void)TreeView_DeleteAllItems(hTreeView
);
660 /* Get the device image list */
661 ImageListData
.cbSize
= sizeof(ImageListData
);
662 SetupDiGetClassImageList(&ImageListData
);
664 (void)TreeView_SetImageList(hTreeView
,
665 ImageListData
.ImageList
,
668 if (!GetComputerName(ComputerName
,
671 ComputerName
[0] = _T('\0');
674 /* Get the image index of the computer class */
675 SetupDiGetClassImageIndex(&ImageListData
,
676 &GUID_DEVCLASS_COMPUTER
,
679 /* Insert the root item into the tree */
680 hRoot
= InsertIntoTreeView(hTreeView
,