简体   繁体   English

MapViewOfFile返回错误5(ERROR_ACCESS_DENIED)

[英]MapViewOfFile returns Error 5 (ERROR_ACCESS_DENIED)

I'm trying to develop a system that uses shared memory for communication between two processes. 我正在尝试开发一个使用共享内存在两个进程之间进行通信的系统。 One process is a 32 bit application and uses a 32bit dll for the communication. 一个进程是一个32位应用程序,并使用32位dll进行通信。 The other process is a 64 bit application and uses a 64 bit dll which contains the exact same code for creating/opening the shared memory. 另一个过程是一个64位应用程序,并使用一个64位dll,其中包含与创建/打开共享内存完全相同的代码。 I made it so whenever one process opens a handle to the memory and cannot open it, it automatically tries to create the memory. 我这样做的目的是,只要一个进程打开了内存的句柄而无法打开它,它就会自动尝试创建内存。 The other process will then try the same so whichever process runs the code first will create the memory while the other process will open a handle to the already existing memory. 然后另一个进程将尝试相同的操作,因此无论哪个进程先运行代码,都将创建内存,而另一个进程将打开已存在内存的句柄。

The code works absolutely fine when the shared memory is created by the 64 bit process/dll but whenever the 32 bit dll creates it, I get error 5 (ERROR_ACCESS_DENIED) returned when calling MapViewOfFile. 当共享内存由64位进程/ dll创建时,代码工作得非常好,但是每当32位dll创建共享内存时,调用MapViewOfFile时都会返回错误5(ERROR_ACCESS_DENIED)。

I already checked if the size that I pass to any of the functions is different, for example because one of the structures has a different size depending on if it was compiled for 32 bit or 64 bit. 我已经检查了传递给任何函数的大小是否不同,例如,因为其中一个结构具有不同的大小取决于它是为32位还是64位编译的。 However, this is not the case, the size is always the same in both processes. 但是,事实并非如此,两个过程的大小始终相同。

I also tried the code that was suggested in this answer without success. 我也尝试了答案中建议的代码,但未成功。 Does anyone have an idea why the code sometimes fails with error 5? 有谁知道为什么代码有时会因错误5而失败?

Here is my code: 这是我的代码:

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: %i\n", 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: %i\n", 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 errors - this is in most cast translated from original NTSTATUS native api call result. win32错误-大多数情况下,这是从原始NTSTATUS本机api调用结果转换而来的。 but this translation is not injective - sometimes many different status converted to the same win32 error value. 但是此转换不是内含的-有时许多不同的状态会转换为相同的win32错误值。 for example to the same ERROR_ACCESS_DENIED converted at least 18(!) different ntstatus. 例如,将相同的ERROR_ACCESS_DENIED转换为至少18(!)个不同的ntstatus。 so original error can be not STATUS_ACCESS_DENIED but absolute another, having nothing common to real access denied. 因此原始错误不是STATUS_ACCESS_DENIED而是绝对错误,没有拒绝实际访问的常见错误。 because this, if win32 api call is shell over native call - always better call RtlGetLastNtStatus for get original error status code or call native api direct ( ZwMapViewOfSection instead MapViewOfFile ) 因此,如果win32 api调用是本机调用RtlGetLastNtStatus总是更好地调用RtlGetLastNtStatus以获得原始错误状态代码或直接调用本机api( ZwMapViewOfSection而不是MapViewOfFile

unfortunately I don't know original status returned by ZwMapViewOfSection , but I guess that this is STATUS_INVALID_VIEW_SIZE ( An attempt was made to create a view for a section which is bigger than the section. ). 不幸的是,我不知道ZwMapViewOfSection返回的原始状态,但是我想这是STATUS_INVALID_VIEW_SIZE试图为大于该部分的部分创建视图。 )。

in create and map section used sizeof(InputData) and sizeof(OutputData) - no definitions of this structures in code, bat based on 在创建和映射部分中使用sizeof(InputData)sizeof(OutputData) -此结构在代码中没有定义,基于

The code works absolutely fine when the shared memory is created by the 64 bit process/dll but whenever the 32 bit dll creates it, I get error 5 ( ERROR_ACCESS_DENIED ) returned when calling MapViewOfFile . 当共享内存是由64位进程/ dll创建的,但代码正确运行,但是无论何时由32位dll创建共享内存,调用MapViewOfFile时都会返回错误5( ERROR_ACCESS_DENIED )。

I guess next - in 32bit code InputData or OutputData have smaller size )compare 64 bit code). 我猜接下来-在32位代码中InputDataOutputData大小较小(比较64位代码)。 this just explain all. 这只是解释所有。 if 64 bit code first create section and then 32 bit code try map smaller size - this is ok. 如果先创建64位代码,然后再创建32位代码,则尝试将地图尺寸缩小一些-可以。 but if 32 bit code first create section and then 64 bit code try map size bigger that section size - we got STATUS_INVALID_VIEW_SIZE which translated to ERROR_ACCESS_DENIED 但是,如果先使用32位代码创建部分,然后再使用64位代码,则尝试将地图尺寸扩大为该部分尺寸-我们得到了STATUS_INVALID_VIEW_SIZE ,该值转换为ERROR_ACCESS_DENIED

