怎么样知道硬盘上有哪几个分区或者指定的分区是在哪一个硬盘上? ( 积分: 100 )

  • 主题发起人 主题发起人 想飞的男孩
  • 开始时间 开始时间

想飞的男孩

Unregistered / Unconfirmed
GUEST, unregistred user!
问题简述:如题
问题详述:
1、最初问题是想判断盘符是否移动存储设备,然后使用GetDriveType函数存在一个漏洞,因为移动存储设备生产的不规范,存在有移动存储设备检测出来是硬盘的。
2、而后,在资源管理器中,windows是能够知道移动存储设备所在磁盘0还是磁盘1,意思无论该盘符GetDriveType是什么类型,不管如何伪装,若在磁盘1上,一定是移动存储设备。
问题解决过程:
已经在网上搜索N多资料了,
例如下面这样的帖子 http://www.7880.com/Info/Article-491c6e40.html 各位就不必再贴了
帖子中提到“需要JEDI的Win32支持库才能编译 ”
所有的帖子都只是这样一句话,不明白如何引用,请各位老兄知道的介绍一下。能有代码解决,或者提供线索解决的,100分送上,谢谢了。
 
http://www.7880.com/Info/Article-491c6e40.html
像上面这URL的这种效果不理想,有时找到出来的不对的

你看下下面这个的VC++6的源码研究下,好像是直接读取分区表内容的
http://www.cn-dos.net/forum/viewthread.php?tid=30157
 
function GetVolumeInfo(DriverLetter:string):TDiskExtent;
var
hVolume: THandle;
DiskExtents: PVolumeDiskExtents;
dwOutBytes: Cardinal;
begin
with Result do
begin
DiskNumber := 0;
StartingOffset.QuadPart := 0;
ExtentLength.QuadPart := 0;
end;
hVolume := CreateFile(PChar('//./'+DriverLetter+':'), GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hVolume < 1 then Exit;
DiskExtents := AllocMem(Max_Path);

if DeviceIoControl(hVolume,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
nil, 0,
DiskExtents, Max_Path,
dwOutBytes, nil) then
begin
if DiskExtents^.NumberOfDiskExtents > 0 then
Result := DiskExtents^.Extents[0];
end;

FreeMem(DiskExtents);
CloseHandle(hVolume);
end;

搜索到上面的代码,测试通过了,确实能通过返回磁盘0、1、2、3判断出是硬盘还是移动存储设备,判断了几十台十正确的。
但是,在一台2000的计算机和一台Xp的计算机上,判断错误了,明明是移动存储设备,返回的却是磁盘0。

不怕错误,就怕正确率是99%,郁闷中啊。。。
 
和楼主遇到同样的问题,郁闷中。有篇帖子里给出了VC的代码解决这个问题。
试着改了下,不过一直报错,等待高人。
另外楼主读取硬盘数,如果及机器上挂的不止一块硬盘的话不依然有问题吗

4.区分移动硬盘和硬盘
我说了,移动硬盘也是DRIVE_FIXED ,真够bt的,这个没做过的话,很难想像的,太bt了
那怎么区分
用DeviceIoControl对卷下IOCTL_STORAGE_QUERY_PROPERTY进行获取信息
取返回STORAGE_DEVICE_DESCRIPTOR结构里面的STORAGE_BUS_TYPE

代码
#include <dbt.h>
#include <winioctl.h>
// IOCTL control code
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0,
StorageAdapterProperty,
StorageDeviceIdProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;

typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0,
PropertyExistsQuery,
PropertyMaskQuery,
PropertyQueryMaxDefined
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;


typedef struct _STORAGE_PROPERTY_QUERY {
STORAGE_PROPERTY_ID PropertyId;
STORAGE_QUERY_TYPE QueryType;
UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;




typedef struct _STORAGE_DEVICE_DESCRIPTOR {
ULONG Version;
ULONG Size;
UCHAR DeviceType;
UCHAR DeviceTypeModifier;
BOOLEAN RemovableMedia;
BOOLEAN CommandQueueing;
ULONG VendorIdOffset;
ULONG ProductIdOffset;
ULONG ProductRevisionOffset;
ULONG SerialNumberOffset;
STORAGE_BUS_TYPE BusType;
ULONG RawPropertiesLength;
UCHAR RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;



HANDLE hDevice; // 设备句柄
BOOL bResult; // DeviceIoControl的返回结果


// 打开设备
hDevice = ::CreateFile(szPath, // 文件名
GENERIC_READ, // 软驱需要读盘
FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享方式
NULL, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 不需设置文件属性
NULL);


if (hDevice == INVALID_HANDLE_VALUE)
{
return FALSE;
}

STORAGE_PROPERTY_QUERY Query; // input param for query
DWORD dwOutBytes; // IOCTL output length

Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;

STORAGE_DEVICE_DESCRIPTOR pDevDesc;

pDevDesc.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);

// 用 IOCTL_STORAGE_QUERY_PROPERTY

bResult = ::DeviceIoControl(hDevice, // device handle
IOCTL_STORAGE_QUERY_PROPERTY, // info of device property
&Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer
&pDevDesc, pDevDesc.Size, // output data buffer
&dwOutBytes, // out's length
(LPOVERLAPPED)NULL);

UINT Type = pDevDesc.BusType;

// Unknown 0x00
// SCSI 0x01
// ATAPI 0x02
// ATA 0x03
// IEEE1394 0x04
// SSA(Serial storage architecture) 0x05
// Fibre Channel, 0x06
// USB, 0x07
// RAID, 0x08
这样,就能区分USB硬盘和普通硬盘了
 
如果是动态盘,或者阵列的盘,比如跨区卷,那么怎么判断???上面的都是判断基本盘的代码。
 
这些代码是不会区分磁盘阵列或者移动硬盘的,统一识别为FIXED,你可以先检测盘符,再检测usb设备
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
913
SUNSTONE的Delphi笔记
S
后退
顶部