首页  编辑  

磁盘物理驱动器

Tags: /超级猛料/Hardware.硬件相关/驱动器相关/硬盘/   Date Created:

硬盘分区和物理硬盘的对应关系?

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.