Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenenumdevices.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Device Managment 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: base/system/devmgmt/enumdevices.c 00005 * PURPOSE: Enumerates all devices on the local machine 00006 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com> 00007 * 00008 */ 00009 00010 #include "precomp.h" 00011 00012 static SP_CLASSIMAGELIST_DATA ImageListData; 00013 static HDEVINFO hDevInfo; 00014 00015 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 00016 00017 VOID 00018 FreeDeviceStrings(HWND hTreeView) 00019 { 00020 HTREEITEM hItem; 00021 00022 hItem = TreeView_GetRoot(hTreeView); 00023 00024 if (hItem) 00025 { 00026 hItem = TreeView_GetChild(hTreeView, 00027 hItem); 00028 /* loop the parent items */ 00029 while (hItem) 00030 { 00031 hItem = TreeView_GetChild(hTreeView, 00032 hItem); 00033 if (hItem == NULL) 00034 break; 00035 00036 /* loop the child items and free the DeviceID */ 00037 while (TRUE) 00038 { 00039 HTREEITEM hOldItem; 00040 TV_ITEM tvItem; 00041 //TCHAR Buf[100]; 00042 00043 tvItem.hItem = hItem; 00044 tvItem.mask = TVIF_PARAM;// | TVIF_TEXT; 00045 //tvItem.pszText = Buf; 00046 //tvItem.cchTextMax = 99; 00047 00048 (void)TreeView_GetItem(hTreeView, &tvItem); 00049 00050 //MessageBox(NULL, Buf, NULL, 0); 00051 00052 HeapFree(GetProcessHeap(), 00053 0, 00054 (LPTSTR)tvItem.lParam); 00055 00056 hOldItem = hItem; 00057 00058 hItem = TreeView_GetNextSibling(hTreeView, 00059 hItem); 00060 if (hItem == NULL) 00061 { 00062 hItem = hOldItem; 00063 break; 00064 } 00065 } 00066 00067 hItem = TreeView_GetParent(hTreeView, 00068 hItem); 00069 hItem = TreeView_GetNextSibling(hTreeView, 00070 hItem); 00071 } 00072 } 00073 } 00074 00075 00076 VOID 00077 OpenPropSheet(HWND hTreeView, 00078 HTREEITEM hItem) 00079 { 00080 TV_ITEM tvItem; 00081 00082 tvItem.hItem = hItem; 00083 tvItem.mask = TVIF_PARAM; 00084 00085 if (TreeView_GetItem(hTreeView, &tvItem) && 00086 (LPTSTR)tvItem.lParam != NULL) 00087 { 00088 DevicePropertiesExW(hTreeView, 00089 NULL, 00090 (LPTSTR)tvItem.lParam, 00091 DPF_EXTENDED, 00092 FALSE); 00093 } 00094 00095 } 00096 00097 00098 static HTREEITEM 00099 InsertIntoTreeView(HWND hTreeView, 00100 HTREEITEM hRoot, 00101 LPTSTR lpLabel, 00102 LPTSTR DeviceID, 00103 INT DevImage, 00104 LONG DevProb) 00105 { 00106 TV_ITEM tvi; 00107 TV_INSERTSTRUCT tvins; 00108 00109 ZeroMemory(&tvi, sizeof(tvi)); 00110 ZeroMemory(&tvins, sizeof(tvins)); 00111 00112 tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; 00113 tvi.pszText = lpLabel; 00114 tvi.cchTextMax = lstrlen(lpLabel); 00115 tvi.lParam = (LPARAM)DeviceID; 00116 tvi.iImage = DevImage; 00117 tvi.iSelectedImage = DevImage; 00118 00119 if (DevProb != 0) 00120 { 00121 tvi.stateMask = TVIS_OVERLAYMASK; 00122 00123 if (DevProb == CM_PROB_DISABLED) 00124 { 00125 /* FIXME: set the overlay icon */ 00126 } 00127 00128 } 00129 00130 tvins.item = tvi; 00131 tvins.hParent = hRoot; 00132 00133 return TreeView_InsertItem(hTreeView, &tvins); 00134 } 00135 00136 00137 static INT 00138 EnumDeviceClasses(INT ClassIndex, 00139 BOOL ShowHidden, 00140 LPTSTR DevClassName, 00141 LPTSTR DevClassDesc, 00142 BOOL *DevPresent, 00143 INT *ClassImage, 00144 BOOL *IsUnknown, 00145 BOOL *IsHidden) 00146 { 00147 GUID ClassGuid; 00148 HKEY KeyClass; 00149 TCHAR ClassName[MAX_CLASS_NAME_LEN]; 00150 DWORD RequiredSize = MAX_CLASS_NAME_LEN; 00151 UINT Ret; 00152 00153 *DevPresent = FALSE; 00154 *DevClassName = _T('\0'); 00155 *IsHidden = FALSE; 00156 00157 Ret = CM_Enumerate_Classes(ClassIndex, 00158 &ClassGuid, 00159 0); 00160 if (Ret != CR_SUCCESS) 00161 { 00162 /* all classes enumerated */ 00163 if(Ret == CR_NO_SUCH_VALUE) 00164 { 00165 return -1; 00166 } 00167 00168 if (Ret == CR_INVALID_DATA) 00169 { 00170 ; /*FIXME: what should we do here? */ 00171 } 00172 00173 /* handle other errors... */ 00174 } 00175 00176 /* This case is special because these devices don't show up with normal class enumeration */ 00177 *IsUnknown = IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_UNKNOWN); 00178 00179 if (ShowHidden == FALSE && 00180 (IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_LEGACYDRIVER) || 00181 IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_VOLUME))) 00182 *IsHidden = TRUE; 00183 00184 if (SetupDiClassNameFromGuid(&ClassGuid, 00185 ClassName, 00186 RequiredSize, 00187 &RequiredSize)) 00188 { 00189 lstrcpy(DevClassName, ClassName); 00190 } 00191 00192 if (!SetupDiGetClassImageIndex(&ImageListData, 00193 &ClassGuid, 00194 ClassImage)) 00195 { 00196 /* FIXME: can we do this? 00197 * Set the blank icon: IDI_SETUPAPI_BLANK = 41 00198 * it'll be image 24 in the imagelist */ 00199 *ClassImage = 24; 00200 } 00201 00202 /* Get device info for all devices of a particular class */ 00203 hDevInfo = SetupDiGetClassDevs(*IsUnknown ? NULL : &ClassGuid, 00204 NULL, 00205 NULL, 00206 DIGCF_PRESENT | (*IsUnknown ? DIGCF_ALLCLASSES : 0)); 00207 if (hDevInfo == INVALID_HANDLE_VALUE) 00208 { 00209 return 0; 00210 } 00211 00212 KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, 00213 MAXIMUM_ALLOWED, 00214 DIOCR_INSTALLER, 00215 NULL, 00216 0); 00217 if (KeyClass != INVALID_HANDLE_VALUE) 00218 { 00219 00220 LONG dwSize = MAX_DEV_LEN; 00221 00222 if (RegQueryValue(KeyClass, 00223 NULL, 00224 DevClassDesc, 00225 &dwSize) != ERROR_SUCCESS) 00226 { 00227 *DevClassDesc = _T('\0'); 00228 } 00229 } 00230 else 00231 { 00232 return 0; 00233 } 00234 00235 *DevPresent = TRUE; 00236 00237 RegCloseKey(KeyClass); 00238 00239 return 0; 00240 } 00241 00242 00243 static LONG 00244 EnumDevices(INT index, 00245 LPTSTR DeviceClassName, 00246 LPTSTR DeviceName, 00247 LPTSTR *DeviceID) 00248 { 00249 SP_DEVINFO_DATA DeviceInfoData; 00250 CONFIGRET cr; 00251 ULONG Status, ProblemNumber; 00252 DWORD DevIdSize; 00253 00254 *DeviceName = _T('\0'); 00255 *DeviceID = NULL; 00256 00257 ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); 00258 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 00259 00260 if (!SetupDiEnumDeviceInfo(hDevInfo, 00261 index, 00262 &DeviceInfoData)) 00263 { 00264 /* no such device */ 00265 return -1; 00266 } 00267 00268 if (DeviceClassName == NULL && !IsEqualGUID(&DeviceInfoData.ClassGuid, &GUID_NULL)) 00269 { 00270 /* we're looking for unknown devices and this isn't one */ 00271 return -2; 00272 } 00273 00274 /* get the device ID */ 00275 if (!SetupDiGetDeviceInstanceId(hDevInfo, 00276 &DeviceInfoData, 00277 NULL, 00278 0, 00279 &DevIdSize)) 00280 { 00281 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 00282 { 00283 (*DeviceID) = (LPTSTR)HeapAlloc(GetProcessHeap(), 00284 0, 00285 DevIdSize * sizeof(TCHAR)); 00286 if (*DeviceID) 00287 { 00288 if (!SetupDiGetDeviceInstanceId(hDevInfo, 00289 &DeviceInfoData, 00290 *DeviceID, 00291 DevIdSize, 00292 NULL)) 00293 { 00294 HeapFree(GetProcessHeap(), 00295 0, 00296 *DeviceID); 00297 *DeviceID = NULL; 00298 } 00299 } 00300 } 00301 } 00302 00303 /* get the device's friendly name */ 00304 if (!SetupDiGetDeviceRegistryProperty(hDevInfo, 00305 &DeviceInfoData, 00306 SPDRP_FRIENDLYNAME, 00307 0, 00308 (BYTE*)DeviceName, 00309 MAX_DEV_LEN, 00310 NULL)) 00311 { 00312 /* if the friendly name fails, try the description instead */ 00313 SetupDiGetDeviceRegistryProperty(hDevInfo, 00314 &DeviceInfoData, 00315 SPDRP_DEVICEDESC, 00316 0, 00317 (BYTE*)DeviceName, 00318 MAX_DEV_LEN, 00319 NULL); 00320 } 00321 00322 cr = CM_Get_DevNode_Status_Ex(&Status, 00323 &ProblemNumber, 00324 DeviceInfoData.DevInst, 00325 0, 00326 NULL); 00327 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM)) 00328 { 00329 return ProblemNumber; 00330 } 00331 00332 return 0; 00333 } 00334 00335 00336 VOID 00337 ListDevicesByType(HWND hTreeView, 00338 HTREEITEM hRoot, 00339 BOOL bShowHidden) 00340 { 00341 HTREEITEM hDevItem; 00342 TCHAR DevName[MAX_DEV_LEN]; 00343 TCHAR DevDesc[MAX_DEV_LEN]; 00344 LPTSTR DeviceID = NULL; 00345 BOOL DevExist = FALSE; 00346 INT ClassRet; 00347 INT index = 0; 00348 INT DevImage; 00349 BOOL IsUnknown = FALSE; 00350 BOOL IsHidden = FALSE; 00351 00352 do 00353 { 00354 ClassRet = EnumDeviceClasses(index, 00355 bShowHidden, 00356 DevName, 00357 DevDesc, 00358 &DevExist, 00359 &DevImage, 00360 &IsUnknown, 00361 &IsHidden); 00362 00363 if ((ClassRet != -1) && (DevExist) && !IsHidden) 00364 { 00365 TCHAR DeviceName[MAX_DEV_LEN]; 00366 INT DevIndex = 0; 00367 LONG Ret; 00368 00369 if (DevDesc[0] != _T('\0')) 00370 { 00371 hDevItem = InsertIntoTreeView(hTreeView, 00372 hRoot, 00373 DevDesc, 00374 NULL, 00375 DevImage, 00376 0); 00377 } 00378 else 00379 { 00380 hDevItem = InsertIntoTreeView(hTreeView, 00381 hRoot, 00382 DevName, 00383 NULL, 00384 DevImage, 00385 0); 00386 } 00387 00388 do 00389 { 00390 Ret = EnumDevices(DevIndex, 00391 IsUnknown ? NULL : DevName, 00392 DeviceName, 00393 &DeviceID); 00394 if (Ret >= 0) 00395 { 00396 InsertIntoTreeView(hTreeView, 00397 hDevItem, 00398 DeviceName, 00399 DeviceID, 00400 DevImage, 00401 Ret); 00402 if (Ret != 0) 00403 { 00404 /* Expand the class if the device has a problem */ 00405 (void)TreeView_Expand(hTreeView, 00406 hDevItem, 00407 TVE_EXPAND); 00408 } 00409 } 00410 00411 DevIndex++; 00412 00413 } while (Ret != -1); 00414 00415 /* kill InfoList initialized in EnumDeviceClasses */ 00416 if (hDevInfo) 00417 { 00418 SetupDiDestroyDeviceInfoList(hDevInfo); 00419 hDevInfo = NULL; 00420 } 00421 00422 /* don't insert classes with no devices */ 00423 if (!TreeView_GetChild(hTreeView, 00424 hDevItem)) 00425 { 00426 (void)TreeView_DeleteItem(hTreeView, 00427 hDevItem); 00428 } 00429 else 00430 { 00431 (void)TreeView_SortChildren(hTreeView, 00432 hDevItem, 00433 0); 00434 } 00435 } 00436 00437 index++; 00438 00439 } while (ClassRet != -1); 00440 00441 (void)TreeView_Expand(hTreeView, 00442 hRoot, 00443 TVE_EXPAND); 00444 00445 (void)TreeView_SortChildren(hTreeView, 00446 hRoot, 00447 0); 00448 00449 (void)TreeView_SelectItem(hTreeView, 00450 hRoot); 00451 } 00452 00453 00454 static HTREEITEM 00455 AddDeviceToTree(HWND hTreeView, 00456 HTREEITEM hRoot, 00457 DEVINST dnDevInst, 00458 BOOL bShowHidden) 00459 { 00460 TCHAR DevName[MAX_DEV_LEN]; 00461 TCHAR FriendlyName[MAX_DEV_LEN]; 00462 TCHAR ClassGuidString[MAX_GUID_STRING_LEN]; 00463 GUID ClassGuid; 00464 ULONG ulLength; 00465 LPTSTR DeviceID; 00466 INT ClassImage = 24; 00467 CONFIGRET cr; 00468 00469 ulLength = MAX_GUID_STRING_LEN * sizeof(TCHAR); 00470 cr = CM_Get_DevNode_Registry_Property(dnDevInst, 00471 CM_DRP_CLASSGUID, 00472 NULL, 00473 ClassGuidString, 00474 &ulLength, 00475 0); 00476 if (cr == CR_SUCCESS) 00477 { 00478 pSetupGuidFromString(ClassGuidString, &ClassGuid); 00479 00480 if (bShowHidden == FALSE && 00481 (IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_LEGACYDRIVER) || 00482 IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_VOLUME))) 00483 return NULL; 00484 } 00485 else 00486 { 00487 /* It's a device with no driver */ 00488 ClassGuid = GUID_DEVCLASS_UNKNOWN; 00489 } 00490 00491 cr = CM_Get_Device_ID(dnDevInst, 00492 DevName, 00493 MAX_DEV_LEN, 00494 0); 00495 if (cr != CR_SUCCESS) 00496 return NULL; 00497 00498 ulLength = MAX_DEV_LEN * sizeof(TCHAR); 00499 cr = CM_Get_DevNode_Registry_Property(dnDevInst, 00500 CM_DRP_FRIENDLYNAME, 00501 NULL, 00502 FriendlyName, 00503 &ulLength, 00504 0); 00505 if (cr != CR_SUCCESS) 00506 { 00507 ulLength = MAX_DEV_LEN * sizeof(TCHAR); 00508 cr = CM_Get_DevNode_Registry_Property(dnDevInst, 00509 CM_DRP_DEVICEDESC, 00510 NULL, 00511 FriendlyName, 00512 &ulLength, 00513 0); 00514 if (cr != CR_SUCCESS) 00515 return NULL; 00516 } 00517 00518 if (!SetupDiGetClassImageIndex(&ImageListData, 00519 &ClassGuid, 00520 &ClassImage)) 00521 { 00522 /* FIXME: can we do this? 00523 * Set the blank icon: IDI_SETUPAPI_BLANK = 41 00524 * it'll be image 24 in the imagelist */ 00525 ClassImage = 24; 00526 } 00527 00528 if (DevName != NULL) 00529 { 00530 DeviceID = HeapAlloc(GetProcessHeap(), 00531 0, 00532 (lstrlen(DevName) + 1) * sizeof(TCHAR)); 00533 if (DeviceID == NULL) 00534 { 00535 return NULL; 00536 } 00537 00538 lstrcpy(DeviceID, DevName); 00539 } 00540 00541 return InsertIntoTreeView(hTreeView, 00542 hRoot, 00543 FriendlyName, 00544 DeviceID, 00545 ClassImage, 00546 0); 00547 } 00548 00549 00550 static VOID 00551 EnumChildDevices(HWND hTreeView, 00552 HTREEITEM hRoot, 00553 DEVINST dnParentDevInst, 00554 BOOL bShowHidden) 00555 { 00556 HTREEITEM hDevItem; 00557 DEVINST dnDevInst; 00558 CONFIGRET cr; 00559 00560 cr = CM_Get_Child(&dnDevInst, 00561 dnParentDevInst, 00562 0); 00563 if (cr != CR_SUCCESS) 00564 return; 00565 00566 hDevItem = AddDeviceToTree(hTreeView, 00567 hRoot, 00568 dnDevInst, 00569 bShowHidden); 00570 if (hDevItem != NULL) 00571 { 00572 EnumChildDevices(hTreeView, 00573 hDevItem, 00574 dnDevInst, 00575 bShowHidden); 00576 } 00577 00578 while (cr == CR_SUCCESS) 00579 { 00580 cr = CM_Get_Sibling(&dnDevInst, 00581 dnDevInst, 00582 0); 00583 if (cr != CR_SUCCESS) 00584 break; 00585 00586 hDevItem = AddDeviceToTree(hTreeView, 00587 hRoot, 00588 dnDevInst, 00589 bShowHidden); 00590 if (hDevItem != NULL) 00591 { 00592 EnumChildDevices(hTreeView, 00593 hDevItem, 00594 dnDevInst, 00595 bShowHidden); 00596 } 00597 } 00598 00599 (void)TreeView_SortChildren(hTreeView, 00600 hRoot, 00601 0); 00602 } 00603 00604 00605 VOID 00606 ListDevicesByConnection(HWND hTreeView, 00607 HTREEITEM hRoot, 00608 BOOL bShowHidden) 00609 { 00610 DEVINST devInst; 00611 CONFIGRET cr; 00612 00613 cr = CM_Locate_DevNode(&devInst, 00614 NULL, 00615 CM_LOCATE_DEVNODE_NORMAL); 00616 if (cr == CR_SUCCESS) 00617 EnumChildDevices(hTreeView, 00618 hRoot, 00619 devInst, 00620 bShowHidden); 00621 00622 (void)TreeView_Expand(hTreeView, 00623 hRoot, 00624 TVE_EXPAND); 00625 00626 (void)TreeView_SelectItem(hTreeView, 00627 hRoot); 00628 } 00629 00630 00631 HTREEITEM 00632 InitTreeView(HWND hTreeView) 00633 { 00634 HTREEITEM hRoot; 00635 HBITMAP hComp; 00636 TCHAR ComputerName[MAX_PATH]; 00637 DWORD dwSize = MAX_PATH; 00638 INT RootImage; 00639 00640 (void)TreeView_DeleteAllItems(hTreeView); 00641 00642 /* get the device image List */ 00643 ImageListData.cbSize = sizeof(ImageListData); 00644 SetupDiGetClassImageList(&ImageListData); 00645 00646 hComp = LoadBitmap(hInstance, 00647 MAKEINTRESOURCE(IDB_ROOT_IMAGE)); 00648 00649 ImageList_Add(ImageListData.ImageList, 00650 hComp, 00651 NULL); 00652 00653 DeleteObject(hComp); 00654 00655 (void)TreeView_SetImageList(hTreeView, 00656 ImageListData.ImageList, 00657 TVSIL_NORMAL); 00658 00659 if (!GetComputerName(ComputerName, 00660 &dwSize)) 00661 { 00662 ComputerName[0] = _T('\0'); 00663 } 00664 00665 RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1; 00666 00667 /* insert the root item into the tree */ 00668 hRoot = InsertIntoTreeView(hTreeView, 00669 NULL, 00670 ComputerName, 00671 NULL, 00672 RootImage, 00673 0); 00674 00675 return hRoot; 00676 } Generated on Sat May 26 2012 04:15:52 for ReactOS by
1.7.6.1
|