unit RawRead;
interface
uses
Windows, Math, Forms, Dialogs, SysUtils;
const
FILE_READ_ATTRIBUTES = $80;
FSCTL_GET_RETRIEVAL_POINTERS = 589939; //(($00000009) shr 16) or ((28) shr 14) or ((3) shr 2) or (0);
type
ULONGLONG = ULONG;
PULONGLONG = ^ULONGLONG;
TClusters = array of LONGLONG;
STARTING_VCN_INPUT_BUFFER = record
StartingVcn: LARGE_INTEGER;
end;
PSTARTING_VCN_INPUT_BUFFER = ^STARTING_VCN_INPUT_BUFFER;
Extents = record
NextVcn: LARGE_INTEGER;
Lcn: LARGE_INTEGER;
end;
RETRIEVAL_POINTERS_BUFFER = record
ExtentCount: DWORD;
StartingVcn: LARGE_INTEGER;
Extents: array[0..0] of Extents;
Cn029.Com 为西安网吧努力 end;
PRETRIEVAL_POINTERS_BUFFER = ^RETRIEVAL_POINTERS_BUFFER;
Function FileCopyEx(lpSrcName: PChar; lpDstName: PChar; var Progress: DWORD): Boolean;
implementation
function GetFileClusters(lpFileName: PChar; ClusterSize: Int64; ClCount: PInt64; var FileSize: Int64): TClusters;
var
hFile: THandle;
OutSize: ULONG;
Bytes, Cls, CnCount, r: ULONG;
Clusters: TClusters;
PrevVCN, lcn: LARGE_INTEGER;
InBuf: STARTING_VCN_INPUT_BUFFER;
OutBuf: PRETRIEVAL_POINTERS_BUFFER;
begin
Clusters := nil;
hFile := CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil, OPEN_EXISTING, 0, 0);
if (hFile <> INVALID_HANDLE_VALUE) then
begin
FileSize := GetFileSize(hFile, nil);
Cn029.Com 为西安网吧努力
OutSize := SizeOf(RETRIEVAL_POINTERS_BUFFER) + (FileSize div ClusterSize) * SizeOf(OutBuf^.Extents);
GetMem(OutBuf, OutSize);
InBuf.StartingVcn.QuadPart := 0;
if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, @InBuf,
SizeOf(InBuf), OutBuf, OutSize, Bytes, nil)) then
begin
ClCount^ := (FileSize + ClusterSize - 1) div ClusterSize;
SetLength(Clusters, ClCount^);
PrevVCN := OutBuf^.StartingVcn;
Cls := 0;
r := 0;
while (r < OutBuf^.ExtentCount) do
begin
Lcn := OutBuf^.Extents[r].Lcn;