VC ++ Gets Physical ID under the current system storage devices

A cause:

Because of the recent need to write a disk SMART obtain the value of Windows tools, studied under the relevant documents, we found all DeviceIocontrol subsequent execution of the function, they have to get physical number of devices, physicalX. I found the method to record.

Execution environment VS2019.

 The two steps:

1. SetupDiGetClassDevs () Get information disk type pointing device set pointer HDEVINFO.

2. SetupDiEnumDeviceInterfaces () acquired by the previous step HDEVINFO, enumerated one by one beginning from 0 based disk device is present, the presence of returns TRUE, the device information in SP_DEVICE_INTERFACE_DATA structure.

3. SetupDiGetDeviceInterfaceDetail () according to the previous step SP_DEVICE_INTERFACE_DATA , DevicePath acquired (in PSP_DEVICE_INTERFACE_DETAIL_DATA structure).

4. HANDLE = CreateFile (), according DevicePath, create a file handle reading and writing.

5.DeviceIoControl (), Step 4 using the handle, ctrl_code use IOCTL_STORAGE_GET_DEVICE_NUMBER. STORAGE_DEVICE_NUMBER return value structure, device_number (id) and partition structure in a variable number.

 

 Three details:

1.SetupDiGetClassDevs 

MSDN explanation:

The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information elements for a local computer.

In simple terms, is to get a set of specified all the information of the installed equipment category or all categories, such as specifying a USB device, etc., returns a pointer to a HDEVINFO, the following functions will be used.

WINSETUPAPI HDEVINFO SetupDiGetClassDevsW(
const GUID *ClassGuid,
PCWSTR Enumerator,
HWND hwndParent,
DWORD Flags
);

 

Parameter Description:

PGUID  ClassGuid

GUID provide a pointer to a pointer when creating the device list. If the flag is set DIGCF_ALLCLASSES, then this parameter can be ignored, and the results list includes all categories of devices already installed.

To find some sign of the definition file in Winioctl.h

#define DiskClassGuid GUID_DEVINTERFACE_DISK //本次使用该标志,获取所有DISK类型的设备信息集合的指针。
#define CdRomClassGuid GUID_DEVINTERFACE_CDROM
#define PartitionClassGuid GUID_DEVINTERFACE_PARTITION
#define TapeClassGuid GUID_DEVINTERFACE_TAPE
#define WriteOnceDiskClassGuid GUID_DEVINTERFACE_WRITEONCEDISK
#define VolumeClassGuid GUID_DEVINTERFACE_VOLUME
#define MediumChangerClassGuid GUID_DEVINTERFACE_MEDIUMCHANGER
#define FloppyClassGuid GUID_DEVINTERFACE_FLOPPY
#define CdChangerClassGuid GUID_DEVINTERFACE_CDCHANGER
#define StoragePortClassGuid GUID_DEVINTERFACE_STORAGEPORT

#define HiddenVolumeClassGuid GUID_DEVINTERFACE_HIDDEN_VOLUME

#define GUID_CLASS_COMPORT GUID_DEVINTERFACE_COMPORT
#define GUID_SERENUM_BUS_ENUMERATOR GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR

PCTSTR Enumerator

  Providing a device instance registry key name the enum branch, the content may be filtered by its lifting plum: as: PCI only PCI display device. If this parameter is not specified, then the entire enumeration tree to obtain device information for all devices from instances.

HWND hwndParent   

  Provide top-level window handles, all user interfaces can use it to contact members.

DWORD Flags

It provides an option for use in the device information structure. SetupApi.h file to view the following Flags:

#define DIGCF_DEFAULT 0x00000001 // only valid with DIGCF_DEVICEINTERFACE
#define DIGCF_PRESENT 0x00000002 //当前存在的设备
#define DIGCF_ALLCLASSES 0x00000004
#define DIGCF_PROFILE 0x00000008
#define DIGCF_DEVICEINTERFACE 0x00000010

 

The configuration is as follows, disk devices get all information about the current system :

GUID lpGuid = GUID_DEVINTERFACE_DISK;

hDevInfoSet = SetupDiGetClassDevs(
&lpGuid, // class GUID
NULL, // Enumerator
NULL, // hwndParent
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE // present devices
);

 Four Source:

DWORD CDiskToolDlg::GetDevicePath()
{
    HDEVINFO hDevInfoSet;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
    DWORD DeviceIndex;
    BOOL result;
    GUID lpGuid;
    DWORD requiredSize;
    HANDLE handle;
    STORAGE_DEVICE_NUMBER diskNumber;
    DWORD bytesReturned;

    DeviceIndex = 0;
    lpGuid = GUID_DEVINTERFACE_DISK;


    //get a handle to a device information set
    hDevInfoSet = SetupDiGetClassDevs(
        &lpGuid,      // class GUID
        NULL,         // the Enumerator 
        NULL,         // The hwndParent 
        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE     // Present Devices 
    ); 

    IF (hDevInfoSet == INVALID_HANDLE_VALUE) 
    { 
        CString res_error; 
        res_error.Format (_T ( " % D " ), the GetLastError ()); // convert into String 
        logs_display (_T ( " device handle failed: " ) res_error +); // output error code 
        return (DWORD) - . 1 ; 
    } 


    Result = to true;
    ZeroMemory(&deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));//清空内存
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);//函数硬性要求cbSize
    m_Device_List.ResetContent();
    while(SetupDiEnumDeviceInterfaces(hDevInfoSet,NULL,&lpGuid,DeviceIndex,&deviceInterfaceData))//依此获取deviceInterfaceData
    {
        DeviceIndex++;
        SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
            &deviceInterfaceData,
            NULL,
            0,
            &requiredSize,
            NULL);
        if (ERROR_INSUFFICIENT_BUFFER == GetLastError())//如果Getlasterror的结果为ERROR_INSUFFICIENT_BUFFER,将返回requiresize值。
        {
            deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
            ZeroMemory(deviceInterfaceDetailData, requiredSize);
            deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            //抓取devicepath,deviceinterfacedetaildata.devicepath.
            result=    SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
                    &deviceInterfaceData,
                    deviceInterfaceDetailData,
                    requiredSize,
                    NULL,
                    NULL);
            

            if (result)
            {
                handle = CreateFile(deviceInterfaceDetailData->DevicePath,
                    GENERIC_READ,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    NULL);

                if (handle!= INVALID_HANDLE_VALUE)
                {
                    DeviceIoControl(handle,
                        IOCTL_STORAGE_GET_DEVICE_NUMBER,
                        NULL,
                        0,
                        &diskNumber,
                        sizeof(STORAGE_DEVICE_NUMBER),
                        &bytesReturned,
                        NULL);
                    CloseHandle(handle);
                    BYTE b_deviceIndex=diskNumber.DeviceNumber;
                    IsUsbType(UCHAR(b_deviceIndex));
                        device_count++;
                    //ReadDiskSmart(UCHAR(b_deviceIndex));
                }
                else
                {
                    CString res_error;
                    res_error.Format(_T(" % D " ), the GetLastError ()); // converted into String 
                    logs_display (_T ( " the CreateFile error: " ) res_error +); // output error code 
                    return (DWORD) - . 1 ; 
                } 
            } 
            the else 
            { 
                CString res_error; 
                res_error .Format (_T ( " % D " ), the GetLastError ()); // converted into String 
                logs_display (_T ( " getdevicepath failure: " ) res_error +); // output code error 
                
                return (DWORD) - . 1 ; 
            } 

        } 
        the else 
        { 
            CString res_error; 
            res_error.Format (_T ( " % D " ), the GetLastError ()); // converted into String 
            logs_display (_T ( " Get the data length of the memory required failed: " ) res_error +); // output error code 
            return (DWORD) - . 1 ; 
        } 
    } 
    CString device_count_str; 
    device_count_str.Format (_T ( " % D "), DEVICE_COUNT); 

} // Get connected hard disk serial number PHYSICALX

 

Guess you like

Origin www.cnblogs.com/allen-gg/p/11245890.html
Recommended