首页
社区
课程
招聘
[求助]给文件绝对路径,能否得到文件再磁盘的起始位置(簇,扇区)信息
发表于: 2016-2-4 16:35 4407

[求助]给文件绝对路径,能否得到文件再磁盘的起始位置(簇,扇区)信息

2016-2-4 16:35
4407
给出文件绝对路径,能否得到文件再磁盘的起始位置(簇,扇区)信息
类似于如下伪代码

GetFileInDeviceInfo(char* 文件路径)
{
    //得到磁盘所在起始簇号

    //簇连

    //簇结束位置
   。。。。
}

问题如标题

用户层或者驱动层是否有相关参考代码,在此感谢各位了!


在下只找到类似于这样的源码,还能有更详细的源码不
使用函数
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
支持
分享
最新回复 (2)
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
在CSDN中找到如下一个URL:http://www.codeproject.com/KB/files/FDump.aspx,楼主可看一下是否能够满足要求。
2016-2-5 11:33
0
雪    币: 24
活跃值: (1353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢,我把分都给你,应该是解决了
2016-2-5 16:56
0
游客
登录 | 注册 方可回帖
返回
//