18

I wish to implement IPC using Named Shared Memory.

To do this, one of the steps is getting a handle to a Mapping Memory Object, using CreateFileMapping().

I do it exactly as MSDN website reccommends: http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx:

hFileMappingHandle = CreateFileMapping
    (
        INVALID_HANDLE_VALUE,      // use paging file
        NULL,                      // default security 
        PAGE_READWRITE,            // read/write access
        0,            // maximum object size (high-order DWORD) 
        256,            // maximum object size (low-order DWORD)  
        "Global\\MyFileMappingObject"          // name of mapping object
    ); 
DWORD dwError = GetLastError();

However, the handle returned is always 0x0, and the System Error Code returned is: 0x5 (Access Denied.)

  • Only Named Memory Sharing desired (not file sharing).
  • Windows 7 x64 bit OS
  • Administrator's user rights available
  • Developed Application: 64bit Plug-In application (.dll)

Does anybody have the same experience, and a way to fix it, please? I use MSDN site as my reference, so I to not think, there is problem in the code.

svick
  • 236,525
  • 50
  • 385
  • 514
Bunkai.Satori
  • 4,698
  • 13
  • 49
  • 77

6 Answers6

13

Looks like you don't have enough privileges.

From MSDN:

Creating a file mapping object in the global namespace from a session other than session zero requires the SeCreateGlobalPrivilege privilege. For more information, see Kernel Object Namespaces.

...

The creation of a file-mapping object in the global namespace, by using CreateFileMapping, from a session other than session zero is a privileged operation. Because of this, an application running in an arbitrary Remote Desktop Session Host (RD Session Host) server session must have SeCreateGlobalPrivilege enabled in order to create a file-mapping object in the global namespace successfully. The privilege check is limited to the creation of file-mapping objects, and does not apply to opening existing ones. For example, if a service or the system creates a file-mapping object, any process running in any session can access that file-mapping object provided that the user has the necessary access.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
  • 5
    Hi Eugene, that was exactly my problem. I deleted the prefix "Global\\" from the name of my mapping object, and apprently that fixed the problem. I do not plan to deal with terminal services, so the solution should be acceptable for now. I read the docummentation on SeCreateGlobalPriviledge, but it is not clear to me, if the priviledges can be assigned by the application itself, or if I have to manually adjust the priviledges say from within Windows Explorer? – Bunkai.Satori Oct 22 '10 at 17:23
  • 1
    The privilege is defined by user account under which your application is started. You can attempt to use AdjustTokenPrivilege function as discussed here: http://delphi.about.com/b/2008/09/26/zarko-needs-help-createfilemapping-terminal-services-global-session-secreateglobalprivilege.htm , but this doesn't guarantee result. In general, try searching for SeCreateGlobalPrivilege, the results contain some interesting sources of information – Eugene Mayevski 'Callback Oct 22 '10 at 20:00
  • "I deleted the prefix "Global\\" ... and apparently that fixed the problem." @Bunkai.Satori - this is exactly what I needed. Thanks! – Stryker2k2 Jun 28 '23 at 16:13
2

Administrators, Services and Network Services have SeCreateGlobalPrivilege by default. You must remember though, that Windows7/Vista does not run everything as admin. So use "Start as administrator" to make "Global\" work for your application. If you're debugging, start Visual Studio as admin also.

alemjerus
  • 8,023
  • 3
  • 32
  • 40
1

To create global file mappings you need the SeCreateGlobalPrivilege privilege - do you have that? Access-denied implies this is a permissions problem, for sure.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • Hi Steve, that was my problem. Thank you. I fixed the problem for now in a different way, but if I wisth to set priviledges, can that be done programatically from within my application, please? – Bunkai.Satori Oct 22 '10 at 17:25
  • You can do this using `AdjustTokenPrivileges` as shown here: http://msdn.microsoft.com/en-us/library/aa446619(v=VS.85).aspx. The token handle comes from `OpenProcessToken` which must be called using (at least) `TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY` – Steve Townsend Oct 22 '10 at 17:35
0

The reference to terminal services in the documentation about global namespace is a bit misleading as it implies you only need to worry about this if you have an unusual situation.

In fact both IIS and system services run in session zero, and the first / only user to log on runs in session 1 - so you have to use Global namespace to communicate between IIS or a service and a normal program.

Dave Bush
  • 31
  • 3
0

use security attributes and DACL. Example:

ZeroMemory(&attributes, sizeof(attributes));
attributes.nLength = sizeof(attributes);
ConvertStringSecurityDescriptorToSecurityDescriptorA(
            "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)",
            SDDL_REVISION_1,
            &attributes.lpSecurityDescriptor,
            NULL);
hMapObject = CreateFileMappingA(
            INVALID_HANDLE_VALUE,
            &attributes,
            PAGE_READWRITE,
            0,
            1024,
            "mySMobject");
Shashank
  • 116
  • 1
  • 5
0

This is a very old question and marked as answered. But going through the same MSDN article and build a sample based on it, I was able to succeed without any special privileges.

One just need to get rid of "Global\" part of the name. Surprisingly, it doens't work this way for Semaphors and Events, you will get "0x2 ERROR_FILE_NOT_FOUND". But for the memory mapped shared memory it works just fine. I was able to Create a read/write shared memory on a server, and Open it on a Client.

Павел
  • 677
  • 6
  • 21