Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SharedMemory_win.cpp « mumble « src - github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 044932d55ac1add07569ed62fbe4cc48b9f83de7 (plain)
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;
	}
}