ReadFile函数返回ERROR_INVALID_PARAMETER

时间:2015-07-29 10:01:53

标签: c winapi readfile

我正在尝试使用ReadFile函数。这是我的代码:

#define BUFFERSIZE 5

int main(int argc, char* argv[])
{
    OVERLAPPED overlapIn = {};
    HANDLE tHandle;
    char buf[BUFFERSIZE] = {};
    DWORD  lpNumberOfBytesRead;

    tHandle = CreateFile(
        L"\\\\.\\D:",
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (tHandle == INVALID_HANDLE_VALUE)
    {
        DWORD error = GetLastError();
        assert(0);
    }

    if (ReadFile(tHandle, &buf, BUFFERSIZE - 1, &lpNumberOfBytesRead, NULL) == 0)
    {
        int error = GetLastError();
        printf("Terminal failure: Unable to read from disk.\n GetLastError=%d\n", error);
        CloseHandle(tHandle);
        return 1;
    }

GetLastError函数返回代码87,即ERROR_INVALID_PARAMETER。

很明显,其中一个参数是错误的,但我不知道哪一个,因为我试图做一切像文档中所写的一样。

2 个答案:

答案 0 :(得分:3)

documentation for CreateFile

中对此进行了描述
  

即使未在CreateFile中指定非高速缓存选项,也可以根据特定文件系统的判断将卷句柄打开为非高速缓存。您应该假设所有Microsoft文件系统都将未处理的卷句柄打开。

MSDN article on File Buffering描述了非缓存句柄的要求:

  

文件访问大小(包括OVERLAPPED结构中的可选文件偏移量,如果指定)必须是多个字节,它是卷扇区大小的整数倍。例如,如果扇区大小为512字节,则应用程序可以请求读取和写入512,1024,1,536或2,048字节,但不能请求335,981或7,171字节。

     

用于读取和写入操作的文件访问缓冲区地址应该是物理扇区对齐的,这意味着在内存中的地址上对齐,该地址是卷的物理扇区大小的整数倍。根据磁盘的不同,可能不会强制执行此要求。

严格的代码应检查相关文件系统的扇区大小,然后使用this approach分配内存。但是,根据我的经验,扇区大小始终小于或等于分配粒度,因此您可以使用VirtualAlloc()来分配内存块。

答案 1 :(得分:0)

缓冲区大小需要与hdd sectorize对齐

WIN32_FIND_DATA atr = {0};
DWORD BYTES_PER_SECTOR;
char path[MAX_PATH];

/* get path length current dir */
const size_t len = GetCurrentDirectory(0, 0); 

/* set path to path char array */
GetCurrentDirectory(len, path);

/* windows function to get disk details */
GetDiskFreeSpace(NULL, NULL, &BYTES_PER_SECTOR, NULL, NULL); 

/* find first file in dir */
find = FindFirstFile(path, &atr);

for(;find != INVALID_HANDLE_VALUE;){

/* get the file size */
DWORD filesize = atr.nFileSizeLow;
  if(atr.nFileSizeHigh > 0){
                     filesize = atr.nFileSizeHigh;
                     filesize = (filesize << 31);
                     filesize = atr.nFileSizeLow;
                     }
 /* sector size aligned file size */
 size_t buffer_size = ((BYTES_PER_SECTOR + ((filesize + BYTES_PER_SECTOR)-1)) & ~(BYTES_PER_SECTOR -1));

 /* create buffer */
 DWORD buffer[buffer_size];                                                       

 /* create a new file or open an existing file */
 handle =   CreateFile(&path[0], GENERIC_READ | GENERIC_WRITE, 0 , NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL))!=INVALID_HANDLE_VALUE)

 /* read the file in to buffer */
 ReadFile(handle, (void*)&buffer, buffer_size, &bytesread, NULL)

if(FindNextFile(find, &atr)==0){ printf("last file processed, leaving\n");break;};
 } 
 CloseHandle(file);
 FindClose(find);