来由:我想在WINDOWS2000/XP下对2个物理硬盘进行按磁道拷贝,查了一下资料说WIN2000/XP下物理硬盘可以当作一个FILE来进行操作,因此写了一下代码。
问题:复制完毕的硬盘可以看到主分区C和扩展分区,但看不到逻辑分区(d、E、F等),在主分区C中有些文件夹名出现问题打不开,而且有些文件也存在乱码的问题。按道理说我做的是按磁道拷贝,拷贝完后的硬盘与源盘应该一摸一样才对啊,望高手解惑!!
代码:
var
  SectorCount:integer; //每次读取扇区个数
  SourceDrive:PChar;  //源盘
  TagetDrive:Pchar;    //目标盘
  P:Pointer;       //缓冲区
  SectorStart:integer; //开始复制的扇区数
  repeatcount,i:integer;
begin
  SectorCount:=256; //一次复制256个扇区
  SourceDrive:=PChar('\\.\PHYSICALDRIVE0');  //源盘为第一个物理硬盘
  TagetDrive:=PChar('\\.\PHYSICALDRIVE1');  //目标盘为第二个物理硬盘  hDeviceHandle := CreateFile(SourceDrive,  //源盘句柄
                              GENERIC_READ,  //如果只是读扇区,可以用GENERIC_READ
                              FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,0, 0);
  tDeviceHandle:= CreateFile(TagetDrive,   //目标盘句柄
                              GENERIC_All,  //如果只是读扇区,可以用GENERIC_READ
                              FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,0, 0);  if (hDeviceHandle <> INVALID_HANDLE_VALUE) and (tDeviceHandle <> INVALID_HANDLE_VALUE)then
  begin
  try
    SectorStart:=0;  //从第一个扇区开始
    RepeatCount:=(EndSector-SectorStart) div SectorCount;  //循环次数
    P:=allocmem(SectorCount*BytesPerSector+1); //申请新的内存空间
    for i:=0 to repeatcount do
    begin
      FileSeek(hDevicehandle,SectorStart*BytesPerSector,0); //查找指定扇区数据
      if FileRead(hDevicehandle,p^,SectorCount*BytesPerSector)<>SectorCount*BytesPerSector then
       Break;   //如果读取数不对,停止      FileSeek(tDevicehandle,SectorStart*BytesPerSector,0);
     if FileWrite(tDevicehandle,p^,SectorCount*BytesPerSector)<>SectorCount*BytesPerSector then
       break;    //如果写入数不对,停止
      Inc(SectorStart,SectorCount);
    end;
    freemem(p,SectorCount*BytesPerSector+1);    //剩余的字节数不到一个标准缓冲时候
    repeatcount:=(EndSector-StartSector) mod SectorCount;
    if repeatcount<>0 then     //如果剩余的扇区数不足SectorCount个扇区时,复制剩余扇区
    begin
      P:=allocmem(repeatcount*BytesPerSector+1); //申请新的内存空间
      FileSeek(hDevicehandle,SectorStart*BytesPerSector,0); //查找制定扇区数据
      if FileRead(hDevicehandle,p^,repeatcount*BytesPerSector)<>repeatcount*BytesPerSector then
      begin
        Self.Terminate;
        Exit;
      end;
      FileSeek(tDevicehandle,SectorStart*BytesPerSector,0);
     if FileWrite(tDevicehandle,p^,repeatcount*BytesPerSector)<>repeatcount*BytesPerSector then
      begin
        Self.Terminate;
        Exit;
      end;
      freemem(p,repeatcount*BytesPerSector+1);
    end;  finally
    closehandle(hDeviceHandle);
    closehandle(tDeviceHandle);
  end;
end;
end;