您的位置:首页 > 其它

直接读取扇区来拷贝文件的例子

2011-05-26 23:08 399 查看
使用函数
DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
就可以查询文件的簇链

下面是个例如直接读取扇区来拷贝文件的例子
用法:FileCopy("C://boot.ini", "D://boot.ini");

C/C++ code
ULONGLONG *GetFileClusters(
LPCSTR lpFileName,
ULONG ClusterSize,
ULONG *ClCount,
ULONG *FileSize
)
{
HANDLE  hFile;
ULONG   OutSize;
ULONG   Bytes, Cls, CnCount, r;
ULONGLONG *Clusters = NULL;
BOOLEAN Result = FALSE;
LARGE_INTEGER PrevVCN, Lcn;
STARTING_VCN_INPUT_BUFFER  InBuf;
PRETRIEVAL_POINTERS_BUFFER OutBuf;

hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
*FileSize = GetFileSize(hFile, NULL);

OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (*FileSize / ClusterSize) * sizeof(OutBuf->Extents);

OutBuf = (PRETRIEVAL_POINTERS_BUFFER)malloc(OutSize);

InBuf.StartingVcn.QuadPart = 0;

if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
{
*ClCount = (*FileSize + ClusterSize - 1) / ClusterSize;

Clusters = (PULONGLONG)malloc(*ClCount * sizeof(ULONGLONG));

PrevVCN = OutBuf->StartingVcn;

for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
{
Lcn = OutBuf->Extents[r].Lcn;

for (CnCount = (ULONG)(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart);
CnCount; CnCount--, Cls++, Lcn.QuadPart++) Clusters[Cls] = Lcn.QuadPart;

PrevVCN = OutBuf->Extents[r].NextVcn;
}
}

free(OutBuf);

CloseHandle(hFile);
}

return Clusters;
}

BOOL FileCopy(LPCSTR lpSrcName, LPCSTR lpDstName)
{
BOOL bResult = FALSE;

ULONG         ClusterSize, BlockSize;
ULONGLONG    *Clusters;
ULONG         ClCount, FileSize, Bytes;
HANDLE        hDrive, hFile;
ULONG         SecPerCl, BtPerSec, r;
PVOID         Buff;
LARGE_INTEGER Offset;
CHAR          Name[7];

Name[0] = lpSrcName[0];
Name[1] = ':';
Name[2] = 0;

GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL);

ClusterSize = SecPerCl * BtPerSec;

Clusters = GetFileClusters(lpSrcName, ClusterSize, &ClCount, &FileSize);
if(Clusters)
{
Name[0] = '//';
Name[1] = '//';
Name[2] = '.';
Name[3] = '//';
Name[4] = lpSrcName[0];
Name[5] = ':';
Name[6] = 0;

hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (hDrive != INVALID_HANDLE_VALUE)
{
hFile = CreateFile(lpDstName, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
Buff = malloc(ClusterSize);

for (r = 0; r < ClCount; r++, FileSize -= BlockSize)
{
Offset.QuadPart = ClusterSize * Clusters[r];

SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);

ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL);

BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize;

WriteFile(hFile, Buff, BlockSize, &Bytes, NULL);
}

free(Buff);

CloseHandle(hFile);

bResult = TRUE;
}

CloseHandle(hDrive);
}

free(Clusters);
}
else
{
printf("GetFileClusters fail./n");
}

return bResult;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: