2016-03-22 65 views
1

2つのプロセス間でデータを共有しようとしています。最初はマップされたファイルにデータを書き込み、2番目のマップはそれを読み取ります。名前付き共有メモリWindows api C++

ここに私のコードは、これまでのところです:

まずプロセス:

#include "stdafx.h" 
    #include <Windows.h> 
    #include <tlhelp32.h> 
    #include <tchar.h> 
    #include<stdio.h> 

    #define BUF_SIZE 256 

    int _tmain(int argc, _TCHAR* argv[]) { 
    TCHAR szName[] = TEXT("Global\\MyFileMappingObject"); 
    LPTSTR szMsg = TEXT("MESS"); 

    HANDLE tokenH; 
    TOKEN_PRIVILEGES tp; 
    LUID luid; 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenH)) { 
     printf("OpenProcessToken error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    if (!LookupPrivilegeValue(NULL, SE_CREATE_GLOBAL_NAME, &luid)) { 
     printf("LookupPrivilegeValue error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Luid = luid; 
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    if (!AdjustTokenPrivileges(tokenH, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { 
     printf("AdjustTokenPrivileges error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 
    { 
     printf("The token does not have the specified privilege. \n"); 
     return FALSE; 
    } 
    CloseHandle(tokenH); 

    HANDLE hMapFile; 
    LPCTSTR pBuf; 
    hMapFile = CreateFileMapping(
     INVALID_HANDLE_VALUE, 
     NULL,      
     PAGE_READWRITE,   
     0,      
     BUF_SIZE,     
     szName); 
    if (hMapFile == NULL) 
    { 
     _tprintf(TEXT("Could not create file mapping object (%d).\n"), 
     GetLastError()); 
     return 1; 
    } 
    pBuf = (LPTSTR)MapViewOfFile(hMapFile, 
     FILE_MAP_ALL_ACCESS, 
     0, 
     0, 
     BUF_SIZE); 

    if (pBuf == NULL) 
    { 
     _tprintf(TEXT("Could not map view of file (%d).\n"), 
     GetLastError()); 

     CloseHandle(hMapFile); 

     return 1; 
    } 
    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR))); 
    UnmapViewOfFile(pBuf); 
    printf("Done\n"); 
    CloseHandle(hMapFile); 
    return 0; 
} 

第二工程:

#include "stdafx.h" 
#include <Windows.h> 
#include <tlhelp32.h> 
#include <tchar.h> 
#include <stdio.h> 
#pragma comment(lib, "user32.lib") 

#define BUF_SIZE 256 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    TCHAR szName[] = TEXT("Global\\MyFileMappingObject"); 
    HANDLE tokenH; 
    TOKEN_PRIVILEGES tp; 
    LUID luid; 
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenH); 
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { 
     printf("LookupPrivilegeValue error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Luid = luid; 
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    if (!AdjustTokenPrivileges(tokenH, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { 
     printf("AdjustTokenPrivileges error: %u\n", GetLastError()); 
     return FALSE; 
    } 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 
    { 
     printf("The token does not have the specified privilege. \n"); 
     return FALSE; 
    } 
    CloseHandle(tokenH); 

    HANDLE hMapFile; 
    LPCTSTR pBuf; 
    hMapFile = OpenFileMapping(
     FILE_MAP_ALL_ACCESS, // read/write access 
     FALSE,     // do not inherit the name 
     szName);    // name of mapping object 

    if (hMapFile == NULL) 
    { 
     _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
      GetLastError()); 
     return 1; 
    } 
    pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object 
     FILE_MAP_ALL_ACCESS, // read/write permission 
     0, 
     0, 
     BUF_SIZE); 

    if (pBuf == NULL) 
    { 
     _tprintf(TEXT("Could not map view of file (%d).\n"), 
      GetLastError()); 
     CloseHandle(hMapFile); 
     return 1; 
    } 
    MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK); 
    UnmapViewOfFile(pBuf); 
    CloseHandle(hMapFile); 
    return 0; 
} 

最初のプロセスは、そのデータを書き込むために管理します(私はすべてのエラーを受信しません。メッセージが表示され、「完了」メッセージが表示されます)、問題は2番目のプロセスにあります。 "OpenFileMapping"の後、getLastErrorから、存在しないファイルのコード2を取得します。両方のプロセスを管理者として実行します。

答えて

2

エラー2はERROR_FILE_NOT_FOUNDです。つまり、OpenFileMapping()が呼び出された時点で名前付きマッピングオブジェクトが存在しません。

プロセス間で名前付きカーネルオブジェクトを共有するには、両方のプロセスがと同じ時刻にで実行されている必要があります。他の名前付きカーネルオブジェクト(イベント、mutexなど)と同様に、マッピングオブジェクトには関連する参照カウントがあり、各オープンハンドルは参照カウントをインクリメントします。すべてのハンドルが閉じられると、オブジェクトは破棄されます。

最初のアプリがそのビューをマップ解除してマッピングオブジェクトへのハンドルを閉じると、2番目のアプリケーションに同じマッピングオブジェクトに対して開いている独自のハンドルがまだない場合、オブジェクトは破棄されます。したがって、オブジェクトは、2番目のアプリケーションが開こうとするときには存在しません。

+0

私はそれについて考えて、それは理にかなっています。しかし、私は初心者の質問があります:どのように私は最初のプログラムが停止するのを防ぐのですか? –

+0

明らかに、条件が真になるかどうかをチェックするループであろうと、信号のスリープ待ちであろうと、そういうものであろうと、待つことができる最初のアプリケーションに何かをコード化する必要があります。 2番目のアプリケーションが保存された値を消費するまで、最初のアプリケーションを待機させたい場合は、 'CreateEvent()'を使って名前付きイベントオブジェクトを作成し、 'WaitForSingleObject()'を経由して待機させ、 'OpenEvent()'を介してイベントを受け取り、 'SetEvent()'を介してそれを通知します。 –

+0

Windows上では、いつもどんなプロセスにも接続されたり切断されたりする可能性のある「persited」共有メモリを実際に作成することはできませんか? – SergeyA