Hi,
I need to share data between a windows service and another process.
I've tried doing it using file mapping.
I wrote a small program which works well on WindowsXP, a small time service, which writes the time to shared memory every second.
I can read this memory in another process without a problem (on XP).
I've tried the same program on windows 7, and the service itself can read the last written time, but when trying to read the shared memory from another process, the mapping is done to another file - I can read/write from/to this file and got values unrelated to the file with the same name I'm using on the windows service.
I've tried using "Global\" prefix, It works well on XP (after granting permission to create global objects), but still the same behavior on Windows 7.
bool SharedMemoryManager::GetSecurityDescriptor(SECURITY_DESCRIPTOR& sd, SECURITY_ATTRIBUTES& sa)
{
if (!::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
return false;
if (!::SetSecurityDescriptorDacl(&sd, TRUE, (PACL) NULL, FALSE))
return false;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = &sd;
return true;
}
bool SharedMemoryManager::OpenSharedMemory(bool& wasMemoryAlreadyExist, DWORD sizeOfSharedMemory)
{
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;
SECURITY_ATTRIBUTES* pSecurityAttributes = &sa;
if (!GetSecurityDescriptor(sd, sa))
{
DTK_ERROR("SharedMemoryManager::OpenSharedMemory: failed to get security descriptor (error code %0)")
<< PdkString::fromWindowLastError();
pSecurityAttributes = NULL;
}
fileMapping_ = ::CreateFileMapping(
INVALID_HANDLE_VALUE,
pSecurityAttributes,
PAGE_READWRITE,
0,
sizeOfSharedMemory,
sharedMemoryName_.c_str());
if (fileMapping_ == NULL)
{
DTK_ERROR("SharedMemoryManager::OpenSharedMemory: Shared memory cannot be opened: %0")
<< PdkString::fromWindowLastError();
return false;
}
wasMemoryAlreadyExist = (::GetLastError() == ERROR_ALREADY_EXISTS);
sharedMemoryAdress_ = ::MapViewOfFile(fileMapping_, FILE_MAP_WRITE, 0, 0, 0);
if (sharedMemoryAdress_ == NULL)
{
DTK_ERROR("SharedMemoryManager::OpenSharedMemory: Failed to generate a view of the shared memory: %0")
<< PdkString::fromWindowLastError();
return false;
}
return true;
}
void SharedMemoryManager::CloseSharedMemory()
{
if (sharedMemoryAdress_)
{
::UnmapViewOfFile(sharedMemoryAdress_);
sharedMemoryAdress_ = NULL;
}
if (fileMapping_)
{
::CloseHandle(fileMapping_);
fileMapping_ = NULL;
}
}