他人の空似自作物置場

TestPrivateSharedMemory.zip/ExampleApp/ExampleApp.cpp


#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/foreach.hpp>

#include <Windows.h>

#include "../TestPrivateSharedMemory/SharedStruct.h"

typedef boost::shared_ptr<boost::remove_pointer<HANDLE>::type> SHARED_HANDLE;

typedef boost::shared_ptr<boost::remove_pointer<PSID>::type> SHARED_SID;

bool CreateSharedMemory(void *&ptr, const wchar_t * const name, const unsigned int size) {
  HANDLE handle = ::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, name);
  if (handle == NULL) {
    return false;
  }
  ptr = ::MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  if (ptr == NULL) {
    return false;
  }
  return true;
}

SHARED_SID GetWellKnownSid(const WELL_KNOWN_SID_TYPE type) {
  SHARED_SID sid(new unsigned char[SECURITY_MAX_SID_SIZE]);
  DWORD sidSize = SECURITY_MAX_SID_SIZE;
  if (::CreateWellKnownSid(type, NULL, sid.get(), &sidSize) == FALSE) {
    return SHARED_SID();
  }
  return sid;
}

void MyDeleteBoundaryDescriptor(const HANDLE handle) {
  if (handle != NULL) {
    ::DeleteBoundaryDescriptor(handle);
  }
}

void MyClosePrivateNamespace(const HANDLE handle) {
  if (handle != NULL) {
    ::ClosePrivateNamespace(handle, 0);
  }
}

bool OpenPrivateNamespace(SHARED_HANDLE &privateNamespace, const wchar_t * const boundaryName, const wchar_t * const name) {
  std::vector<SHARED_SID> sidList;
  sidList.push_back(GetWellKnownSid(WinBuiltinAnyPackageSid));
  HANDLE boundaryImpl = ::CreateBoundaryDescriptorW(boundaryName, 0);
  if (boundaryImpl == NULL) {
    return false;
  }
  BOOST_FOREACH(const SHARED_SID sid, sidList) {
    if (::AddSIDToBoundaryDescriptor(&boundaryImpl, sid.get()) == FALSE) {
      ::DeleteBoundaryDescriptor(boundaryImpl);
      return false;
    }
  }
  const SHARED_HANDLE boundary(boundaryImpl, &MyDeleteBoundaryDescriptor);
  privateNamespace.reset(::OpenPrivateNamespaceW(boundary.get(), name), &MyClosePrivateNamespace);
  if (!privateNamespace) {
    return false;
  }
  return true;
}

int main(const unsigned int argc, const char * const * const argv) {
  std::locale::global(std::locale("japanese"));
  SHARED_HANDLE privateNamespace;
  if (!OpenPrivateNamespace(privateNamespace, L"boundaryName", L"privateNamespaceName")) {
    std::wcout << L"Error: 名前空間のオープンに失敗しました" << std::endl;
    std::wcout << ::GetLastError() << std::endl;
    std::wcin.ignore();
    return 1;
  }
  void * ptr;
  const wchar_t * const sharedMemoryName = L"privateNamespaceName\\AppConteinerTestMemory";
  if (!CreateSharedMemory(ptr, sharedMemoryName, sizeof(SharedStruct))) {
    std::wcout << L"Error: 共有メモリーの生成に失敗しました" << std::endl;
    std::wcout << ::GetLastError() << std::endl;
    std::wcin.ignore();
    return 1;
  }
  SharedStruct &sharedStruct = *reinterpret_cast<SharedStruct *>(ptr);
  while (true) {
    std::wstring cmd;
    std::wcin >> cmd;
    if (cmd == L"exit") {
      break;
    }
    std::wistringstream wiss(cmd);
    unsigned int value;
    wiss >> value;
    sharedStruct.value = value;
    sharedStruct.changeFlag = true;
  }
  return 0;
}