ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

enumdevices.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.