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>
12 static SP_CLASSIMAGELIST_DATA ImageListData
;
13 static HDEVINFO hDevInfo
;
15 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
18 FreeDeviceStrings(HWND hTreeView
)
22 hItem
= TreeView_GetRoot(hTreeView
);
26 hItem
= TreeView_GetChild(hTreeView
,
28 /* loop the parent items */
31 hItem
= TreeView_GetChild(hTreeView
,
36 /* loop the child items and free the DeviceID */
44 tvItem
.mask
= TVIF_PARAM
;// | TVIF_TEXT;
45 //tvItem.pszText = Buf;
46 //tvItem.cchTextMax = 99;
48 (void)TreeView_GetItem(hTreeView
, &tvItem
);
50 //MessageBox(NULL, Buf, NULL, 0);
52 HeapFree(GetProcessHeap(),
54 (LPTSTR
)tvItem
.lParam
);
58 hItem
= TreeView_GetNextSibling(hTreeView
,
67 hItem
= TreeView_GetParent(hTreeView
,
69 hItem
= TreeView_GetNextSibling(hTreeView
,
77 OpenPropSheet(HWND hTreeView
,
83 tvItem
.mask
= TVIF_PARAM
;
85 if (TreeView_GetItem(hTreeView
, &tvItem
) &&
86 (LPTSTR
)tvItem
.lParam
!= NULL
)
88 DevicePropertiesExW(hTreeView
,
90 (LPTSTR
)tvItem
.lParam
,
99 InsertIntoTreeView(HWND hTreeView
,
107 TV_INSERTSTRUCT tvins
;
109 ZeroMemory(&tvi
, sizeof(tvi
));
110 ZeroMemory(&tvins
, sizeof(tvins
));
112 tvi
.mask
= TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
113 tvi
.pszText
= lpLabel
;
114 tvi
.cchTextMax
= lstrlen(lpLabel
);
115 tvi
.lParam
= (LPARAM
)DeviceID
;
116 tvi
.iImage
= DevImage
;
117 tvi
.iSelectedImage
= DevImage
;
121 tvi
.stateMask
= TVIS_OVERLAYMASK
;
123 if (DevProb
== CM_PROB_DISABLED
)
125 /* FIXME: set the overlay icon */
131 tvins
.hParent
= hRoot
;
133 return TreeView_InsertItem(hTreeView
, &tvins
);
138 EnumDeviceClasses(INT ClassIndex
,
149 TCHAR ClassName
[MAX_CLASS_NAME_LEN
];
150 DWORD RequiredSize
= MAX_CLASS_NAME_LEN
;
154 *DevClassName
= _T('\0');
157 Ret
= CM_Enumerate_Classes(ClassIndex
,
160 if (Ret
!= CR_SUCCESS
)
162 /* all classes enumerated */
163 if(Ret
== CR_NO_SUCH_VALUE
)
168 if (Ret
== CR_INVALID_DATA
)
170 ; /*FIXME: what should we do here? */
173 /* handle other errors... */
176 /* This case is special because these devices don't show up with normal class enumeration */
177 *IsUnknown
= IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_UNKNOWN
);
179 if (ShowHidden
== FALSE
&&
180 (IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_LEGACYDRIVER
) ||
181 IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_VOLUME
)))
184 if (SetupDiClassNameFromGuid(&ClassGuid
,
189 lstrcpy(DevClassName
, ClassName
);
192 if (!SetupDiGetClassImageIndex(&ImageListData
,
196 /* FIXME: can we do this?
197 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
198 * it'll be image 24 in the imagelist */
202 /* Get device info for all devices of a particular class */
203 hDevInfo
= SetupDiGetClassDevs(*IsUnknown
? NULL
: &ClassGuid
,
206 DIGCF_PRESENT
| (*IsUnknown
? DIGCF_ALLCLASSES
: 0));
207 if (hDevInfo
== INVALID_HANDLE_VALUE
)
212 KeyClass
= SetupDiOpenClassRegKeyEx(&ClassGuid
,
217 if (KeyClass
!= INVALID_HANDLE_VALUE
)
220 LONG dwSize
= MAX_DEV_LEN
;
222 if (RegQueryValue(KeyClass
,
225 &dwSize
) != ERROR_SUCCESS
)
227 *DevClassDesc
= _T('\0');
237 RegCloseKey(KeyClass
);
244 EnumDevices(INT index
,
245 LPTSTR DeviceClassName
,
249 SP_DEVINFO_DATA DeviceInfoData
;
251 ULONG Status
, ProblemNumber
;
254 *DeviceName
= _T('\0');
257 ZeroMemory(&DeviceInfoData
, sizeof(SP_DEVINFO_DATA
));
258 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
260 if (!SetupDiEnumDeviceInfo(hDevInfo
,
268 if (DeviceClassName
== NULL
&& !IsEqualGUID(&DeviceInfoData
.ClassGuid
, &GUID_NULL
))
270 /* we're looking for unknown devices and this isn't one */
274 /* get the device ID */
275 if (!SetupDiGetDeviceInstanceId(hDevInfo
,
281 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
283 (*DeviceID
) = (LPTSTR
)HeapAlloc(GetProcessHeap(),
285 DevIdSize
* sizeof(TCHAR
));
288 if (!SetupDiGetDeviceInstanceId(hDevInfo
,
294 HeapFree(GetProcessHeap(),
303 if (DeviceID
!= NULL
&&
304 _tcscmp(*DeviceID
, _T("HTREE\\ROOT\\0")) == 0)
306 HeapFree(GetProcessHeap(),
313 /* get the device's friendly name */
314 if (!SetupDiGetDeviceRegistryProperty(hDevInfo
,
322 /* if the friendly name fails, try the description instead */
323 SetupDiGetDeviceRegistryProperty(hDevInfo
,
332 cr
= CM_Get_DevNode_Status_Ex(&Status
,
334 DeviceInfoData
.DevInst
,
337 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
339 return ProblemNumber
;
347 ListDevicesByType(HWND hTreeView
,
352 TCHAR DevName
[MAX_DEV_LEN
];
353 TCHAR DevDesc
[MAX_DEV_LEN
];
354 LPTSTR DeviceID
= NULL
;
355 BOOL DevExist
= FALSE
;
359 BOOL IsUnknown
= FALSE
;
360 BOOL IsHidden
= FALSE
;
364 ClassRet
= EnumDeviceClasses(index
,
373 if ((ClassRet
!= -1) && (DevExist
) && !IsHidden
)
375 TCHAR DeviceName
[MAX_DEV_LEN
];
379 if (DevDesc
[0] != _T('\0'))
381 hDevItem
= InsertIntoTreeView(hTreeView
,
390 hDevItem
= InsertIntoTreeView(hTreeView
,
400 Ret
= EnumDevices(DevIndex
,
401 IsUnknown
? NULL
: DevName
,
406 InsertIntoTreeView(hTreeView
,
414 /* Expand the class if the device has a problem */
415 (void)TreeView_Expand(hTreeView
,
425 /* kill InfoList initialized in EnumDeviceClasses */
428 SetupDiDestroyDeviceInfoList(hDevInfo
);
432 /* don't insert classes with no devices */
433 if (!TreeView_GetChild(hTreeView
,
436 (void)TreeView_DeleteItem(hTreeView
,
441 (void)TreeView_SortChildren(hTreeView
,
449 } while (ClassRet
!= -1);
451 (void)TreeView_Expand(hTreeView
,
455 (void)TreeView_SortChildren(hTreeView
,
459 (void)TreeView_SelectItem(hTreeView
,
465 AddDeviceToTree(HWND hTreeView
,
470 TCHAR DevName
[MAX_DEV_LEN
];
471 TCHAR FriendlyName
[MAX_DEV_LEN
];
472 TCHAR ClassGuidString
[MAX_GUID_STRING_LEN
];
475 LPTSTR DeviceID
= NULL
;
479 ulLength
= MAX_GUID_STRING_LEN
* sizeof(TCHAR
);
480 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
486 if (cr
== CR_SUCCESS
)
488 pSetupGuidFromString(ClassGuidString
, &ClassGuid
);
490 if (bShowHidden
== FALSE
&&
491 (IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_LEGACYDRIVER
) ||
492 IsEqualGUID(&ClassGuid
, &GUID_DEVCLASS_VOLUME
)))
497 /* It's a device with no driver */
498 ClassGuid
= GUID_DEVCLASS_UNKNOWN
;
501 cr
= CM_Get_Device_ID(dnDevInst
,
505 if (cr
!= CR_SUCCESS
)
508 ulLength
= MAX_DEV_LEN
* sizeof(TCHAR
);
509 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
515 if (cr
!= CR_SUCCESS
)
517 ulLength
= MAX_DEV_LEN
* sizeof(TCHAR
);
518 cr
= CM_Get_DevNode_Registry_Property(dnDevInst
,
524 if (cr
!= CR_SUCCESS
)
528 if (!SetupDiGetClassImageIndex(&ImageListData
,
532 /* FIXME: can we do this?
533 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
534 * it'll be image 24 in the imagelist */
540 DeviceID
= HeapAlloc(GetProcessHeap(),
542 (lstrlen(DevName
) + 1) * sizeof(TCHAR
));
543 if (DeviceID
== NULL
)
548 lstrcpy(DeviceID
, DevName
);
551 return InsertIntoTreeView(hTreeView
,
561 EnumChildDevices(HWND hTreeView
,
563 DEVINST dnParentDevInst
,
570 cr
= CM_Get_Child(&dnDevInst
,
573 if (cr
!= CR_SUCCESS
)
576 hDevItem
= AddDeviceToTree(hTreeView
,
580 if (hDevItem
!= NULL
)
582 EnumChildDevices(hTreeView
,
588 while (cr
== CR_SUCCESS
)
590 cr
= CM_Get_Sibling(&dnDevInst
,
593 if (cr
!= CR_SUCCESS
)
596 hDevItem
= AddDeviceToTree(hTreeView
,
600 if (hDevItem
!= NULL
)
602 EnumChildDevices(hTreeView
,
609 (void)TreeView_SortChildren(hTreeView
,
616 ListDevicesByConnection(HWND hTreeView
,
623 cr
= CM_Locate_DevNode(&devInst
,
625 CM_LOCATE_DEVNODE_NORMAL
);
626 if (cr
== CR_SUCCESS
)
627 EnumChildDevices(hTreeView
,
632 (void)TreeView_Expand(hTreeView
,
636 (void)TreeView_SelectItem(hTreeView
,
642 InitTreeView(HWND hTreeView
)
646 TCHAR ComputerName
[MAX_PATH
];
647 DWORD dwSize
= MAX_PATH
;
650 (void)TreeView_DeleteAllItems(hTreeView
);
652 /* get the device image List */
653 ImageListData
.cbSize
= sizeof(ImageListData
);
654 SetupDiGetClassImageList(&ImageListData
);
656 hComp
= LoadBitmap(hInstance
,
657 MAKEINTRESOURCE(IDB_ROOT_IMAGE
));
659 ImageList_Add(ImageListData
.ImageList
,
665 (void)TreeView_SetImageList(hTreeView
,
666 ImageListData
.ImageList
,
669 if (!GetComputerName(ComputerName
,
672 ComputerName
[0] = _T('\0');
675 RootImage
= ImageList_GetImageCount(ImageListData
.ImageList
) - 1;
677 /* insert the root item into the tree */
678 hRoot
= InsertIntoTreeView(hTreeView
,