MapViewOfFile 返回错误 5 (ERROR_ACCESS_DENIED)
MapViewOfFile returns Error 5 (ERROR_ACCESS_DENIED)
我正在尝试开发一个使用共享内存进行两个进程之间通信的系统。一个进程是 32 位应用程序,使用 32 位 dll 进行通信。另一个进程是一个 64 位应用程序,使用 64 位 dll,其中包含用于创建/打开共享内存的完全相同的代码。我这样做是,每当一个进程打开内存的句柄并且无法打开它时,它就会自动尝试创建内存。然后,另一个进程将尝试相同的操作,因此首先运行代码的进程将创建内存,而另一个进程将打开现有内存的句柄。
当共享内存由 64 位进程/dll 创建时,代码绝对可以正常工作,但每当 32 位 dll 创建它时,我在调用 MapViewOfFile 时返回错误 5 (ERROR_ACCESS_DENIED)。
我已经检查了传递给任何函数的大小是否不同,例如,因为其中一个结构的大小不同,具体取决于它是编译为 32 位还是 64 位。但是,情况并非如此,两个过程中的大小始终相同。
我也尝试了本答案中建议的代码,但没有成功。 有谁知道为什么代码有时会因错误 5 而失败?
这是我的代码:
static LPVOID lpMappedInputData = nullptr,
lpMappedOutputData = nullptr;
static HANDLE hInputFileMapping = NULL,
hOutputFileMapping = NULL;
HANDLE createOrOpenFileMapping(DWORD size, LPCSTR lpName)
{
HANDLE hMapFile = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpName);
if (!hMapFile)
DEBUG_LOG("OpenFileMapping failed! Error code: %i - Attempting to create the file mapping instead...n", GetLastError());
if (!hMapFile)
{
hMapFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, lpName);
if (!hMapFile)
DEBUG_LOG("CreateFileMapping failed! Error code: %in", GetLastError());
}
return hMapFile;
}
LPVOID mapViewOfFile(HANDLE hFileMappingObject, DWORD size)
{
LPVOID lpMappedData = MapViewOfFile(hFileMappingObject, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size);
if (!lpMappedData)
{
CloseHandle(hFileMappingObject);
DEBUG_LOG("MapViewOfFile failed! Error code: %in", GetLastError());
}
return lpMappedData;
}
bool Initialize()
{
DEBUG_LOG("Initializing the input file mapping...n");
hInputFileMapping = createOrOpenFileMapping(sizeof(InputData), "Local\InputData");
if (!hInputFileMapping)
return false;
lpMappedInputData = mapViewOfFile(hInputFileMapping, sizeof(InputData));
if (!lpMappedInputData)
return false;
DEBUG_LOG("Initializing the output file mapping...n");
hOutputFileMapping = createOrOpenFileMapping(sizeof(OutputData), "Local\OutputData");
if (!hOutputFileMapping)
return false;
lpMappedOutputData = mapViewOfFile(hOutputFileMapping, sizeof(OutputData));
if (!lpMappedOutputData)
return false;
return true;
}
void Deinitialize()
{
DEBUG_LOG("Deinitializing the file mappings...n");
if (lpMappedInputData)
UnmapViewOfFile(lpMappedInputData);
if (hInputFileMapping)
CloseHandle(hInputFileMapping);
if (lpMappedOutputData)
UnmapViewOfFile(lpMappedOutputData);
if (hOutputFileMapping)
CloseHandle(hOutputFileMapping);
DEBUG_LOG("Successfully deinitialized the file mappings!n");
}
win32 错误 - 这是从原始NTSTATUS
本机 API 调用结果翻译而来的大多数转换。 但这种转换不是注入式的 - 有时许多不同的状态转换为相同的 Win32 错误值。 例如,将同一ERROR_ACCESS_DENIED
转换为至少 18(!) 不同的 NT状态。 所以原始错误可以不是STATUS_ACCESS_DENIED
而是绝对的另一个, 没有任何共同点与真正的访问被拒绝。因为这样,如果 Win32 API 调用是通过本机调用 shell - 总是最好调用RtlGetLastNtStatus
以获取原始错误状态代码或直接调用本机 API(ZwMapViewOfSection
而不是MapViewOfFile
)
不幸的是,我不知道ZwMapViewOfSection
返回的原始状态,但我想这是STATUS_INVALID_VIEW_SIZE
(尝试为大于该部分的部分创建视图。
在创建和映射部分中使用了sizeof(InputData)
和sizeof(OutputData)
- 代码中没有此结构的定义,BAT 基于
当共享内存由创建时,代码绝对可以正常工作 64 位进程/DLL,但每当 32 位 DLL 创建它时,我都会得到 调用
MapViewOfFile
时返回错误 5 (ERROR_ACCESS_DENIED
)。
我想接下来 - 在 32 位代码中InputData
或OutputData
具有较小的尺寸)比较 64 位代码)。这只是解释一切。如果 64 位代码首先创建部分,然后 32 位代码尝试映射较小的尺寸 - 这没关系。但是,如果 32 位代码首先创建部分,然后 64 位代码尝试将地图大小大于该部分大小 - 我们得到了STATUS_INVALID_VIEW_SIZE
转换为ERROR_ACCESS_DENIED
但是怎么样
我已经检查了大小是否..两者的大小总是相同的 过程。
不信。我被重新检查。
作为单独的注释 -CreateFileMapping
创建或打开命名或未命名的文件映射对象 指定的文件。
所以我们不需要特殊的函数createOrOpenFileMapping
并首先调用OpenFileMappingA
- 只需调用CreateFileMappingW
(A
API 有什么用? 以及createOrOpenFileMapping
的任何方式代码都有 RAISE 条件 - 两个进程都可以并发调用OpenFileMappingA
,并且都在这里失败。 无论如何,两者都调用CreateFileMappingA
但主要GetLastError()
有时不是最好的,ERROR_ACCESS_DENIED
并不总是STATUS_ACCESS_DENIED
并与实际访问被拒绝错误有关
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- 为什么调试器引发"read access violation. this was nullptr"异常?
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- Simulink "Access Violation"写入 C++ lambda 函数捕获列表中的 PWork 变量
- Qt QXmlStreamReader Access Violation
- "Access is Denied" U盘上的创建文件()
- 指向 std::unrodered_map 中元素的指针返回'Read access violation'
- 例外:'Access violation reading location'
- 向量数组"Cannot access memory at address"
- Windeployqt不会运行,"Access is denied."
- 我在发布模式下运行时收到"Access violation reading location"错误 - C++
- 获取交汇点的目标路径似乎总是以"Error 5 Access Denied"结尾
- 从 UMDF 驱动程序调用创建文件时出现'Access is denied'错误 (C++)
- 启动应用程序"Access denied" - Windows Vista
- 常见日志文件系统 API 的 RegisterManageableLogClient() 和"access is denied"错误
- CreateMutex -- "Access is denied"
- 尝试在 Cygwin 中通过 G++ 编译程序时收到"access is denied "消息
- 增强串行通信,COM端口被拒绝并出现错误"open: access is denied"
- 为什么 LoadUserProfile() 在系统服务中运行的此代码中失败并显示错误 5 "Denied Access"?
- 如何修复 Visual Studio 2012 和 VS community 2015 中的'Access denied'错误?