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