使用函数
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; }
本文介绍了一个利用Windows API函数DeviceIoControl来获取文件的簇链信息的方法,并提供了一个具体的C/C++代码示例,展示了如何通过读取磁盘扇区来复制文件。

8916

被折叠的 条评论
为什么被折叠?



