Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsharedmemory_win.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsharedmemory.h"
5#include "qsharedmemory_p.h"
6#include "qsystemsemaphore.h"
7#include <qdebug.h>
8#include <qt_windows.h>
9
11
12using namespace Qt::StringLiterals;
13
14#if QT_CONFIG(sharedmemory)
15
16void QSharedMemoryPrivate::setWindowsErrorString(QLatin1StringView function)
17{
18 DWORD windowsError = GetLastError();
19 if (windowsError == 0)
20 return;
21 switch (windowsError) {
22 case ERROR_ALREADY_EXISTS:
23 error = QSharedMemory::AlreadyExists;
24 errorString = QSharedMemory::tr("%1: already exists").arg(function);
25 break;
26 case ERROR_FILE_NOT_FOUND:
27 error = QSharedMemory::NotFound;
28 errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
29 break;
30 case ERROR_COMMITMENT_LIMIT:
31 error = QSharedMemory::InvalidSize;
32 errorString = QSharedMemory::tr("%1: invalid size").arg(function);
33 break;
34 case ERROR_NO_SYSTEM_RESOURCES:
35 case ERROR_NOT_ENOUGH_MEMORY:
36 error = QSharedMemory::OutOfResources;
37 errorString = QSharedMemory::tr("%1: out of resources").arg(function);
38 break;
39 case ERROR_ACCESS_DENIED:
40 error = QSharedMemory::PermissionDenied;
41 errorString = QSharedMemory::tr("%1: permission denied").arg(function);
42 break;
43 default:
44 errorString = QSharedMemory::tr("%1: unknown error: %2")
45 .arg(function, qt_error_string(windowsError));
46 error = QSharedMemory::UnknownError;
47#if defined QSHAREDMEMORY_DEBUG
48 qDebug() << errorString << "key" << key;
49#endif
50 }
51}
52
53HANDLE QSharedMemoryWin32::handle(QSharedMemoryPrivate *self)
54{
55 if (!hand) {
56 const auto function = "QSharedMemory::handle"_L1;
57 if (self->nativeKey.isEmpty()) {
58 self->setError(QSharedMemory::KeyError,
59 QSharedMemory::tr("%1: unable to make key").arg(function));
60 return 0;
61 }
62 hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false,
63 reinterpret_cast<const wchar_t *>(self->nativeKey.nativeKey().utf16()));
64 if (!hand) {
65 self->setWindowsErrorString(function);
66 return 0;
67 }
68 }
69 return hand;
70}
71
72bool QSharedMemoryWin32::cleanHandle(QSharedMemoryPrivate *)
73{
74 if (hand != 0 && !CloseHandle(hand)) {
75 hand = 0;
76 return false;
77 }
78 hand = 0;
79 return true;
80}
81
82bool QSharedMemoryWin32::create(QSharedMemoryPrivate *self, qsizetype size)
83{
84 const auto function = "QSharedMemory::create"_L1;
85 if (self->nativeKey.isEmpty()) {
86 self->setError(QSharedMemory::KeyError,
87 QSharedMemory::tr("%1: key error").arg(function));
88 return false;
89 }
90
91 // Create the file mapping.
92 DWORD high, low;
93 if constexpr (sizeof(qsizetype) == 8)
94 high = DWORD(quint64(size) >> 32);
95 else
96 high = 0;
97 low = DWORD(size_t(size) & 0xffffffff);
98 hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, high, low,
99 reinterpret_cast<const wchar_t *>(self->nativeKey.nativeKey().utf16()));
100 self->setWindowsErrorString(function);
101
102 // hand is valid when it already exists unlike unix so explicitly check
103 return self->error != QSharedMemory::AlreadyExists && hand;
104}
105
106bool QSharedMemoryWin32::attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode)
107{
108 // Grab a pointer to the memory block
109 int permissions = (mode == QSharedMemory::ReadOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS);
110 self->memory = (void *)MapViewOfFile(handle(self), permissions, 0, 0, 0);
111 if (!self->memory) {
112 self->setWindowsErrorString("QSharedMemory::attach"_L1);
113 cleanHandle(self);
114 return false;
115 }
116
117 // Grab the size of the memory we have been given (a multiple of 4K on windows)
118 MEMORY_BASIC_INFORMATION info;
119 if (!VirtualQuery(self->memory, &info, sizeof(info))) {
120 // Windows doesn't set an error code on this one,
121 // it should only be a kernel memory error.
122 self->setError(QSharedMemory::UnknownError,
123 QSharedMemory::tr("%1: size query failed")
124 .arg("QSharedMemory::attach: "_L1));
125 return false;
126 }
127 self->size = qsizetype(info.RegionSize);
128
129 return true;
130}
131
132bool QSharedMemoryWin32::detach(QSharedMemoryPrivate *self)
133{
134 // umap memory
135 if (!UnmapViewOfFile(self->memory)) {
136 self->setWindowsErrorString("QSharedMemory::detach"_L1);
137 return false;
138 }
139 self->memory = 0;
140 self->size = 0;
141
142 // close handle
143 return cleanHandle(self);
144}
145
146#endif // QT_CONFIG(sharedmemory)
147
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
Definition qstring.cpp:6995
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
Combined button and popup list for selecting options.
Q_MULTIMEDIA_EXPORT QString errorString(HRESULT hr)
void * HANDLE
QString self
Definition language.cpp:58
DBusConnection const char DBusError * error
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
#define qDebug
[1]
Definition qlogging.h:164
GLuint64 GLenum void * handle
GLenum mode
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
SSL_CTX int void * arg
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
QHostInfo info
[0]