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
qv4compilationunitmapper_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
5
6#include <private/qv4compileddata_p.h>
7
8#include <QtCore/qdatetime.h>
9#include <QtCore/qfileinfo.h>
10#include <QtCore/qscopeguard.h>
11
12#include <qt_windows.h>
13
15
16using namespace QV4;
17
18CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString)
19{
20 close();
21
22 // ### TODO: fix up file encoding/normalization/unc handling once QFileSystemEntry
23 // is exported from QtCore.
25 CreateFile(reinterpret_cast<const wchar_t*>(cacheFileName.constData()),
26 GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ,
27 nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
28 nullptr);
29 if (handle == INVALID_HANDLE_VALUE) {
30 *errorString = qt_error_string(GetLastError());
31 return nullptr;
32 }
33
34 auto fileHandleCleanup = qScopeGuard([handle]{
35 CloseHandle(handle);
36 });
37
39 DWORD bytesRead;
40 if (!ReadFile(handle, reinterpret_cast<char *>(&header), sizeof(header), &bytesRead, nullptr)) {
41 *errorString = qt_error_string(GetLastError());
42 return nullptr;
43 }
44
45 if (bytesRead != sizeof(header)) {
46 *errorString = QStringLiteral("File too small for the header fields");
47 return nullptr;
48 }
49
50 if (!header.verifyHeader(sourceTimeStamp, errorString))
51 return nullptr;
52
53 // Data structure and qt version matched, so now we can access the rest of the file safely.
54
55 /* Error out early on file corruption. We assume we can read header.unitSize bytes
56 later (even before verifying the checksum), potentially causing out-of-bound
57 reads
58 Also, no need to wait until checksum verification if we know beforehand
59 that the cached unit is bogus
60 */
61 LARGE_INTEGER fileSize;
62 if (!GetFileSizeEx(handle, &fileSize)) {
63 *errorString = QStringLiteral("Could not determine file size");
64 return nullptr;
65 }
66 if (header.unitSize != fileSize.QuadPart) {
67 *errorString = QStringLiteral("Potential file corruption, file too small");
68 return nullptr;
69 }
70
71
72 HANDLE fileMappingHandle = CreateFileMapping(handle, 0, PAGE_READONLY, 0, 0, 0);
73 if (!fileMappingHandle) {
74 *errorString = qt_error_string(GetLastError());
75 return nullptr;
76 }
77
78 auto mappingCleanup = qScopeGuard([fileMappingHandle]{
79 CloseHandle(fileMappingHandle);
80 });
81
82 dataPtr = MapViewOfFile(fileMappingHandle, FILE_MAP_READ, 0, 0, 0);
83 if (!dataPtr) {
84 *errorString = qt_error_string(GetLastError());
85 return nullptr;
86 }
87
88 return reinterpret_cast<CompiledData::Unit*>(dataPtr);
89}
90
91void CompilationUnitMapper::close()
92{
93 if (dataPtr != nullptr) {
94 // Do not unmap cache files that are built with the StaticData flag. That's the majority of
95 // them and it's necessary to benefit from the QString literal optimization. There might
96 // still be QString instances around that point into that memory area. The memory is backed
97 // on the disk, so the kernel is free to release the pages and all that remains is the
98 // address space allocation.
99 if (!(reinterpret_cast<CompiledData::Unit*>(dataPtr)->flags & CompiledData::Unit::StaticData))
100 UnmapViewOfFile(dataPtr);
101 }
102 dataPtr = nullptr;
103}
104
\inmodule QtCore\reentrant
Definition qdatetime.h:283
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1246
Combined button and popup list for selecting options.
Q_MULTIMEDIA_EXPORT QString errorString(HRESULT hr)
void * HANDLE
static QString header(const QString &name)
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
GLuint64 GLenum void * handle
GLbitfield flags
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
#define QStringLiteral(str)