ブログ

割とコンピュータよりの情報をお届けします。

Windowsで共有メモリの使用WindowsサービスとWindowsアプリケーション間のやり取り

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);
の周辺を入れていました。

[参考]

  1. C++で複数プロセスから読み書き可能な共有メモリを作る
  2. 【共有メモリ】アクセスが拒否されました。
2018/08/16 コンピュータ   TakeMe
< 前の記事     一覧へ     後の記事 >

コメント送信フォーム


※ Eメールは公開されません
Loading...
 画像の文字を入力してください