来由:我想在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;
问题:复制完毕的硬盘可以看到主分区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;
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货