2 * PROJECT: ReactOS Device Managment
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/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
;
18 static HDEVINFO hDevInfo
;
20 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
23 FreeDeviceStrings(HWND hTreeView
)
27 hItem
= TreeView_GetRoot(hTreeView
);
31 hItem
= TreeView_GetChild(hTreeView
,
33 /* loop the parent items */
36 hItem
= TreeView_GetChild(hTreeView
,
41 /* loop the child items and free the DeviceID */
49 tvItem
.mask
= TVIF_PARAM
;// | TVIF_TEXT;
50 //tvItem.pszText = Buf;
51 //tvItem.cchTextMax = 99;
53 (void)TreeView_GetItem(hTreeView
, &tvItem
);
55 //MessageBox(NULL, Buf, NULL, 0);
57 HeapFree(GetProcessHeap(),
59 (LPTSTR
)tvItem
.lParam
);
63 hItem
= TreeView_GetNextSibling(hTreeView
,
72 hItem
= TreeView_GetParent(hTreeView
,
74 hItem
= TreeView_GetNextSibling(hTreeView
,
82 OpenPropSheet(HWND hTreeView
,
88 tvItem
.mask
= TVIF_PARAM
;
90 if (TreeView_GetItem(hTreeView
, &tvItem
) &&
91 (LPTSTR
)tvItem
.lParam
!= NULL
)
93 DevicePropertiesExW(hTreeView
,
95 (LPTSTR
)tvItem
.lParam
,
104 InsertIntoTreeView(HWND hTreeView
,
112 TV_INSERTSTRUCT tvins
;
114 ZeroMemory(&tvi
, sizeof(tvi
));
115 ZeroMemory(&tvins
, sizeof(tvins
));
117 tvi
.mask
= TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
118 tvi
.pszText
= lpLabel
;
119 tvi
.cchTextMax
= lstrlen(lpLabel
);
120 tvi
.lParam
= (LPARAM
)DeviceID
;
121 tvi
.iImage
= DevImage
;
122 tvi
.iSelectedImage
= DevImage
;
126 tvi
.stateMask
= TVIS_OVERLAYMASK
;
128 if (DevProb
== CM_PROB_DISABLED
)
130 /* FIXME: set the overlay icon */
136 tvins
.hParent
= hRoot
;
138 return TreeView_InsertItem(hTreeView
, &tvins
);
143 EnumDeviceClasses(INT ClassIndex
,
154 TCHAR ClassName
[MAX_CLASS_NAME_LEN
];
155 DWORD RequiredSize
= MAX_CLASS_NAME_LEN
;
159 *DevClassName
= _T('\0');
162 Ret
= CM_Enumerate_Classes(ClassIndex
,
165 if (Ret
!= CR_SUCCESS
)
167 /* all classes enumerated */
168 if(Ret
== CR_NO_SUCH_VALUE
)
173 if (Ret
== CR_INVALID_DATA
)
175 ; /*FIXME: what should we do here? */
178 /* handle other errors... */
181 /* This case is special because these devices don't show up with normal class enumeration */
182 *IsUnknown
= IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_UNKNOWN
);
184 if (ShowHidden
== FALSE
&&
185 (IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_LEGACYDRIVER
) ||
186 IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_VOLUME
)))
189 if (SetupDiClassNameFromGuid(&ClassGuid
,
194 lstrcpy(DevClassName
, ClassName
);
197 if (!SetupDiGetClassImageIndex(&ImageListData
,
201 /* FIXME: can we do this?
202 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
203 * it'll be image 24 in the imagelist */
207 /* Get device info for all devices of a particular class */
208 hDevInfo
= SetupDiGetClassDevs(*IsUnknown
? NULL
: &ClassGuid
,
211 DIGCF_PRESENT
| (*IsUnknown
? DIGCF_ALLCLASSES
: 0));
212 if (hDevInfo
== INVALID_HANDLE_VALUE
)
217 KeyClass
= SetupDiOpenClassRegKeyEx(&ClassGuid
,
222 if (KeyClass
!= INVALID_HANDLE_VALUE
)
225 LONG dwSize
= MAX_DEV_LEN
;
227 if (RegQueryValue(KeyClass
,
230 &dwSize
) != ERROR_SUCCESS
)
232 *DevClassDesc
= _T('\0');
242 RegCloseKey(KeyClass
);
249 EnumDevices(INT index
,
250 LPTSTR DeviceClassName
,
254 SP_DEVINFO_DATA DeviceInfoData
;
256 ULONG Status
, ProblemNumber
;
259 *DeviceName
= _T('\0');
262 ZeroMemory(&DeviceInfoData
, sizeof(SP_DEVINFO_DATA
));
263 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
265 if (!SetupDiEnumDeviceInfo(hDevInfo
,
273 if (DeviceClassName
== NULL
&& !IsEqualGUID(&DeviceInfoData
.ClassGuid
, &GUID_NULL
))
275 /* we're looking for unknown devices and this isn't one */
279 /* get the device ID */
280 if (!SetupDiGetDeviceInstanceId(hDevInfo
,
286 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
288 (*DeviceID
) = (LPTSTR
)HeapAlloc(GetProcessHeap(),
290 DevIdSize
* sizeof(TCHAR
));
293 if (!SetupDiGetDeviceInstanceId(hDevInfo
,
299 HeapFree(GetProcessHeap(),
308 if (DeviceID
!= NULL
&&
309 _tcscmp(*DeviceID
, _T("HTREE\\ROOT\\0")) == 0)
311 HeapFree(GetProcessHeap(),
318 /* get the device's friendly name */
319 if (!SetupDiGetDeviceRegistryProperty(hDevInfo
,
327 /* if the friendly name fails, try the description instead */
328 SetupDiGetDeviceRegistryProperty(hDevInfo
,
337 cr
= CM_Get_DevNode_Status_Ex(&Status
,
339 DeviceInfoData
.DevInst
,
342 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
344 return ProblemNumber
;
352 ListDevicesByType(HWND hTreeView
,
357 TCHAR DevName
[MAX_DEV_LEN
];
358 TCHAR DevDesc
[MAX_DEV_LEN
];
359 LPTSTR DeviceID
= NULL
;
360 BOOL DevExist
= FALSE
;
364 BOOL IsUnknown
= FALSE
;
365 BOOL IsHidden
= FALSE
;
369 ClassRet
= EnumDeviceClasses(index
,
378 if ((ClassRet
!= -1) && (DevExist
) && !IsHidden
)
380 TCHAR DeviceName
[MAX_DEV_LEN
];
384 if (DevDesc
[0] != _T('\0'))
386 hDevItem
= InsertIntoTreeView(hTreeView
,
395 hDevItem
= InsertIntoTreeView(hTreeView
,
405 Ret
= EnumDevices(DevIndex
,
406 IsUnknown
? NULL
: DevName
,
411 InsertIntoTreeView(hTreeView
,
419 /* Expand the class if the device has a problem */
420 (void)TreeView_Expand(hTreeView
,
430 /* kill InfoList initialized in EnumDeviceClasses */
433 SetupDiDestroyDeviceInfoList(hDevInfo
);
437 /* don't insert classes with no devices */
438 if (!TreeView_GetChild(hTreeView
,
441 (void)TreeView_DeleteItem(hTreeView
,
446 (void)TreeView_SortChildren(hTreeView
,
454 } while (ClassRet
!= -1);
456 (void)TreeView_Expand(hTreeView
,
460 (void)TreeView_SortChildren(hTreeView
,
464 (void)TreeView_SelectItem(hTreeView
,
470 AddDeviceToTree(HWND hTreeView
,
475 TCHAR DevName
[MAX_DEV_LEN
];
476 TCHAR FriendlyName
[MAX_DEV_LEN
];
477 TCHAR ClassGuidString
[MAX_GUID_STRING_LEN
];
480 LPTSTR DeviceID
= NULL
;
484 ulLength
= MAX_GUID_STRING_LEN
* sizeof(TCHAR
);
485 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
491 if (cr
== CR_SUCCESS
)
493 pSetupGuidFromString(ClassGuidString
, &ClassGuid
);
495 if (bShowHidden
== FALSE
&&
496 (IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_LEGACYDRIVER
) ||
497 IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_VOLUME
)))
502 /* It's a device with no driver */
503 ClassGuid
= GUID_DEVCLASS_UNKNOWN
;
506 cr
= CM_Get_Device_ID(dnDevInst
,
510 if (cr
!= CR_SUCCESS
)
513 ulLength
= MAX_DEV_LEN
* sizeof(TCHAR
);
514 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
520 if (cr
!= CR_SUCCESS
)
522 ulLength
= MAX_DEV_LEN
* sizeof(TCHAR
);
523 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
529 if (cr
!= CR_SUCCESS
)
533 if (!SetupDiGetClassImageIndex(&ImageListData
,
537 /* FIXME: can we do this?
538 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
539 * it'll be image 24 in the imagelist */
545 DeviceID
= HeapAlloc(GetProcessHeap(),
547 (lstrlen(DevName
) + 1) * sizeof(TCHAR
));
548 if (DeviceID
== NULL
)
553 lstrcpy(DeviceID
, DevName
);
556 return InsertIntoTreeView(hTreeView
,
566 EnumChildDevices(HWND hTreeView
,
568 DEVINST dnParentDevInst
,
575 cr
= CM_Get_Child(&dnDevInst
,
578 if (cr
!= CR_SUCCESS
)
581 hDevItem
= AddDeviceToTree(hTreeView
,
585 if (hDevItem
!= NULL
)
587 EnumChildDevices(hTreeView
,
593 while (cr
== CR_SUCCESS
)
595 cr
= CM_Get_Sibling(&dnDevInst
,
598 if (cr
!= CR_SUCCESS
)
601 hDevItem
= AddDeviceToTree(hTreeView
,
605 if (hDevItem
!= NULL
)
607 EnumChildDevices(hTreeView
,
614 (void)TreeView_SortChildren(hTreeView
,
621 ListDevicesByConnection(HWND hTreeView
,
628 cr
= CM_Locate_DevNode(&devInst
,
630 CM_LOCATE_DEVNODE_NORMAL
);
631 if (cr
== CR_SUCCESS
)
632 EnumChildDevices(hTreeView
,
637 (void)TreeView_Expand(hTreeView
,
641 (void)TreeView_SelectItem(hTreeView
,
647 InitTreeView(HWND hTreeView
)
651 TCHAR ComputerName
[MAX_PATH
];
652 DWORD dwSize
= MAX_PATH
;
655 (void)TreeView_DeleteAllItems(hTreeView
);
657 /* get the device image List */
658 ImageListData
.cbSize
= sizeof(ImageListData
);
659 SetupDiGetClassImageList(&ImageListData
);
661 hComp
= LoadBitmap(hInstance
,
662 MAKEINTRESOURCE(IDB_ROOT_IMAGE
));
664 ImageList_Add(ImageListData
.ImageList
,
670 (void)TreeView_SetImageList(hTreeView
,
671 ImageListData
.ImageList
,
674 if (!GetComputerName(ComputerName
,
677 ComputerName
[0] = _T('\0');
680 RootImage
= ImageList_GetImageCount(ImageListData
.ImageList
) - 1;
682 /* insert the root item into the tree */
683 hRoot
= InsertIntoTreeView(hTreeView
,