我做到了:) 我做了一個節目誰添加或當它開始刪除驅動器號 - 是否添加或從計算機中刪除一個或多個存儲驅動器:
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.
在我提到它的電腦完美無缺。
謝謝大家的所有幫助我製作此代碼的想法。
如果有人注意到一些錯誤或對如何改進它有任何好的想法,我會很樂意修復/實施它們。
你可以描述何時使用FindFirstVolume..FindNextVolume不起作用? – Remko 2011-01-12 19:25:20
所以你的問題是如何遍歷所有分區,而不是如何安裝它們? – 2011-01-12 19:29:04
@Remko它們不適用於某些Windows版本,其中某些設備(如USB驅動器)的驅動程序會動態添加,並且這些功能無法「看見」它們。 @Ritsaert我說我想掛載他們(全部)。 – 2011-01-12 20:29:11