当您尝试写入到网络共享文件夹中的文件时出现"ERROR_ACCESS_DENIED"错误


重要:本文包含有关修改注册表的信息。在修改注册表之前,请确保备份,并且确保您了解如何在发生问题时还原注册表。有关如何备份、 还原和编辑注册表的信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章︰
Microsoft Windows 注册表256986说明

症状


WriteFile函数的调用可能会失败。满足以下条件时,您会遇到这种症状︰
  • 您正在使用的客户端计算机正在运行 Microsoft Windows XP Service Pack 1 (SP1)。
  • 使用写文件函数尝试写入到网络共享文件夹中的文件。
  • 共享的文件夹是在运行 Microsoft Windows 2000 或 Microsoft Windows Server 2003 的服务器计算机上。
此外,您可能会收到以下错误消息︰
ERROR_ACCESS_DENIED

原因


满足以下条件时,会发生此问题:
  • 当您使用CreateFile函数来创建该文件时,则dwDesiredAccess参数中指定仅 GENERIC_WRITE 常数。
  • 服务器消息块 (SMB) 签名被启用客户端计算机和服务器计算机之间的通信。

解决方法


若要解决此问题,请使用下列方法之一:
  • dwDesiredAccess参数中指定的 GENERIC_READ 常量和 GENERIC_WRITE 常量。
  • 修改 SMB 签名。

在 dwDesiredAccess 参数中指定的 GENERIC_READ 常量和 GENERIC_WRITE 常量

下面的代码用于创建该文件。

注意:将替换以下占位符︰
  • 服务器名称的占位符替换为正在运行 Windows 2000 或 Windows Server 2003 的服务器计算机的名称。
  • 文件夹名称的占位符替换为服务器计算机上的网络共享文件夹的名称。
// Specify the GENERIC_READ constant and the GENERIC_WRITE constant
// in the dwDesiredAccess parameter when you create the file.
hFile = CreateFile("\\\\ServerName\\FolderName\\Test.txt", GENERIC_READ |
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

修改 SMB 签名

警告如果您使用注册表编辑器不当,可能会导致严重的问题,可能需要您重新安装操作系统。Microsoft 不能保证您可以解决导致注册表编辑器使用不当的问题。由您自己承担使用注册表编辑器所带来的风险。
在服务器计算机上,并在客户端计算机上,请执行以下步骤︰
  1. 在注册表编辑器中,找到并单击以下注册表子项︰
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Lanmanserver\Parameters
  2. 在注册表编辑器的右窗格中,右键单击
    requiresecuritysignature名称字段中,然后再单击修改。此时将显示编辑 DWORD 值对话框。
  3. 数值数据框中,键入
    0,然后单击确定
  4. 退出注册表编辑器,然后重新启动计算机。

详细信息


再现现象的步骤

  1. 在计算机上运行 Windows XP SP1,使用 Microsoft Visual C++ 6.0 创建名为测试一个简单的 Win32 控制台应用程序项目。默认情况下,创建的 Test.cpp 文件。
  2. 通过在dwDesiredAccess参数中指定仅 GENERIC_WRITE 常数,使用CreateFile函数时创建的文件。
  3. 使用
    写文件函数尝试写入该文件。若要执行此操作,请用下面的代码替换 Test.cpp 文件中的现有代码。

    注意:将替换以下占位符︰
    • 服务器名称的占位符替换为正在运行 Windows 2000 或 Windows Server 2003 的服务器计算机的名称。
    • 文件夹名称的占位符替换为服务器计算机上的网络共享文件夹的名称。
    :
    #include "stdafx.h"
    #include "windows.h"
    #include "stdio.h"
    #include "conio.h"

    void main()
    {
    HANDLE hFile;
    char lpBuffer[99999];
    DWORD lpNumberOfBytesWritten;

    // Write data to the buffer that you will
    // you use to write data to the file.
    for (int i = 0; i < 100000; ++i)
    lpBuffer[i] = 'a';

    // Specify only the GENERIC_WRITE constant in the
    // dwDesiredAccess parameter when you create the file.
    hFile = CreateFile("\\\\ServerName\\FolderName\\Test.txt",
    GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    // Try to write the data in the buffer to the file.
    // If the call to the WriteFile function fails,
    // call the GetLastError function.
    if (!WriteFile(hFile, lpBuffer, 100000, &lpNumberOfBytesWritten, NULL))

    // If an ERROR_ACCESS_DENIED error has occurred, inform the user.
    if (GetLastError() == ERROR_ACCESS_DENIED)
    {
    printf("An ERROR_ACCESS_DENIED error has occurred.");
    printf("Press any key to continue.");
    getch();
    }

    // Close the handle to the file.
    CloseHandle(hFile);
    }
  4. 生成并运行该应用程序。控制台窗口出现。如果出现"症状"一节中提到的行为,控制台窗口包含以下输出︰
    发生 ERROR_ACCESS_DENIED 错误。
    请按任意键继续。

参考资料


有关CreateFile函数的详细信息,
写文件正常工作,请访问下面的 Microsoft 开发人员网络 (MSDN) 的网站︰