WindowsでWindowsサービスとアプリケーションの間の共有メモリによるデータのやり取りを確認していた。
まずは簡単に,共有メモリの使い方を学習する。
参考にするページはこのページ。
とりあえず,CreateFileMappingとMapViewOfFileを使用することでメモリの共有ができる。しかし,これができるのは同じユーザの場合。
Windowsサービスとユーザアプリケーション間のやり取りに苦労する。
そこで次の例を読み込む。
CreateFileMappingの2つ目の引数をNULLではなく設定するのだ。
ここまでできるとサービス側で読み書きできて,アプリケーション側では読み取り専用で開かせたい。
アプリケーション側
#include "stdafx.h" int main() { TCHAR name[] = _T("Global\\somename"); DWORD dwSize = sizeof(int); HANDLE hSharedMemory = OpenFileMapping( FILE_MAP_READ,//FILE_MAP_ALL_ACCESS, FALSE, name ); int* pMemory = (int*)MapViewOfFile(hSharedMemory, FILE_MAP_READ/*FILE_MAP_ALL_ACCESS*/, NULL, NULL, dwSize); for (int i = 0; i < 40; i++) { //(*pMemory)--; _tprintf_s(_T("memory: %d\n"), *pMemory); Sleep(500); } UnmapViewOfFile(pMemory); CloseHandle(hSharedMemory); return 0; }
サービス側 試行錯誤してみました。
#include "stdafx.h" int main() { TCHAR name[] = _T("Global\\somename"); DWORD dwSize = sizeof(int); SECURITY_DESCRIPTOR secDesc; SECURITY_ATTRIBUTES secAttr; InitializeSecurityDescriptor(&secDesc, SECURITY_DESCRIPTOR_REVISION); DWORD dwAclSize = 1024; SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_LOCAL_SID_AUTHORITY; // SECURITY_WORLD_SID_AUTHORITY (Everyone)でもよい PSID pSid = NULL; if (!AllocateAndInitializeSid(&SIDAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSid)) { return 1; } PACL pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize); if (pDacl == NULL) { return 1; } // 随意アクセス制御リストを初期化 InitializeAcl(pDacl, dwAclSize, ACL_REVISION); // ACE(アクセス制御エントリ)をDACLに追加 AddAccessAllowedAce(pDacl, ACL_REVISION, GENERIC_READ, pSid); AddAccessDeniedAce(pDacl, ACL_REVISION, GENERIC_WRITE, pSid); SetSecurityDescriptorDacl(&secDesc, TRUE, pDacl, FALSE); secAttr.nLength = sizeof(SECURITY_ATTRIBUTES); secAttr.bInheritHandle = TRUE; secAttr.lpSecurityDescriptor = &secDesc; HANDLE hSharedMemory = CreateFileMapping(INVALID_HANDLE_VALUE, &secAttr, PAGE_READWRITE, NULL, dwSize, name); LocalFree(pDacl); FreeSid(pSid); int* pMemory = (int*)MapViewOfFile(hSharedMemory, FILE_MAP_ALL_ACCESS, NULL, NULL, dwSize); *pMemory = 0; // Only the administrators process can handle it as fully accessible variable. for (int i = 0; i < 40; i++) { (*pMemory)++; _tprintf_s(_T("src_memory: %d\n"), *pMemory); Sleep(1000); } UnmapViewOfFile(pMemory); CloseHandle(hSharedMemory); return 0; }
特に
AddAccessAllowedAce(pDacl, ACL_REVISION, GENERIC_READ, pSid);
AddAccessDeniedAce(pDacl, ACL_REVISION, GENERIC_WRITE, pSid);
の周辺を入れていました。
[参考]