从群集中读取数据

时间:2014-06-11 15:28:40

标签: c++ winapi file-io

我需要帮助使用CreateFile()从文件的最后一个群集中读取数据,然后使用ReadFile()。首先,我对ReadFile()的结果为零,因为我认为我在CreateFile()中设置的权限不正确。

/**********CreateFile for volume ********/

        HANDLE hDevice = INVALID_HANDLE_VALUE;            
            hDevice = CreateFile(L"\\\\.\\C:",    
            0,                
            FILE_SHARE_READ | 
            FILE_SHARE_WRITE,
            NULL,             
            OPEN_EXISTING,    
            0,                
            NULL);            

        if (hDevice == INVALID_HANDLE_VALUE)    
        {
            wcout << "error at hDevice at CreateFile "<< endl;
            system("pause");
        }

        /******* Read file from the volume *********/
        DWORD nRead;
        TCHAR buff[4096];
        if (BOOL fileFromVol = ReadFile(
            hDevice,
            buff,
            4096,
            &nRead,
            NULL
            ) == 0) {
            cout << "Error with fileFromVol" << "\n\n";
            system("pause");
        }

接下来,我将获得所需的所有集群信息和文件信息(文件大小,文件的最后一个集群位置,磁盘上的集群数,集群大小等)。如何将卷上的指针设置为从指定的群集位置开始,以便从中读取/写入数据?

2 个答案:

答案 0 :(得分:3)

主要问题是您为0指定了dwDesiredAccess。要读取数据,您应指定FILE_READ_DATA

最重要的是,我严肃地质疑TCHAR的用法。当您需要支持Windows 9x时,这适用于文本。除了不需要支持Windows 9x之外,数据不是文本。您的缓冲区应为unsigned char类型。

显然,您需要缓冲区是群集大小的倍数。您已经硬编码4096,但真正的代码肯定会查询群集大小。

当这些API调用中的任何一个失败时,它们会指示上一个错误值中的失败原因。您可以致电GetLastError获取。当ReadFile失败时,它会返回ERROR_ACCESS_DENIED

您可以致电SetFilePointerEx查询该卷。同样,您需要寻找簇大小的倍数。

LARGE_INTEGER dist;
dist.QuadPart = ClusterNum * ClusterSize;
BOOL res = SetFilePointerEx(hFile, dist, nullptr, FILE_BEGIN);
if (!res)
    // handle error

如果您按顺序阅读,则无需设置文件指针。拨打ReadFile会自动提前。

答案 1 :(得分:1)

在进行随机访问I / O时,根本不要弄乱存储在文件句柄中的文件指针。而是使用OVERLAPPED结构并指定每个I / O操作的位置。

这甚至适用于同步I / O(如果文件是在没有FILE_FLAG_OVERLAPPED的情况下打开的。)

当然,正如David所说,如果使用在没有足够访问权限的情况下打开的文件句柄执行操作,您将获得ERROR_ACCESS_DENIED