but how about 但是怎么样

I already checked if the size .. the size is always the same in both processes. 我已经检查过大小..在两个过程中大小是否始终相同。

not believe. 不信。 I be recheck. 我要重新检查。

as separate note - the CreateFileMapping 作为单独的注释CreateFileMapping

Creates or opens a named or unnamed file mapping object for a specified file. 为指定文件创建或打开命名或未命名文件映射对象。

so we not need special function createOrOpenFileMapping and call OpenFileMappingA first - just call CreateFileMappingW (for what use A api ?). 因此,我们不需要特殊的函数createOrOpenFileMapping并首先调用OpenFileMappingA只需调用CreateFileMappingW (使用A api即可)。 and any way code of createOrOpenFileMapping have raise condition - both processes can call OpenFileMappingA in concurrent and both fail here. 并且createOrOpenFileMapping任何代码createOrOpenFileMapping引发条件-两个进程可以同时调用OpenFileMappingA ,并且都在此处失败。 that both anyway call CreateFileMappingA 无论如何都调用CreateFileMappingA

but main GetLastError() some times not the best and ERROR_ACCESS_DENIED not always is STATUS_ACCESS_DENIED and related to real access denied error 但是主要的GetLastError()有时不是最好的,并且ERROR_ACCESS_DENIED并非总是STATUS_ACCESS_DENIED并且与实际访问被拒绝的错误有关

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RegOpenKeyEx()返回ERROR_ACCESS_DENIED - RegOpenKeyEx() returns ERROR_ACCESS_DENIED RegOpenKeyEx 返回错误代码 5 (ERROR_ACCESS_DENIED) - RegOpenKeyEx returns error code 5 (ERROR_ACCESS_DENIED) CreateRemoteThread在win7 64位上返回ERROR_ACCESS_DENIED(5) - CreateRemoteThread returns ERROR_ACCESS_DENIED (5) on win7 64 bit RegDeleteKey因ERROR_ACCESS_DENIED失败 - RegDeleteKey fails with ERROR_ACCESS_DENIED ShowCaret和SetCaretPos失败,并显示ERROR_ACCESS_DENIED - ShowCaret and SetCaretPos failing with ERROR_ACCESS_DENIED AssignProcessToJobObject 有时会因 ERROR_ACCESS_DENIED 而失败 - AssignProcessToJobObject sometimes fails with ERROR_ACCESS_DENIED OpenEvent/OpenFileMapping 失败并显示 ERROR_ACCESS_DENIED - OpenEvent/OpenFileMapping fails with ERROR_ACCESS_DENIED CreateNamedPipe是否导致ERROR_ACCESS_DENIED? - CreateNamedPipe causes ERROR_ACCESS_DENIED? RegOpenKeyEx 返回 ERROR_SUCCESS 但 RegSetValueEx 总是返回 ERROR_ACCESS_DENIED - RegOpenKeyEx returns ERROR_SUCCESS but RegSetValueEx allways returns ERROR_ACCESS_DENIED 写入远程Windows共享文件夹的所有者时,GetNamedSecurityInfo返回ERROR_ACCESS_DENIED(5) - GetNamedSecurityInfo returns ERROR_ACCESS_DENIED(5) when writting owner of a remote Windows shared folder
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM