繁体   English   中英

LockFileEx之后调用ReadFile时崩溃

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM