2

I have a Windows service (running in the system process) and a desktop application that need to share a configuration structure. The data originates in the app, but the user process doesn't have permission to create a global memory object so I create it when the service starts using CreateFileMapping() and a DACL based on this answer. This appears to work fine: I get a non-null handle back from CreateFileMapping() and GetLastError() is 0. The problem is that the app can't see the object -- OpenFileMapping() returns a NULL handle and ERROR_FILE_NOT_FOUND -- and I also can't see it if I manually browse the global objects with WinObj. What's keeping my object from being visible?

SECURITY_ATTRIBUTES security;
ZeroMemory(&security, sizeof(security));
security.nLength = sizeof(security);
ConvertStringSecurityDescriptorToSecurityDescriptor(
    "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)",
    SDDL_REVISION_1,
    &security.lpSecurityDescriptor,
    NULL);
HANDLE  hFile = CreateFileMapping(INVALID_HANDLE_VALUE, &security, PAGE_READWRITE, 0, 1024*4, "Global\\gCONFIGXFILE");
DWORD   fileMappingResult = GetLastError();
if (hFile)
{
    CloseHandle(hFile);
}
LocalFree(security.lpSecurityDescriptor);
Community
  • 1
  • 1
jeffm
  • 3,120
  • 1
  • 34
  • 57

1 Answers1

6

Your service is closing its handle to the file mapping immediately after creating it, thus the mapping is being destroyed before the app has a chance to open its handle to the mapping. Your service needs to leave its handle to the mapping open, at least until after the app has opened its handle to the mapping.

Since you are sharing configuration, you should probably be creating the mapping at service start and leave it open until service stop. You could use a named event via CreateEvent() to let the service tell the app when the mapping has actually been created, and maybe use another named event whenever the content of the mapping is changed by either process.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I didn't realize this would happen automatically; I thought I would have to delete the handle. Thanks! – jeffm Jun 17 '15 at 19:25
  • 2
    In a sense, closing the handle *is* the delete. Many kernel objects are reference counted, including file mappings. When you create the mapping, it has a reference count of 1. When you close the handle, its reference count decrements. When the reference count reaches zero, the mapping is freed. That is why the app needs to open its handle to the mapping before the service closes its handle, so the reference count will not fall to zero prematurely. – Remy Lebeau Jun 17 '15 at 19:48