VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/networking/UIDownloaderExtensionPack.cpp@ 93996

Last change on this file since 93996 was 93996, checked in by vboxsync, 3 years ago

FE/Qt: qt6: Regular expressions. bugref:9898

  • QString::remove, QString::replace and other does not accept QRegExp any more, must use QRegularExpression (qt4 debt).
  • Some uses of QRegExp was not converted, opting instead to include QRegExp from Core5Compat.
  • QRegExpValidator (removed) -> QRegularExpressionValidator (5.1) for setValidator.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: UIDownloaderExtensionPack.cpp 93996 2022-02-28 22:04:49Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIDownloaderExtensionPack class implementation.
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QDir>
20#include <QFile>
21#include <QRegularExpression>
22#include <QVariant>
23
24/* GUI includes: */
25#include "QIFileDialog.h"
26#include "UICommon.h"
27#include "UIDownloaderExtensionPack.h"
28#include "UIMessageCenter.h"
29#include "UIModalWindowManager.h"
30#include "UINetworkReply.h"
31#include "UINotificationCenter.h"
32#include "UIVersion.h"
33
34/* Other VBox includes: */
35#include <iprt/sha.h>
36
37
38UIDownloaderExtensionPack::UIDownloaderExtensionPack()
39{
40 /* Get version number and adjust it for test and trunk builds. The server only has official releases. */
41 const QString strVersion = UIVersion(uiCommon().vboxVersionStringNormalized()).effectiveReleasedVersion().toString();
42
43 /* Prepare source/target: */
44 const QString strUnderscoredName = QString(GUI_ExtPackName).replace(' ', '_');
45 const QString strSourceName = QString("%1-%2.vbox-extpack").arg(strUnderscoredName, strVersion);
46 const QString strSourcePath = QString("https://download.virtualbox.org/virtualbox/%1/").arg(strVersion);
47 const QString strSource = strSourcePath + strSourceName;
48 const QString strPathSHA256SumsFile = QString("https://www.virtualbox.org/download/hashes/%1/SHA256SUMS").arg(strVersion);
49 const QString strTarget = QDir(uiCommon().homeFolder()).absoluteFilePath(strSourceName);
50
51 /* Set source/target: */
52 setSource(strSource);
53 setTarget(strTarget);
54 setPathSHA256SumsFile(strPathSHA256SumsFile);
55}
56
57QString UIDownloaderExtensionPack::description() const
58{
59 return UIDownloader::description().arg(tr("VirtualBox Extension Pack"));
60}
61
62bool UIDownloaderExtensionPack::askForDownloadingConfirmation(UINetworkReply *pReply)
63{
64 return msgCenter().confirmDownloadExtensionPack(GUI_ExtPackName, source().toString(), pReply->header(UINetworkReply::ContentLengthHeader).toInt());
65}
66
67void UIDownloaderExtensionPack::handleDownloadedObject(UINetworkReply *pReply)
68{
69 m_receivedData = pReply->readAll();
70}
71
72void UIDownloaderExtensionPack::handleVerifiedObject(UINetworkReply *pReply)
73{
74 /* Try to verify the SHA-256 checksum: */
75 QString strCalculatedSumm;
76 bool fSuccess = false;
77 do
78 {
79 /* Read received data into the buffer: */
80 const QByteArray receivedData(pReply->readAll());
81 /* Make sure it's not empty: */
82 if (receivedData.isEmpty())
83 break;
84
85 /* Parse buffer contents to dictionary: */
86#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
87 const QStringList dictionary(QString(receivedData).split("\n", Qt::SkipEmptyParts));
88#else
89 const QStringList dictionary(QString(receivedData).split("\n", QString::SkipEmptyParts));
90#endif
91 /* Make sure it's not empty: */
92 if (dictionary.isEmpty())
93 break;
94
95 /* Parse each record to tags, look for the required one: */
96 foreach (const QString &strRecord, dictionary)
97 {
98 QRegularExpression separator(" \\*| ");
99 const QString strFileName = strRecord.section(separator, 1);
100 const QString strDownloadedSumm = strRecord.section(separator, 0, 0);
101 if (strFileName == source().fileName())
102 {
103 /* Calc the SHA-256 on the bytes, creating a string: */
104 uint8_t abHash[RTSHA256_HASH_SIZE];
105 RTSha256(m_receivedData.constData(), m_receivedData.length(), abHash);
106 char szDigest[RTSHA256_DIGEST_LEN + 1];
107 int rc = RTSha256ToString(abHash, szDigest, sizeof(szDigest));
108 if (RT_FAILURE(rc))
109 {
110 AssertRC(rc);
111 szDigest[0] = '\0';
112 }
113 strCalculatedSumm = szDigest;
114 //printf("Downloaded SHA-256 summ: [%s]\n", strDownloadedSumm.toUtf8().constData());
115 //printf("Calculated SHA-256 summ: [%s]\n", strCalculatedSumm.toUtf8().constData());
116 /* Make sure checksum is valid: */
117 fSuccess = strDownloadedSumm == strCalculatedSumm;
118 break;
119 }
120 }
121 }
122 while (false);
123
124 /* If SHA-256 checksum verification failed: */
125 if (!fSuccess)
126 {
127 /* Warn the user about additions-image was downloaded and saved but checksum is invalid: */
128 UINotificationMessage::cannotValidateExtentionPackSHA256Sum(GUI_ExtPackName, source().toString(), QDir::toNativeSeparators(target()));
129 return;
130 }
131
132 /* Serialize that buffer into the file: */
133 while (true)
134 {
135 /* Make sure the file already exists. If we reached
136 * this place, it's already written and checked. */
137 QFile file(target());
138 bool fSuccess = false;
139 /* Check step. Try to open file for reading first. */
140 if (file.open(QIODevice::ReadOnly))
141 fSuccess = true;
142 /* Failsafe step. Try to open file for writing otherwise. */
143 if (!fSuccess && file.open(QIODevice::WriteOnly))
144 {
145 /* Write buffer into the file: */
146 file.write(m_receivedData);
147 file.close();
148 fSuccess = true;
149 }
150 /* If the file already exists or was just written: */
151 if (fSuccess)
152 {
153 /* Warn the listener about extension-pack was downloaded: */
154 emit sigDownloadFinished(source().toString(), target(), strCalculatedSumm);
155 break;
156 }
157
158 /* Warn the user about extension-pack was downloaded but was NOT saved: */
159 msgCenter().cannotSaveExtensionPack(GUI_ExtPackName, source().toString(), QDir::toNativeSeparators(target()));
160
161 /* Ask the user for another location for the extension-pack file: */
162 QString strTarget = QIFileDialog::getExistingDirectory(QFileInfo(target()).absolutePath(),
163 windowManager().mainWindowShown(),
164 tr("Select folder to save %1 to").arg(GUI_ExtPackName), true);
165
166 /* Check if user had really set a new target: */
167 if (!strTarget.isNull())
168 setTarget(QDir(strTarget).absoluteFilePath(QFileInfo(target()).fileName()));
169 else
170 break;
171 }
172}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette