现有HDD,USB,U盘,磁盘分区结构如下
HDD   USB HDD   U盘1   U盘2
C E G H
D F
在combobox中列出HDD,USB HDD,U盘1,U盘2,然后选择其中一个时,在ListBox中显示对应的分区,一般情况下没有问题,代码已经实现,但是当两个U盘的PARTITION_INFORMATION对应的分区特征信息一样时,显示的结果如下:
HDD   USB HDD   U盘1   U盘2
C E       G       G
D F       H       H下面是实现的函数,请哪位大侠帮忙指正:
void CXXXDlg::EnumDevice(CString strDevice)
{
    m_DriveList.DeleteAllItems();//显示分区信息的listbox
    char bufDrvStr[128];
    char bufLayout[2048];
    DWORD dwNum;
    HANDLE hDevice;
    PARTITION_INFORMATION pi;
    DRIVE_LAYOUT_INFORMATION* pdli;
    CString strDrive;
    hDevice = CreateFile(strDevice, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hDevice==(HANDLE)-1) 
    {
        ::MessageBox(0,"","err", MB_OK);
        return;
    }
    pdli = (DRIVE_LAYOUT_INFORMATION*)bufLayout;
    memset(bufLayout, 0, sizeof(bufLayout));
    DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, bufLayout, sizeof(bufLayout), &dwNum, NULL);
    CloseHandle(hDevice);
    GetLogicalDriveStrings(sizeof(bufDrvStr), bufDrvStr);
    for(char *s=bufDrvStr; *s!=0;s+=strlen(s)+1) 
    {
      // if (GetDriveType(s)!=DRIVE_FIXED)
     //   continue;
strDrive.Format("\\\\.\\%c:", *s);
hDevice = CreateFile(strDrive, GENERIC_READ,FILE_SHARE_WRITE, NULL, OPEN_EXISTING,0, NULL);
if (hDevice==(HANDLE)-1) continue;
if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_PARTITION_INFO,NULL, 0, &pi, sizeof(pi), &dwNum, NULL))
{
     CloseHandle(hDevice);  
     continue;
} for(DWORD n=0; n<pdli->PartitionCount; n++) 
{
   if (memcmp(pdli->PartitionEntry+n,&pi,2*sizeof(LARGE_INTEGER))==0) //比较分区特征信息
   {

       AddDriveItem(s,pi.BootIndicator);//显示分区信息
       break;
   }
}
CloseHandle(hDevice);
   }
    
}

解决方案 »

  1.   

    用SetupDiGetDeviceRegistryProperty获取系统设备的SPDRP_PHYSICAL_DEVICE_OBJECT_NAME属性
      

  2.   

    你说的SetupDiGetDeviceRegistryProperty是针对device的,我需要的是可以在partition和device之间建立联系的,用你那种方法,该如何枚举分区信息呢,请指教!
      

  3.   

    partition的Device 有没有 GUID,可能是 mount的那个。步骤可以是这样子的...:
    1. 查 USB Device
    2. 查 Disk Device
    3. 查 Partition Device   都是透过 GUID 的方式
    4. 判断它们之间的 父子甚至爷孙关系,可以得到 关于Device的那棵树。 CM_打头的那群。
      

  4.   

    LPGUID pGuid = (LPGUID) & GUID_USB_DEVICE_ENUMERATOR_INTERFACE_CLASS;

    HDEVINFO            hardwareDeviceInfo;

    ULONG predictedLength = 0;
    ULONG requiredLength = 0;

    hardwareDeviceInfo = SetupDiGetClassDevs (
    pGuid,
    NULL, // Define no enumerator (global)
    NULL, // Define no
    (DIGCF_PRESENT | // Only Devices present
    DIGCF_INTERFACEDEVICE )
    ); // Function class devices.

    if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
    {
    TRACE(_T("Windows \"SetupDiGetClassDevs\" API Fail"),NULL,MB_OK);
    return bRetValue;
    }

    SP_INTERFACE_DEVICE_DATA            deviceInterfaceData;
    ZeroMemory(&deviceInterfaceData,sizeof (SP_INTERFACE_DEVICE_DATA));
    deviceInterfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

    while(SetupDiEnumDeviceInterfaces (
    hardwareDeviceInfo,
    0, // No care about specific PDOs
    pGuid,
    index, //device -1
    &deviceInterfaceData)
    )
    {
    SetupDiGetDeviceInterfaceDetail (
    hardwareDeviceInfo,
    &deviceInterfaceData,
    NULL, // probing so no output buffer yet
    0, // probing so output buffer length of zero
    &requiredLength,
    NULL
    );

    PSP_DEVICE_INTERFACE_DETAIL_DATA FlashDiskInterfaceDetailData = NULL;
    FlashDiskInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc (requiredLength);
    ZeroMemory(FlashDiskInterfaceDetailData,sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA));
    FlashDiskInterfaceDetailData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);

    SP_DEVINFO_DATA  device_info_data;
    ZeroMemory(&device_info_data,sizeof (SP_DEVINFO_DATA));
    device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);

    predictedLength = requiredLength;

    if (! SetupDiGetDeviceInterfaceDetail (
    hardwareDeviceInfo,
    &deviceInterfaceData,
    FlashDiskInterfaceDetailData,
    predictedLength,
    &requiredLength,
    &device_info_data))
    {
    // MessageBox(NULL,"Windows \"SetupDiGetInterfaceDeviceDetail\" API Fail",NULL,MB_OK);
    SAFE_FREE(FlashDiskInterfaceDetailData);
    break;
    }
    // find device interface 
    // TRACE("device_info_data.DevInst 0x%04x\n",device_info_data.DevInst);

    bRetValue = IsDev(device_info_data.DevInst); //需求
    SAFE_FREE(FlashDiskInterfaceDetailData);
    index ++;

    if (bRetValue == TRUE)
    {
    break;
    }
    }

    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
      

  5.   

    正想研究这个,先收藏UP
    UPUP
    UPUPUP
      

  6.   

    to  jslisong(碧螺春) :
    这个例子看不大懂, 而且GUID_USB_DEVICE_ENUMERATOR_INTERFACE_CLASS这个在MSDN上都找不到呀,麻烦大侠解释下代码,谢了!to DentistryDoctor(MVP-My heart will fly,in the sky.):
    遍历硬盘的分区链表,这个如何能做到?是否有API,请指教!
      

  7.   

    DEFINE_GUID (GUID_USB_DEVICE_ENUMERATOR_INTERFACE_CLASS,
     0xA5DCBF10, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
      

  8.   

    to jslisong(碧螺春) :
    谢谢,你给的代码我已经看过,但是好像不符合我的要求:
    我是要实现如下功能:
    给定一个盘符(c:,d:等),可以判定它是属于哪个磁盘设备的
    或者给定一个磁盘设备,要枚举属于它的所有分区。而你给的都是针对device的,实现枚举磁盘设备功能的函数我已经有了。
      

  9.   

    你可以试试下面的 guid,应该是你的 C D 盘的//This GUID is for Mounted file system
    //DEFINE_GUID (MOUNTDEV_MOUNTED_DEVICE_GUID,
    //  0x53f5630d, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);//DEFINE_GUID (HARDDISK_GUID, 0x53f56307, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
    //DEFINE_GUID VOLUME_GUID, 0x53f5630d, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
      

  10.   

    to jslisong(碧螺春):    你上面说的那几个guid,我用过,好像作用不大。