1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5
6 #include "mumble_pch.hpp"
7
8 #include "SharedMemory.h"
9
10 #ifndef _WIN32_WINNT
11 #define _WIN32_WINNT 0x0501
12 #include <windows.h>
13 #endif
14
15 #include <QtCore/QDebug>
16
17 struct SharedMemory2Private {
18 HANDLE hMemory;
19 };
20
SharedMemory2(QObject * p,unsigned int minsize,const QString & memname)21 SharedMemory2::SharedMemory2(QObject *p, unsigned int minsize, const QString &memname) : QObject(p) {
22 a_ucData = NULL;
23
24 d = new SharedMemory2Private();
25 d->hMemory = NULL;
26
27 if (memname.isEmpty()) {
28 // Create a new segment
29
30 for (int i=0;i<100;++i) {
31 qsName = QString::fromLatin1("Local\\MumbleOverlayMemory%1").arg(++uiIndex);
32 d->hMemory = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, minsize, qsName.toStdWString().c_str());
33 if (d->hMemory && GetLastError() != ERROR_ALREADY_EXISTS) {
34 break;
35 }
36
37 if (d->hMemory)
38 CloseHandle(d->hMemory);
39 d->hMemory = NULL;
40 }
41 } else {
42 // Open existing segment
43
44 qsName = memname;
45 d->hMemory = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, minsize, qsName.toStdWString().c_str());
46 qWarning("%p %lx", d->hMemory, GetLastError());
47 if (GetLastError() != ERROR_ALREADY_EXISTS) {
48 qWarning() << "SharedMemory2: Memory doesn't exist" << qsName;
49 if (d->hMemory) {
50 CloseHandle(d->hMemory);
51 d->hMemory = NULL;
52 }
53 }
54 }
55
56 if (d->hMemory == NULL) {
57 qWarning() << "SharedMemory2: CreateFileMapping failed for" << qsName;
58 } else {
59 a_ucData = reinterpret_cast<unsigned char *>(MapViewOfFile(d->hMemory, FILE_MAP_ALL_ACCESS, 0, 0, 0));
60
61 if (a_ucData == NULL) {
62 qWarning() << "SharedMemory2: Failed to map memory" << qsName;
63 } else {
64 MEMORY_BASIC_INFORMATION mbi;
65 memset(&mbi, 0, sizeof(mbi));
66 if ((VirtualQuery(a_ucData, &mbi, sizeof(mbi)) == 0) || (mbi.RegionSize < minsize)) {
67 qWarning() << "SharedMemory2: Memory too small" << qsName << mbi.RegionSize;
68 } else {
69 uiSize = mbi.RegionSize;
70 return;
71 }
72 }
73 }
74
75 if (a_ucData) {
76 UnmapViewOfFile(a_ucData);
77 a_ucData = NULL;
78 }
79 if (d->hMemory) {
80 CloseHandle(d->hMemory);
81 d->hMemory = NULL;
82 }
83 }
84
~SharedMemory2()85 SharedMemory2::~SharedMemory2() {
86 if (a_ucData)
87 UnmapViewOfFile(a_ucData);
88 if (d->hMemory)
89 CloseHandle(d->hMemory);
90
91 delete d;
92 }
93
systemRelease()94 void SharedMemory2::systemRelease() {
95 // This doesn't really do anything on Win32, since it has delete-on-close semantics anyway
96 if (d->hMemory) {
97 CloseHandle(d->hMemory);
98 d->hMemory = NULL;
99 }
100 }
101