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

使用函数
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; }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值