硬盘格式化代码(delphi)-转载

转载地址:https://www.cnblogs.com/sunzh/archive/2008/12/10/1351602.html

 转载代码,未经测试,格式化为高危操作,请谨慎测试。

以下是我用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;


打赏
关键词: 硬盘格式化 delphi

0 评论

发表评论