Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Windows中使用Delphi从USB驱动器装入分区?_Windows_Delphi_Winapi_Usb - Fatal编程技术网

如何在Windows中使用Delphi从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);

我想从Windows(XP)中的USB驱动器挂载所有分区。我的意思是我想给他们每个人分配驱动器号(当他们没有驱动器号时)。 操作系统会自动执行此操作,但在某些情况下,这样的程序是有用的

我知道如何找到驱动器是否在USB上。 到目前为止,我的代码是:

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)将卸载它。