[英]Crash when calling ReadFile after LockFileEx
我有几个尝试读取和写入同一文件的进程。 我希望他们每个人都锁定文件,以便一次只能访问其中一个文件。
我试过了( 编辑:这次是完整的测试代码 ):
#include "stdafx.h"
#include "Windows.h"
bool test()
{
const char* path = "test.txt";
HANDLE hFile = CreateFileA(path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("ERROR: Cannot open file %s\n", path);
return false;
}
// Lock the file
{
OVERLAPPED overlapped = {0};
BOOL res = LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, ~0, ~0, &overlapped);
if (!res)
{
printf("ERROR: Cannot lock file %s\n", path);
return false;
}
}
DWORD fileSize = GetFileSize(hFile, NULL);
if (fileSize > 0)
{
char* content = new char[fileSize+1];
// Read the file
BOOL res = ReadFile(hFile, content, fileSize, NULL, NULL);
if (!res)
{
printf("ERROR: Cannot read file %s\n", path);
}
delete[] content;
}
const char* newContent = "bla";
int newContentSize = 3;
// Write the file
BOOL res = WriteFile(hFile, newContent, newContentSize, NULL, NULL);
if (!res)
{
//int err = GetLastError();
printf("ERROR: Cannot write to file\n");
}
// Unlock the file
{
OVERLAPPED overlapped = {0};
UnlockFileEx(hFile, 0, ~0, ~0, &overlapped);
}
CloseHandle(hFile);
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
bool res = test();
return 0;
}
在装有Windows 8的计算机上,这可以正常工作。但是,在装有Windows 7的同事的计算机上,它崩溃了。 具体来说,对ReadFile和WriteFile的调用总是崩溃。
请注意,它永远不会输入带有错误printfs的代码路径。 除了在ReadFile 中的位置0x00000000上执行写操作 (在Windows 7上运行)之外,此代码不会触发任何错误。
我们还尝试将重叠的结构传递给ReadFile和WriteFile调用。 它可以防止崩溃,但是锁不再起作用,文件都被加密了(不是使用此测试代码,而是使用真实代码)。
我究竟做错了什么?
看来您的问题是:
lpNumberOfBytesRead [输出,可选]参数在您的调用中为null。
仅当lpOverlapped参数不为NULL时,此参数才能为NULL。
http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa365467%28v=vs.85%29.aspx
这是您的问题:
您缺少必要的struct-member 和 :
0
和~0
和{0}
都是不好的代码 ,这样的常量表达式总是会产生unepected结果- WINAPI不起作用喜欢的libc, 参数并不总是对常量进行比较 ,而不是他们对测试/通过宏和其他preprocessor-定义本身,因此传递常量值或用常量初始化WINAPI结构常常会导致此类错误 。
经过多年的试验,我发现只有一种避免这种情况的方法,我将用更正的代码表示:
OVERLAPPED overlapped;
overlapped.hEvent = CreateEvent( ........... ); // put valid parameters here!
UnlockFileEx(hFile, 0 /*"reserved"*/, ULONG_MAX, ULONG_MAX, &overlapped);
请仔细阅读以下内容: http : //msdn.microsoft.com/zh-cn/library/windows/desktop/aa365716%28v=vs.85%29.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.