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);
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.