硬盘分区和物理硬盘的对应关系?
hPhysicalDriveIOCTL := CreateFile('\\.\PhysicalDrive'+s), ....)
where s = '0', '1', ....
+ DeviceIoControl(hPhysicalDriveIOCTL, ...)
This work in WinNT/2000/XP perfectly.
---------------------------------------
怎么样知道我的硬盘上有哪几个分区或者指定的分区是在哪一个硬盘上?
磁盘 1 的分区 1 : C
磁盘 1 的分区 2 : D
磁盘 1 的分区 3 : E
磁盘 1 的分区 4 : F
磁盘 2 的分区 1 : G
磁盘 2 的分区 2 : I
磁盘 2 的分区 3 : J
磁盘 2 的分区 4 : K
例如,返回E盘对应的硬盘为磁盘 1?
可以使用WMI,可以参考猛料中的WMI的例子和MSDN就可以找到答案。
另外可以使用JEDI的Win32 API库:
GetVolumeInfo('C').DiskNumber结果就是所在的物理磁盘ID
需要JEDI的Win32支持库才能编译!
unit _Utility;
interface
uses
Windows, SysUtils;
const
FILE_ANY_ACCESS = 0;
METHOD_BUFFERED = 0;
IOCTL_VOLUME_BASE = DWORD('V');
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (
(IOCTL_VOLUME_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
(0 shl 2) or METHOD_BUFFERED);
type
TIdSector = packed record
wGenConfig: Word;
wNumCyls: Word;
wReserved: Word;
wNumHeads: Word;
wBytesPerTrack: Word;
wBytesPerSector: Word;
wSectorsPerTrack: Word;
wVendorUnique: array[0..2] of Word;
sSerialNumber: array[0..19] of char;
wBufferType: Word;
wBufferSize: Word;
wECCSize: Word;
sFirmwareRev: array[0..7] of char;
sModelNumber: array[0..39] of char;
wMoreVendorUnique: Word;
wDoubleWordIO: Word;
wCapabilities: Word;
wReserved1: Word;
wPIOTiming: Word;
wDMATiming: Word;
wBS: Word;
wNumCurrentCyls: Word;
wNumCurrentHeads: Word;
wNumCurrentSectorsPerTrack: Word;
ulCurrentSectorCapacity: ULONG;
wMultSectorStuff: Word;
ulTotalAddressableSectors: ULONG;
wSingleWordDMA: Word;
wMultiWordDMA: Word;
bReserved: array[0..127] of Byte;
end;
PIdSector = ^TIdSector;
IDEREGS = record
bFeaturesReg: BYTE; // Used for specifying SMART "commands".
bSectorCountReg: BYTE; // IDE sector count register
bSectorNumberReg: BYTE; // IDE sector number register
bCylLowReg: BYTE; // IDE low order cylinder value
bCylHighReg: BYTE; // IDE high order cylinder value
bDriveHeadReg: BYTE; // IDE drive/head register
bCommandReg: BYTE; // Actual IDE command.
bReserved: BYTE; // reserved for future use. Must be zero.
end;
SENDCMDINPARAMS = record
cBufferSize: DWORD;
irDriveRegs: IDEREGS;
bDriveNumber: BYTE;
bReserved: array[0..2] of BYTE;
dwReserved: array[0..3] of DWORD;
bBuffer: BYTE;
end;
DRIVERSTATUS = record
bDriverError: BYTE;
bIDEStatus: BYTE;
bReserved: array[0..1] of BYTE;
dwReserved: array[0..1] of DWORD;
end;
SENDCMDOUTPARAMS = record
cBufferSize: DWORD;
DriverStatus: DRIVERSTATUS;
bBuffer: BYTE;
end;
PSENDCMDOUTPARAMS = ^SENDCMDOUTPARAMS;
// ·O"C,?A`(c)O~^(1)?A*I"
TDiskExtent = record
DiskNumber: Cardinal;
StartingOffset: LARGE_INTEGER;
ExtentLength: LARGE_INTEGER;
end;
DISK_EXTENT = TDiskExtent;
PDiskExtent = ^TDiskExtent;
TVolumeDiskExtents = record
NumberOfDiskExtents: Cardinal;
Extents: array[0..0] of TDiskExtent;
end;
VOLUME_DISK_EXTENTS = TVolumeDiskExtents;
PVolumeDiskExtents = ^TVolumeDiskExtents;
function GetVolumeInfo(DriverLetter: Char; var DiskExtent: TDiskExtent): Integer;
implementation
function GetVolumeInfo(DriverLetter: Char; var DiskExtent: TDiskExtent): Integer;
var
hVolume: THandle;
DiskExtents: PVolumeDiskExtents;
dwOutBytes: Cardinal;
begin
Result := -1;
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
begin
DiskExtent := DiskExtents^.Extents[0];
Result := 0;
end
else
Result := -3;
end
else
Result := -2;
FreeMem(DiskExtents);
CloseHandle(hVolume);
end;
end.