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

来源:互联网 发布:兵器推演软件 编辑:程序博客网 时间:2024/05/21 10:10

使用函数
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;}