DevicePath Information

In Windows based environment, each device belongs to a device class, and the operating system assigns a unique device path and instance ID to identify each device.

In this article, you'll see how to retrieve the device path and the device instance ID for storage devices attached to a system. I strongly suggest that you also read the MSDN artcles as well.

I have used following APIs to achieve the same results:

HDEVINFO  SetupDiGetClassDevs( 
         IN LPGUID  ClassGuid..OPTIONAL, 
         IN PCTSTR  Enumerator..OPTIONAL,
         IN HWND  hwndParent..OPTIONAL,
         IN DWORD  Flags);

The SetupDiGetClassDevs function returns a handle to the device information set. For a full description of this class, please see the MSDN article.

WINSETUPAPI BOOL WINAPI  SetupDiEnumDeviceInf(    
         IN HDEVINFO  DeviceInfoSet,    
         IN DWORD  MemberIndex,    
         OUT PSP_DEVINFO_DATA  DeviceInfoData);

The SetupDiEnumDeviceInf function returns SP_DEVINFO_DATA structure from the the device information set. For detailed information please see this MSDN article.

WINSETUPAPI BOOL WINAPI SetupDiEnumDeviceInterfaces(
         IN HDEVINFO  DeviceInfoSet,    
         IN PSP_DEVINFO_DATA  DeviceInfoData  OPTIONAL,
         IN LPGUID  InterfaceClassGuid,    
         IN DWORD  MemberIndex,    
         OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData);

The SetupDiEnumDeviceInterfaces function enumerates the device interfaces presented within the device information set.

WINSETUPAPI BOOL WINAPI  SetupDiGetDeviceInterfaceDetail(
          IN HDEVINFO  DeviceInfoSet,    
          IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,    
          OUT PSP_DEVICE_INTERFACE_DETAIL_DATA  DeviceInterfaceDetailData..OPTIONAL,    
          IN DWORD  DeviceInterfaceDetailDataSize,    
          OUT PDWORD  RequiredSize..OPTIONAL,    
          OUT PSP_DEVINFO_DATA  DeviceInfoData OPTIONAL);

The SetupDiGetDeviceInterfaceDetail function helps to retrieve details about a device. To get details about the interfaces you need to call this function twice. First, Call SetupDiGetDeviceInterfaceDetail with a NULL DeviceInterfaceDetailData pointer, a DeviceInterfaceDetailDataSize of zero, and a valid RequiredSize variable. In response to this function call, the function returns the required buffer size to RequiredSize variable. You can then allocate a buffer[TCHAR] and call the function again, which in turn returns the interface details.

WINSETUPAPI BOOL WINAPI  SetupDiGetClassDescription(
         IN LPGUID  ClassGuid,    
         OUT PTSTR  ClassDescription,    
         IN DWORD  ClassDescriptionSize,    
         OUT PDWORD  RequiredSize  OPTIONAL);

The SetupDiGetClassDescription function returns the class description associated with the setup GUID.

WINSETUPAPI BOOL WINAPI  SetupDiGetDeviceInstanceId(    
         IN HDEVINFO  DeviceInfoSet,    
         IN PSP_DEVINFO_DATA  DeviceInfoData,    
         OUT PTSTR  DeviceInstanceId,    
         IN DWORD  DeviceInstanceIdSize,     
         OUT PDWORD  RequiredSize  OPTIONAL);

The SetupDiGetDeviceInstanceId function returns device instance Id associated with device information element.

The following demo code snippet is the implemenation details to get attached storage devices device path and device instance ID:

// USB_Drive_Property.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "USB_Drive_Property.h"
#include <windows.h>
#include <SetupApi.h> // Included from Windows SDKs

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// Defined in winioctl.h
DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);

// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
   int nRetCode = 0;
   
   // initialize MFC and print and error on failure
   if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
   {
      // TODO: change error code to suit your needs
      _tprintf(_T("Fatal Error: MFC initialization failed\n"));
      nRetCode = 1;
   }
   else
   {
      // TODO: code your application's behavior here.

      HDEVINFO hDevHandle;
      SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
      DWORD required = 0;
      deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

      int nBufferSize = 0;
      
      SP_DEVINFO_DATA devInfoData;
      devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

      DWORD MemberIndex = 0;
      BOOL  Result;

      hDevHandle = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, 
         DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

      if(hDevHandle == INVALID_HANDLE_VALUE)
      {
         return 1;
      }
      else
      {
         BOOL bStart = false;
         TCHAR *buffer = NULL;
         PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData;
			do
			{
				Result = SetupDiEnumDeviceInfo(hDevHandle, MemberIndex, &devInfoData);

				if(Result)
				{
				   Result = SetupDiEnumDeviceInterfaces(hDevHandle, 0, &GUID_DEVINTERFACE_VOLUME, 
                  MemberIndex, &deviceInterfaceData);
            }
            
            if(!Result)
            {
               SetupDiDestroyDeviceInfoList(hDevHandle);
               delete []buffer;
               buffer = NULL;
               return 1;
            }
            MemberIndex++;

            BOOL detailResult = FALSE;
      
            if(!bStart)
            {
               // As per MSDN, Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a 
               // NULL DeviceInterfaceDetailData pointer, a DeviceInterfaceDetailDataSize of zero, 
               // and a valid RequiredSize variable. In response to such a call, this function returns 
               // the required buffer size at RequiredSize and fails with GetLastError returning 
               // ERROR_INSUFFICIENT_BUFFER. 
               // Allocate an appropriately sized buffer and call the function again to get the interface details. 

               SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, NULL, 0, &required, NULL);

               buffer = new TCHAR[required];
               devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) buffer;
               devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
               nBufferSize = required;
               bStart = true;
            }

            detailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, 
               devicedetailData, nBufferSize , &required, NULL);

            _tprintf(L"Device Path = %s\n\n", devicedetailData->DevicePath);

            if(detailResult)
            {
               TCHAR szDescription[MAX_PATH];
               memset(szDescription, 0, MAX_PATH);

               SetupDiGetClassDescription(&devInfoData.ClassGuid, szDescription, MAX_PATH, &required);
               _tprintf(L"Class Description = %s\n\n", szDescription);

               memset(szDescription, 0, MAX_PATH);
               SetupDiGetDeviceInstanceId(hDevHandle, &devInfoData, szDescription, MAX_PATH, 0);
               _tprintf(L"Device Instance Id = %s\n\n\n", szDescription);
            }

            if(!detailResult)
            {
               continue;
            }
         }while(Result);
      }
   }

   return nRetCode;
}

The snap shot of the output looks like the picture below:



About the Author

Mufti Mohammed

Small-Talk and Small-Programming working together. My Blog

Comments

  • Trist omringd om te kunnen stroom gehecht aan klanten veranderen

    Posted by mrswanzi on 06/06/2013 04:55pm

    [url=http://koptelefoon-monsterbeats.weebly.com/]beats by dre[/url] Wij raden je aan om bij een van de onderstaande webshops te bestellen. Bij deze shops weet je zeker dat je vertrouwd je Beats kunt kopen met een goede prijs, snelle verzending en goede garantie. Geniet volledig in stijl en draadloos van je favoriete muziek met de Beats by Dr. Dre Wireless [url=http://koptelefoon-monsterbeats.tumblr.com/]beats by dre[/url] Wanneer je te voet over straat loopt is een open constructie veel beter, omdat je dan het verkeer en omgevingsgeluiden gewoon kunt horen. Een open koptelefoon voelt bovendien prettiger aan en heeft een natuurlijkere weergave. Dit resulteert in een ontspannender luistergenot. Wanneer je in het bezit bent van de Real dan kun je je op vele situaties verheugen: studeren met de Real, joggen met de Real, gamen met de Real, films kijken met de Real, werken met de Real, en nog veel meer! Met de de Real creer je je eigen universum en ga je op in jouw moment! Voordelen van high definition verslaan Dr Dre hoofdtelefoon [url=http://koptelefoon-monsterbeats.blogspot.com/]monster beats koptelefoon[/url] Beats By Dre De zijn een bijzondere serie koptelefoons. Veel mensen kiezen ervoor om beats te kopen om hun muziek interessanter en het beluisteren waard. Dit is een vrij eenvoudige en goedkope oplossing voor degenen die niet de tijd of de apparatuur om de beats voor hun muziek of liedjes te produceren. Echter, springt hoofd eerst in deze wereld niet aan te raden, want er zijn tal van oplichters die er zijn gewoon te wachten om uw geld te nemen. Als u wilt weten hoe je beats kopen van legitieme bronnen, verder te lezen.

    Reply
  • are there any code to download?

    Posted by fair_trade on 01/23/2012 10:16pm

    as the title

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Due to internal controls and regulations, the amount of long term archival data is increasing every year. Since magnetic tape does not need to be periodically operated or connected to a power source, there will be no data loss because of performance degradation due to the drive actuator. Read this white paper to learn about a series of tests that determined magnetic tape is a reliable long-term storage solution for up to 30 years.

Most Popular Programming Stories

More for Developers

RSS Feeds