如何在Windows中使用Delphi从USB驱动器装入分区?
我想从Windows(XP)中的USB驱动器挂载所有分区。我的意思是我想给他们每个人分配驱动器号(当他们没有驱动器号时)。 操作系统会自动执行此操作,但在某些情况下,这样的程序是有用的 我知道如何找到驱动器是否在USB上。 到目前为止,我的代码是:如何在Windows中使用Delphi从USB驱动器装入分区?,windows,delphi,winapi,usb,Windows,Delphi,Winapi,Usb,我想从Windows(XP)中的USB驱动器挂载所有分区。我的意思是我想给他们每个人分配驱动器号(当他们没有驱动器号时)。 操作系统会自动执行此操作,但在某些情况下,这样的程序是有用的 我知道如何找到驱动器是否在USB上。 到目前为止,我的代码是: type STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined);
type
STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined);
TStorageQueryType = STORAGE_QUERY_TYPE;
STORAGE_PROPERTY_ID = (StorageDeviceProperty = 0, StorageAdapterProperty);
TStoragePropertyID = STORAGE_PROPERTY_ID;
STORAGE_PROPERTY_QUERY = packed record
PropertyId: STORAGE_PROPERTY_ID;
QueryType: STORAGE_QUERY_TYPE;
AdditionalParameters: array[0..9] of AnsiChar;
end;
TStoragePropertyQuery = STORAGE_PROPERTY_QUERY;
STORAGE_BUS_TYPE = (BusTypeUnknown = 0, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre,
BusTypeUsb, BusTypeRAID, BusTypeiScsi, BusTypeSas, BusTypeSata, BusTypeMaxReserved = $7F);
TStorageBusType = STORAGE_BUS_TYPE;
STORAGE_DEVICE_DESCRIPTOR = packed record
Version: DWORD;
Size: DWORD;
DeviceType: Byte;
DeviceTypeModifier: Byte;
RemovableMedia: Boolean;
CommandQueueing: Boolean;
VendorIdOffset: DWORD;
ProductIdOffset: DWORD;
ProductRevisionOffset: DWORD;
SerialNumberOffset: DWORD;
BusType: STORAGE_BUS_TYPE;
RawPropertiesLength: DWORD;
RawDeviceProperties: array[0..0] of AnsiChar;
end;
TStorageDeviceDescriptor = STORAGE_DEVICE_DESCRIPTOR;
const
IOCTL_STORAGE_QUERY_PROPERTY = $002D1400;
var i: Integer;
H: THandle;
USBDrives: array of Byte;
Query: TStoragePropertyQuery;
dwBytesReturned: DWORD;
Buffer: array[0..1023] of Byte;
sdd: TStorageDeviceDescriptor absolute Buffer;
begin
SetLength(UsbDrives, 0);
SetErrorMode(SEM_FAILCRITICALERRORS);
for i := 0 to 99 do
begin
H := CreateFile(PChar('\\.\PhysicalDrive' + IntToStr(i)), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if H <> INVALID_HANDLE_VALUE then
begin
try
dwBytesReturned := 0;
FillChar(Query, SizeOf(Query), 0);
FillChar(Buffer, SizeOf(Buffer), 0);
sdd.Size := SizeOf(Buffer);
Query.PropertyId := StorageDeviceProperty;
Query.QueryType := PropertyStandardQuery;
if DeviceIoControl(H, IOCTL_STORAGE_QUERY_PROPERTY, @Query, SizeOf(Query), @Buffer, SizeOf(Buffer), dwBytesReturned, nil) then
if sdd.BusType = BusTypeUsb then
begin
SetLength(USBDrives, Length(USBDrives) + 1);
UsbDrives[High(USBDrives)] := Byte(i);
end;
finally
CloseHandle(H);
end;
end;
end;
for i := 0 to High(USBDrives) do
begin
//
end;
end.
类型
存储\查询\类型=(PropertyStandardQuery=0,PropertyExistsQuery,PropertyMaxQuery,PropertyQueryMaxDefined);
TStorageQueryType=存储\查询\类型;
存储\属性\ ID=(StorageDeviceProperty=0,StorageAdapterProperty);
TStoragePropertyID=存储\属性\ ID;
存储\属性\查询=打包记录
PropertyId:存储\属性\ ID;
查询类型:存储\查询\类型;
附加参数:AnsiChar的数组[0..9];
结束;
TStoragePropertyQuery=存储\属性\查询;
存储总线类型=(BusTypeUnknown=0,BusTypeScsi,BusTypeAtapi,BusTypeAta,BusType1394,BusTypeSsa,BUSTYPEFIBER,
BusTypeUsb、BusTypeRAID、BusTypeiScsi、BusTypeSas、BusTypeSata、BusTypeMaxReserved=$7F);
TStorageBusType=存储\总线\类型;
存储\设备\描述符=打包记录
版本:德沃德;
尺寸:德沃德;
设备类型:字节;
DeviceTypeModifier:字节;
移除媒体:布尔;
命令排队:布尔;
卖方报价:德沃德;
产品偏移量:DWORD;
ProductRevisionOffset:DWORD;
serialnumberofset:DWORD;
BusType:存储\总线\类型;
原始属性长度:DWORD;
RawDeviceProperties:AnsiChar的数组[0..0];
结束;
t存储设备描述符=存储设备描述符;
常数
IOCTL_存储_查询_属性=$002D1400;
varⅠ:整数;
H:THandle;
USBDrives:字节数组;
查询:TStoragePropertyQuery;
德比:德沃德;
缓冲区:字节数组[0..1023];
sdd:TStorageDeviceDescriptor绝对缓冲区;
开始
设置长度(UsbDrives,0);
设置错误模式(SEM_故障临界错误);
对于i:=0到99 do
开始
H:=CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(i)),0,文件共享读取或文件共享写入,无,打开现有,0,0;
如果H句柄值无效,则
开始
尝试
返回的dwbytes:=0;
FillChar(查询,SizeOf(查询),0);
FillChar(Buffer,SizeOf(Buffer),0);
sdd.Size:=SizeOf(缓冲区);
Query.PropertyId:=StorageDeviceProperty;
Query.QueryType:=PropertyStandardQuery;
如果DeviceIoControl(H,IOCTL_STORAGE_QUERY_属性,@QUERY,SizeOf(QUERY),@Buffer,SizeOf(Buffer),dwBytesReturned,nil),则
如果sdd.BusType=BusTypeUsb,则
开始
设置长度(USBDrives,长度(USBDrives)+1);
UsbDrives[高(UsbDrives)]:=字节(i);
结束;
最后
闭合手柄(H);
结束;
结束;
结束;
对于i:=0至高(USB驱动)do
开始
//
结束;
结束。
但我不知道如何访问每个驱动器上的分区并装载它们。
您能帮我吗?看看卷管理功能- FirstFirstVolume、FindNextVolume、FindVolumeClose将以\\?\Volume{Guid}名称列出分区 Createfile应该能够选择卷名,以便上面的代码可以检查它的USB SetVolumeMountPoint允许您将卷装载为驱动器号或文件夹装载点
这篇博客文章讨论了卷名-似乎是个好主意。非常感谢。但我有两个问题:1。在我的计算机上,它找到分区总数减去1。例如,我的内部硬盘有4个,它找到3个(而不是4个)。我在电脑上加了一个U盘(只有一个分区),它会找到4个(而不是5个)。2.当我将此名称传递给CreateFile时,它返回无效的\u句柄\u值;GetLastError表示找不到错误路径。我该怎么办?我通过删除每个名称末尾的“\”解决了第二个问题。哦,我现在明白了:FirstFirstVolume、FindNextVolume、FindVolumeClose没有找到隐藏分区(4个分区中的2个是隐藏的)。因此,解决方案是好的:)很抱歉,我还不能投票给你:(@vickd)问一个问题:我不是忘恩负义,你帮了我很多。但是还有其他方法来装载分区吗?我问这个问题是因为在一些计算机上FindFirstVolume、FindNextVolume和FindVolumeClose找不到一些卷。你可以在磁盘管理中看到物理驱动器,你可以手动装载分区,但是那些功能找不到它们。你可以吗u请再次帮助我…?谢谢。DefinedDevice可以使用设备名称装载。不要使用物理磁盘0..99,请尝试\device\Harddisk0..99\Partition1..4如果获得句柄,然后使用DefinedDevice(1,'J:','\device\Harddisk0\Partition1')(根据需要更改J和\device)。DefinedDevice(2,'J',nil)将卸载它。