以下是我用delphi写的硬盘分区代码
Const
IOCTL_DISK_BASE = $00000007;
IOCTL_DISK_GET_DRIVE_GEOMETRY = $00070000;
IOCTL_DISK_GET_PARTITION_INFO = $00074004;
IOCTL_DISK_SET_PARTITION_INFO = $0007C008;
IOCTL_DISK_GET_DRIVE_LAYOUT = $0007400C;
IOCTL_DISK_SET_DRIVE_LAYOUT = $0007C010;
IOCTL_DISK_VERIFY = $00070014;
IOCTL_DISK_FORMAT_TRACKS = $0007C018;
IOCTL_DISK_REASSIGN_BLOCKS = $0007C01C;
IOCTL_DISK_PERFORMANCE = $00070020;
IOCTL_DISK_IS_WRITABLE = $00070024;
IOCTL_DISK_LOGGING = $00070028;
IOCTL_DISK_FORMAT_TRACKS_EX = $0007C02C;
IOCTL_DISK_HISTOGRAM_STRUCTURE = $00070030;
IOCTL_DISK_HISTOGRAM_DATA = $00070034;
IOCTL_DISK_HISTOGRAM_RESET = $00070038;
IOCTL_DISK_REQUEST_STRUCTURE = $0007003C;
IOCTL_DISK_REQUEST_DATA = $00070040;
IOCTL_DISK_PERFORMANCE_OFF = $00070060;
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = $00560000;
IOCTL_VOLUME_IS_CLUSTERED = $00560030;
type
_MEDIA_TYPE=(DDS_4mm = $20,MiniQic,
Travan,
QIC,
MP_8mm,
AME_8mm, // Tape - 8mm Exabyte Advanced Metal Evap
AIT1_8mm, // Tape - 8mm Sony AIT
DLT, // Tape - DLT Compact IIIxt, IV
NCTP, // Tape - Philips NCTP
IBM_3480, // Tape - IBM 3480
IBM_3490E, // Tape - IBM 3490E
IBM_Magstar_3590, // Tape - IBM Magstar 3590
IBM_Magstar_MP, // Tape - IBM Magstar MP
STK_DATA_D3, // Tape - STK Data D3
SONY_DTF, // Tape - Sony DTF
DV_6mm, // Tape - 6mm Digital Video
DMI, // Tape - Exabyte DMI and compatibles
SONY_D2, // Tape - Sony D2S and D2L
CLEANER_CARTRIDGE, // Cleaner - All Drive types that support Drive Cleaners
CD_ROM, // Opt_Disk - CD
CD_R, // Opt_Disk - CD-Recordable (Write Once)
CD_RW, // Opt_Disk - CD-Rewriteable
DVD_ROM, // Opt_Disk - DVD-ROM
DVD_R, // Opt_Disk - DVD-Recordable (Write Once)
DVD_RW, // Opt_Disk - DVD-Rewriteable
MO_3_RW, // Opt_Disk - 3.5" Rewriteable MO Disk
MO_5_WO, // Opt_Disk - MO 5.25" Write Once
MO_5_RW, // Opt_Disk - MO 5.25" Rewriteable (not LIMDOW)
MO_5_LIMDOW, // Opt_Disk - MO 5.25" Rewriteable (LIMDOW)
PC_5_WO, // Opt_Disk - Phase Change 5.25" Write Once Optical
PC_5_RW, // Opt_Disk - Phase Change 5.25" Rewriteable
PD_5_RW, // Opt_Disk - PhaseChange Dual Rewriteable
ABL_5_WO, // Opt_Disk - Ablative 5.25" Write Once Optical
PINNACLE_APEX_5_RW, // Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical
SONY_12_WO, // Opt_Disk - Sony 12" Write Once
PHILIPS_12_WO, // Opt_Disk - Philips/LMS 12" Write Once
HITACHI_12_WO, // Opt_Disk - Hitachi 12" Write Once
CYGNET_12_WO, // Opt_Disk - Cygnet/ATG 12" Write Once
KODAK_14_WO, // Opt_Disk - Kodak 14" Write Once
MO_NFR_525, // Opt_Disk - Near Field Recording (Terastor)
NIKON_12_RW, // Opt_Disk - Nikon 12" Rewriteable
IOMEGA_ZIP, // Mag_Disk - Iomega Zip
IOMEGA_JAZ, // Mag_Disk - Iomega Jaz
SYQUEST_EZ135, // Mag_Disk - Syquest EZ135
SYQUEST_EZFLYER, // Mag_Disk - Syquest EzFlyer
SYQUEST_SYJET, // Mag_Disk - Syquest SyJet
AVATAR_F2, // Mag_Disk - 2.5" Floppy
MP2_8mm, // Tape - 8mm Hitachi
DST_S, // Ampex DST Small Tapes
DST_M, // Ampex DST Medium Tapes
DST_L, // Ampex DST Large Tapes
VXATape_1, // Ecrix 8mm Tape
VXATape_2, // Ecrix 8mm Tape
STK_9840, // STK 9840
LTO_Ultrium, // IBM, HP, Seagate LTO Ultrium
LTO_Accelis, // IBM, HP, Seagate LTO Accelis
DVD_RAM, // Opt_Disk - DVD-RAM
AIT_8mm, // AIT2 or higher
ADR_1, // OnStream ADR Mediatypes
ADR_2
);
MEDIA_TYPE = _MEDIA_TYPE;
_DISK_GEOMETRY = Record
Cylinders: LARGE_INTEGER;
MediaType: MEDIA_TYPE;
TracksPerCylinder: DWORD;
SectorsPerTrack: DWORD;
BytesPerSector: DWORD;
end;
DISK_GEOMETRY = _DISK_GEOMETRY;
PDISK_GEOMETRY = ^_DISK_GEOMETRY;
_DISK_EXTENT = Record
DiskNumber: DWORD;
StartingOffset: LARGE_INTEGER;
ExtentLength: LARGE_INTEGER;
end;
DISK_EXTENT = _DISK_EXTENT;
PDISK_EXTENT = ^_DISK_EXTENT;
_VOLUME_DISK_EXTENTS = Record
NumberOfDiskExtents: DWORD;
Extents: DISK_EXTENT;
end;
VOLUME_DISK_EXTENTS = _VOLUME_DISK_EXTENTS;
PVOLUME_DISK_EXTENTS = ^_VOLUME_DISK_EXTENTS;
Function fDisk(DiskID: Integer):Boolean;
var
hDevice: THandle;
Tracks,Sectors,Cylinder:DWORD;
hdevicename: AnsiString;
geometry: DISK_GEOMETRY;
labOffset: OVERLAPPED;
count: DWORD;
dwLen: DWORD;
pBuffer: array[0..511] of byte;
PhysicalSectors,PhysicalTracks,PhysicalCylinders,PhysicalSectorsTmp: DWORD;
CylindersOffet,TracksOffet,SectorOffet:DWORD;
CylinderTemp: DWORD; //临时保留了柱面的高2位+扇区号的低6位+柱面的低8位
StartLogicSector: DWORD;
SectorsSum: DWORD;
i: Integer;
str: String;
bRet: Boolean;
sei: SHELLEXECUTEINFO;
szFile: AnsiString;
hHnd: THandle;
begin
Tracks := 1; //起始磁头
Sectors := 1; //起始扇区
Cylinder := 0; //起始柱面
hdevicename := Format('\\.\PHYSICALDRIVE%d',[DiskID]);
hDevice := CreateFile(pchar(hdevicename),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if hDevice=INVALID_HANDLE_VALUE then
begin
Result := False;
Exit;
end;
if (not DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,nil,0,@geometry,sizeof(geometry),count,nil)) then
begin
Result := False;
CloseHandle(hDevice);
Exit;
end;
FillChar(pBuffer,sizeof(pBuffer),#0);
//读取第一扇区
ZeroMemory(@labOffset,sizeof(labOffset));
labOffset.Offset := 1;
ReadFile(hDevice, pBuffer, 512, dwLen, @labOffset);
//0~445字节为引导记录,446~509,为分区表信息占64个字节,510~511为结束标志55AA,占两个字节
pBuffer[446] := $00; //活动分区
PhysicalSectorsTmp := (MaxFileSize+511) div geometry.BytesPerSector; //物理区理论占用的扇区数,从下一磁头开始
PhysicalCylinders := PhysicalSectorsTmp div (geometry.SectorsPerTrack * geometry.TracksPerCylinder)+1; //物理占用的柱面数
PhysicalTracks := (PhysicalSectorsTmp mod (geometry.SectorsPerTrack * geometry.TracksPerCylinder)) div geometry.SectorsPerTrack; //物理区占用的磁头数
PhysicalSectors := geometry.SectorsPerTrack * PhysicalCylinders * geometry.TracksPerCylinder; //物理区实际上占用的扇区数
Tracks := Tracks+PhysicalTracks; //起始磁头
Sectors := 1; //起始扇区
//Cylinder = Cylinder + (PhysicalSectorsTmp-1)/(geometry.TracksPerCylinder * geometry.SectorsPerTrack) + 1; //起始柱面
Cylinder := Cylinder+PhysicalCylinders; //起始柱面
//起始地址
pBuffer[447] := 0;//磁头号
CylinderTemp := ((((Cylinder shr 2) and $C0) or (Sectors and $3F)) shl 8) or (Cylinder and $00FF);
pBuffer[448] := CylinderTemp shr 8; //右移8位取柱面的高2位+扇区号的低6位
pBuffer[449] := CylinderTemp;
//磁盘格式
pBuffer[450] := $0C; //Fat32格式
//结束地址
CylindersOffet := geometry.Cylinders.LowPart-1; //结束柱面号
//CylindersOffet = 1023;
TracksOffet := geometry.TracksPerCylinder-1; //结束磁头号
SectorOffet := geometry.SectorsPerTrack; //结束扇区号
pBuffer[451] := TracksOffet;
CylinderTemp := ((((CylindersOffet shr 2) and $C0) or (SectorOffet and $3F)) shl 8) or (CylindersOffet and $00FF);
pBuffer[452] := CylinderTemp shr 8;
pBuffer[453] := CylinderTemp;
//设置逻辑扇区号
StartLogicSector := PhysicalSectors;
//StartLogicSector = 63;
pBuffer[454] := StartLogicSector;
pBuffer[455] := StartLogicSector shr 8;
pBuffer[456] := StartLogicSector shr 16;
pBuffer[457] := StartLogicSector shr 24;
//总扇区数
SectorsSum := geometry.Cylinders.LowPart*geometry.TracksPerCylinder*geometry.SectorsPerTrack;
SectorsSum := SectorsSum - PhysicalSectors;
//SectorsSum = SectorsSum - 62- geometry.SectorsPerTrack;
pBuffer[458] := SectorsSum;
pBuffer[459] := SectorsSum shr 8;
pBuffer[460] := SectorsSum shr 16;
pBuffer[461] := SectorsSum shr 24;
//没别其它分区
for i := 462 to 509 do
pBuffer[i] := $0;
//结束标志
pBuffer[510] := $55;
pBuffer[511] := $AA;
str := '';
//for(int j=0;j<512;j++)
// str+=IntToHex(pBuffer[j];
//ShowMessage(str);
//memset(&labOffset,0,sizeof(labOffset));
FillChar(labOffset,sizeof(labOffset),0);
labOffset.Offset := 1;
bRet := WriteFile(hDevice, pBuffer, 512, dwLen, @labOffset); //写入分区表
CloseHandle(hDevice);
if (bRet) then
begin
FillChar(sei,sizeof(sei),0);
szFile := 'C:\WINNT\system32\Diskmgmt.msc';
if (not FileExists(szFile) ) then
begin
Result := False;
MessageDlg('无法找到硬盘管理工具',mtWarning,[mbok],0);
end;
sei.cbSize := sizeof(SHELLEXECUTEINFO);
sei.fMask := SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb := 'open'+#0;
sei.lpFile := Pchar(szFile);
sei.lpParameters := '';
sei.nShow := SW_SHOWNORMAL; //SW_SHOWNORMAL; //SW_SHOWDEFAULT; //SW_HIDE
bRet := ShellExecuteExA(@sei);
if (bRet) then
begin
hHnd := INVALID_HANDLE_VALUE;
bRet := FALSE;
for i := 0 to 100 do
begin
Sleep(300);
if (not bRet) then
begin
hHnd := FindWindow(nil, '磁盘管理');
bRet := SetWindowPos(hHnd, HWND_BOTTOM, 0, 0, 50, 50, SWP_HIDEWINDOW);
end;
Application.ProcessMessages();
end;
TerminateProcess(sei.hProcess,1);
CloseHandle(sei.hProcess);
end;
Result := True;
end;
Result := False;
end;