Delphi 从PhysicalDrive开始映射分区
我想映射Windows中所有驱动器(尚未映射的驱动器)的所有分区。我的意思是我想给他们每个人分配驱动器号。 我知道你可以用FindFirstVolume、FindNextVolume、FindVolumeClose来完成,但有些情况下你不能使用它们。 我试过QueryDosDevice,同样的东西 想法是从\.\PhysicalDrive[n]开始,找出分区并映射它们。 我知道这是可行的,因为我看到了一个可以做到这一点的程序。但我不喜欢它,因为它也映射隐藏分区 有人知道……的方法吗。。。? 谢谢。也许我的命令行工具可以帮助你,至少你可以用命令行参数启动它,看看它是否列出了你想要的所有卷 此链接可能也很有用:也许我的命令行工具可以帮助您,至少您可以使用命令行参数启动它,并查看它是否列出了您期望的所有卷Delphi 从PhysicalDrive开始映射分区,delphi,mapping,disk-partitioning,Delphi,Mapping,Disk Partitioning,我想映射Windows中所有驱动器(尚未映射的驱动器)的所有分区。我的意思是我想给他们每个人分配驱动器号。 我知道你可以用FindFirstVolume、FindNextVolume、FindVolumeClose来完成,但有些情况下你不能使用它们。 我试过QueryDosDevice,同样的东西 想法是从\.\PhysicalDrive[n]开始,找出分区并映射它们。 我知道这是可行的,因为我看到了一个可以做到这一点的程序。但我不喜欢它,因为它也映射隐藏分区 有人知道……的方法吗。。。? 谢谢
此链接也可能有用:您可以使用WMI执行此操作。
在库GLibWMI(或)中,您可以找到TDiskPartitionInfo和TDiskDriveInfo
第一个可以为您提供创建的分区和所有属性。
测试通用样本并检查结果。在这样的分区磁盘中:
获得4个具有4个分区属性的实例,如下所示: 图书馆是完全免费的,并且可以使用源代码。检查样品。
您可以找到一些其他代码来使用WMI访问此信息。如果您想使用另一个,可以搜索“WMI和Win32_DiskPartition类”() 请原谅我的英语错误。
关于您可以使用WMI执行此操作。
在库GLibWMI(或)中,您可以找到TDiskPartitionInfo和TDiskDriveInfo
第一个可以为您提供创建的分区和所有属性。
测试通用样本并检查结果。在这样的分区磁盘中:
获得4个具有4个分区属性的实例,如下所示: 图书馆是完全免费的,并且可以使用源代码。检查样品。
您可以找到一些其他代码来使用WMI访问此信息。如果您想使用另一个,可以搜索“WMI和Win32_DiskPartition类”() 请原谅我的英语错误。
关于我做到了:) 我制作了一个程序,在启动时添加或删除驱动器号-如果在计算机中添加或删除了一个或多个存储驱动器:
program MapDrives;
uses Windows;
type
TPARTITION_INFORMATION = record
StartingOffset: _LARGE_INTEGER; //TLargeInteger;
PartitionLength: _LARGE_INTEGER; //TLargeInteger;
HiddenSectors: DWORD;
PartitionNumber: DWORD;
PartitionType: BYTE;
BootIndicator: BOOLEAN;
RecognizedPartition: BOOLEAN;
RewritePartition: BOOLEAN;
end;
function IntToStr(Value: Integer): string;
begin
if Value < 10 then
Result := Char(Value + 48)
else
Result := Char(Value div 10 + 48) + Char(Value + 48);
end;
function GetNextAvailableLetter: AnsiChar;
var Drives, mask: DWord;
i: Integer;
begin
Drives := GetLogicalDrives;
mask := 4;
Result := 'Z';
for i := 3 to 26 do //C to Z
begin
if mask and Drives = 0 then
begin
Result := AnsiChar(64 + i);
Exit;
end;
mask := mask shl 1;
end;
end;
const IOCTL_DISK_GET_PARTITION_INFO = $0074004;
var i, j, k: Integer;
H: THandle;
dwBytesReturned: DWORD;
BreakCycle, DoMount: Boolean;
NextLetter: AnsiChar;
PartitionInformation: TPARTITION_INFORMATION;
PartitionsInformation: array of TPARTITION_INFORMATION;
Drives, mask: DWord;
OldMode: UINT;
begin
OldMode := SetErrorMode(SEM_FAILCRITICALERRORS); //so it shouldn't ask to insert CD or card
//gets informations about already mounted partitions
SetLength(PartitionsInformation, 0);
Drives := GetLogicalDrives;
mask := 4;
for i := 3 to 26 do //C to Z
begin
if mask and Drives <> 0 then
begin
H := CreateFile(PAnsiChar('\\.\' + Char(64 + i) + ':'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if H <> INVALID_HANDLE_VALUE then
begin
SetLength(PartitionsInformation, Length(PartitionsInformation) + 1);
DeviceIoControl(H, IOCTL_DISK_GET_PARTITION_INFO, nil, 0, @PartitionsInformation[High(PartitionsInformation)], SizeOf(TPARTITION_INFORMATION), dwBytesReturned, nil);
CloseHandle(H);
end
else //removes unaccessible drives
DefineDosDevice(DDD_REMOVE_DEFINITION or DDD_RAW_TARGET_PATH, PAnsiChar(string(Char(64 + i) + ':')), nil);
end;
mask := mask shl 1;
end;
for i := 0 to 99 do
begin
H := CreateFile(PAnsiChar('\\.\PhysicalDrive' + IntToStr(i)), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if H = INVALID_HANDLE_VALUE then //no more hdd's
Break;
CloseHandle(H);
for j := 1 to 20 do
begin
BreakCycle := False;
NextLetter := GetNextAvailableLetter;
DefineDosDevice(DDD_RAW_TARGET_PATH or DDD_NO_BROADCAST_SYSTEM, PAnsiChar(string(NextLetter + ':')), PAnsiChar('\Device\Harddisk' + IntToStr(i) + '\Partition' + IntToStr(j)));
DoMount := True;
H := CreateFile(PAnsiChar('\\.\' + NextLetter + ':'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if H = INVALID_HANDLE_VALUE then //no more partitions
BreakCycle := True
else
begin
PartitionInformation.PartitionType := 0;
DeviceIoControl(H, IOCTL_DISK_GET_PARTITION_INFO, nil, 0, @PartitionInformation, SizeOf(TPARTITION_INFORMATION), dwBytesReturned, nil);
DoMount := PartitionInformation.PartitionType in [0, 1, 6, 7, 11, 12, 114];
CloseHandle(H);
end;
if DoMount then
begin
for k := 0 to High(PartitionsInformation) do //compare with already mounted partitions
if (PartitionsInformation[k].StartingOffset.LowPart = PartitionInformation.StartingOffset.LowPart) and
(PartitionsInformation[k].StartingOffset.HighPart = PartitionInformation.StartingOffset.HighPart) and
(PartitionsInformation[k].StartingOffset.QuadPart = PartitionInformation.StartingOffset.QuadPart) and
(PartitionsInformation[k].PartitionLength.LowPart = PartitionInformation.PartitionLength.LowPart) and
(PartitionsInformation[k].PartitionLength.HighPart = PartitionInformation.PartitionLength.HighPart) and
(PartitionsInformation[k].PartitionLength.QuadPart = PartitionInformation.PartitionLength.QuadPart) and
(PartitionsInformation[k].HiddenSectors = PartitionInformation.HiddenSectors) and
(PartitionsInformation[k].PartitionType = PartitionInformation.PartitionType) and
(PartitionsInformation[k].BootIndicator = PartitionInformation.BootIndicator) and
(PartitionsInformation[k].RecognizedPartition = PartitionInformation.RecognizedPartition) then
Break;
DoMount := k > High(PartitionsInformation);
end;
DefineDosDevice(DDD_REMOVE_DEFINITION or DDD_RAW_TARGET_PATH, PAnsiChar(string(NextLetter + ':')), nil);
if (not BreakCycle) and DoMount then
DefineDosDevice(DDD_RAW_TARGET_PATH, PAnsiChar(string(NextLetter + ':')), PAnsiChar('\Device\Harddisk' + IntToStr(i) + '\Partition' + IntToStr(j)));
if BreakCycle then
Break;
end;
end;
SetErrorMode(OldMode); //restore original mode
end.
程序映射驱动器;
使用窗口;
类型
t分区信息=记录
起始偏移量:\大\整数//t整数;
PartitionLength:\u大\u整数//t整数;
希登:德沃德;
分区编号:DWORD;
分区类型:字节;
引导指示器:布尔;
可识别分区:布尔值;
分区:布尔;
结束;
函数IntToStr(值:整数):字符串;
开始
如果值小于10,则
结果:=字符(值+48)
其他的
结果:=字符(值div 10+48)+字符(值+48);
结束;
函数GetNextAvailableLetter:AnsiChar;
var驱动器,掩码:DWord;
i:整数;
开始
驱动器:=GetLogicalDrive;
掩码:=4;
结果:='Z';
对于i:=3到26 do//C到Z
开始
如果掩码和驱动器=0,则
开始
结果:=AnsiChar(64+i);
出口
结束;
掩模:=掩模shl 1;
结束;
结束;
const IOCTL_DISK_GET_PARTITION_INFO=$0074004;
变量i,j,k:整数;
H:THandle;
德比:德沃德;
BreakCycle,DoMount:布尔值;
下一位:安西卡尔;
分区信息:t分区信息;
分区信息:分区信息数组;
驱动器,掩码:DWord;
旧模式:UINT;
开始
OldMode:=设置错误模式(SEM\U故障临界错误)//所以它不应该要求插入CD或卡
//获取有关已装入分区的信息
设置长度(分区信息,0);
驱动器:=GetLogicalDrive;
掩码:=4;
对于i:=3到26 do//C到Z
开始
如果掩码和驱动器为0,则
开始
H:=CreateFile(PAnsiChar('\.\'+Char(64+i)+':')、泛型读取、文件共享读取或文件共享写入、无、打开现有、0、0);
如果H句柄值无效,则
开始
设置长度(分区信息,长度(分区信息)+1);
设备控制(H,IOCTL\u DISK\u GET\u PARTITION\u INFO,nil,0,@PartitionsInformation[High(PartitionsInformation)],SizeOf(TPARTITION\u INFORMATION),dwbytes返回,nil);
闭合手柄(H);
结束
else//删除不可访问的驱动器
definedDevice(DDD_REMOVE_定义或DDD_RAW_目标路径,PAnsiChar(字符串(Char(64+i)+':')),nil);
结束;
掩模:=掩模shl 1;
结束;
对于i:=0到99 do
开始
H:=CreateFile(PAnsiChar('\\.\PhysicalDrive'+IntToStr(i)),通用读取,文件共享读取或文件共享写入,无,打开现有,0,0);
如果H=无效的句柄值,则//不再有hdd
打破
闭合手柄(H);
对于j:=1到20 do
开始
BreakCycle:=假;
NextLetter:=GetNextAvailableLetter;
定义设备(DDD_原始_目标_路径或DDD_非广播_系统、PAnsiChar(字符串(NextLetter+':'))、PAnsiChar('\Device\Harddisk'+IntToStr(i)+'\Partition'+IntToStr(j));
DoMount:=真;
H:=CreateFile(PAnsiChar('\\.\'+NextLetter+':')、泛型读取、文件共享读取或文件共享写入、无、打开现有、0、0);
如果H=无效的句柄值,则//不再有分区
BreakCycle:=真
其他的
开始
PartitionInformation.PartitionType:=0;
设备控制(H,IOCTL\u DISK\u GET\u PARTITION\u INFO,nil,0,@PartitionInformation,SizeOf(TPARTITION\u INFORMATION),dwBytesReturned,nil);
DoMount:=[0,1,6,7,11,12,114]中的PartitionInformation.PartitionType;
C