SharedMemory_WIN32.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //
  2. // SharedMemoryImpl.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/SharedMemory_WIN32.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Processes
  8. // Module: SharedMemoryImpl
  9. //
  10. // Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/SharedMemory_WIN32.h"
  16. #include "Poco/Error.h"
  17. #include "Poco/Exception.h"
  18. #include "Poco/File.h"
  19. #include "Poco/Format.h"
  20. #if defined (POCO_WIN32_UTF8)
  21. #include "Poco/UnicodeConverter.h"
  22. #endif
  23. #include "Poco/UnWindows.h"
  24. namespace Poco {
  25. SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, SharedMemory::AccessMode mode, const void*, bool):
  26. _name(name),
  27. _memHandle(INVALID_HANDLE_VALUE),
  28. _fileHandle(INVALID_HANDLE_VALUE),
  29. _size(static_cast<DWORD>(size)),
  30. _mode(PAGE_READONLY),
  31. _address(0)
  32. {
  33. if (mode == SharedMemory::AM_WRITE)
  34. _mode = PAGE_READWRITE;
  35. #if defined (POCO_WIN32_UTF8)
  36. std::wstring utf16name;
  37. UnicodeConverter::toUTF16(_name, utf16name);
  38. _memHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, _mode, 0, _size, utf16name.c_str());
  39. #else
  40. _memHandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, _mode, 0, _size, _name.c_str());
  41. #endif
  42. if (!_memHandle)
  43. {
  44. DWORD dwRetVal = GetLastError();
  45. #if defined (_WIN32_WCE)
  46. throw SystemException(format("Cannot create shared memory object %s [Error %d: %s]", _name, static_cast<int>(dwRetVal), Error::getMessage(dwRetVal)));
  47. #else
  48. if (_mode != PAGE_READONLY || dwRetVal != 5)
  49. throw SystemException(format("Cannot create shared memory object %s [Error %d: %s]", _name, static_cast<int>(dwRetVal), Error::getMessage(dwRetVal)));
  50. #if defined (POCO_WIN32_UTF8)
  51. _memHandle = OpenFileMappingW(PAGE_READONLY, FALSE, utf16name.c_str());
  52. #else
  53. _memHandle = OpenFileMappingA(PAGE_READONLY, FALSE, _name.c_str());
  54. #endif
  55. if (!_memHandle)
  56. {
  57. dwRetVal = GetLastError();
  58. throw SystemException(format("Cannot open shared memory object %s [Error %d: %s]", _name, static_cast<int>(dwRetVal), Error::getMessage(dwRetVal)));
  59. }
  60. #endif
  61. }
  62. map();
  63. }
  64. SharedMemoryImpl::SharedMemoryImpl(const Poco::File& file, SharedMemory::AccessMode mode, const void*):
  65. _name(file.path()),
  66. _memHandle(INVALID_HANDLE_VALUE),
  67. _fileHandle(INVALID_HANDLE_VALUE),
  68. _size(0),
  69. _mode(PAGE_READONLY),
  70. _address(0)
  71. {
  72. if (!file.exists() || !file.isFile())
  73. throw FileNotFoundException(_name);
  74. _size = static_cast<DWORD>(file.getSize());
  75. DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
  76. DWORD fileMode = GENERIC_READ;
  77. if (mode == SharedMemory::AM_WRITE)
  78. {
  79. _mode = PAGE_READWRITE;
  80. fileMode |= GENERIC_WRITE;
  81. }
  82. #if defined (POCO_WIN32_UTF8)
  83. std::wstring utf16name;
  84. UnicodeConverter::toUTF16(_name, utf16name);
  85. _fileHandle = CreateFileW(utf16name.c_str(), fileMode, shareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  86. #else
  87. _fileHandle = CreateFileA(_name.c_str(), fileMode, shareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  88. #endif
  89. if (_fileHandle == INVALID_HANDLE_VALUE)
  90. throw OpenFileException("Cannot open memory mapped file", _name);
  91. _memHandle = CreateFileMapping(_fileHandle, NULL, _mode, 0, 0, NULL);
  92. if (!_memHandle)
  93. {
  94. DWORD dwRetVal = GetLastError();
  95. CloseHandle(_fileHandle);
  96. _fileHandle = INVALID_HANDLE_VALUE;
  97. throw SystemException(format("Cannot map file into shared memory %s [Error %d: %s]", _name, (int)dwRetVal, Error::getMessage(dwRetVal)));
  98. }
  99. map();
  100. }
  101. SharedMemoryImpl::~SharedMemoryImpl()
  102. {
  103. unmap();
  104. close();
  105. }
  106. void SharedMemoryImpl::map()
  107. {
  108. DWORD access = FILE_MAP_READ;
  109. if (_mode == PAGE_READWRITE)
  110. access = FILE_MAP_WRITE;
  111. LPVOID addr = MapViewOfFile(_memHandle, access, 0, 0, _size);
  112. if (!addr)
  113. {
  114. DWORD dwRetVal = GetLastError();
  115. throw SystemException(format("Cannot map shared memory object %s [Error %d: %s]", _name, (int)dwRetVal, Error::getMessage(dwRetVal)));
  116. }
  117. _address = static_cast<char*>(addr);
  118. }
  119. void SharedMemoryImpl::unmap()
  120. {
  121. if (_address)
  122. {
  123. UnmapViewOfFile(_address);
  124. _address = 0;
  125. return;
  126. }
  127. }
  128. void SharedMemoryImpl::close()
  129. {
  130. if (_memHandle != INVALID_HANDLE_VALUE)
  131. {
  132. CloseHandle(_memHandle);
  133. _memHandle = INVALID_HANDLE_VALUE;
  134. }
  135. if (_fileHandle != INVALID_HANDLE_VALUE)
  136. {
  137. CloseHandle(_fileHandle);
  138. _fileHandle = INVALID_HANDLE_VALUE;
  139. }
  140. }
  141. } // namespace Poco