VirtualBox

source: vbox/trunk/src/VBox/Main/include/GuestSessionImplTasks.h@ 106142

Last change on this file since 106142 was 106142, checked in by vboxsync, 2 months ago

Additions: Automatic Upgrade: Cleanup guest session files after upgrade, bugref:10776.

Also improve logging.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.3 KB
Line 
1/* $Id: GuestSessionImplTasks.h 106142 2024-09-24 15:51:42Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Guest session tasks header.
4 */
5
6/*
7 * Copyright (C) 2018-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef MAIN_INCLUDED_GuestSessionImplTasks_h
29#define MAIN_INCLUDED_GuestSessionImplTasks_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include "GuestSessionWrap.h"
35#include "EventImpl.h"
36#include "ProgressImpl.h"
37
38#include "GuestCtrlImplPrivate.h"
39#include "GuestSessionImpl.h"
40#include "ThreadTask.h"
41
42#include <iprt/vfs.h>
43
44#include <vector>
45
46class Guest;
47class GuestSessionTask;
48class GuestSessionTaskInternalStart;
49
50
51/**
52 * Structure for keeping a file system source specification,
53 * along with options.
54 */
55struct GuestSessionFsSourceSpec
56{
57 GuestSessionFsSourceSpec()
58 : enmType(FsObjType_Unknown)
59 , enmPathStyle(PathStyle_Unknown)
60 , fDryRun(false) { RT_ZERO(Type); }
61
62 /** The (absolute) path to the source to use. */
63 Utf8Str strSource;
64 /** Filter to use. Currently not implemented and thus ignored. */
65 Utf8Str strFilter;
66 /** The root object type of this source (directory, file). */
67 FsObjType_T enmType;
68 /** The path style to use. */
69 PathStyle_T enmPathStyle;
70 /** Whether to do a dry run (e.g. not really touching anything) or not. */
71 bool fDryRun;
72 /** Directory copy flags. */
73 DirectoryCopyFlag_T fDirCopyFlags;
74 /** File copy flags. */
75 FileCopyFlag_T fFileCopyFlags;
76 /** Union to keep type-specific data. Must be a POD type (zero'ing). */
77 union
78 {
79 /** File-specific data. */
80 struct
81 {
82 /** Source file offset to start copying from. */
83 size_t offStart;
84 /** Host file handle to use for reading from / writing to.
85 * Optional and can be NULL if not used. */
86 PRTFILE phFile;
87 /** Source size (in bytes) to copy. */
88 uint64_t cbSize;
89 } File;
90 } Type;
91};
92
93/** A set of GuestSessionFsSourceSpec sources. */
94typedef std::vector<GuestSessionFsSourceSpec> GuestSessionFsSourceSet;
95
96/**
97 * Structure for keeping a file system entry.
98 */
99struct FsEntry
100{
101 /** The entrie's file mode. */
102 RTFMODE fMode;
103 /** The entrie's path, relative to the list's root path. */
104 Utf8Str strPath;
105};
106
107/** A vector of FsEntry entries. */
108typedef std::vector<FsEntry *> FsEntries;
109
110/**
111 * Class for storing and handling file system entries, neeed for doing
112 * internal file / directory operations to / from the guest.
113 */
114class FsList
115{
116public:
117
118 FsList(const GuestSessionTask &Task);
119 virtual ~FsList();
120
121public:
122
123 int Init(const Utf8Str &strSrcRootAbs, const Utf8Str &strDstRootAbs, const GuestSessionFsSourceSpec &SourceSpec);
124 void Destroy(void);
125
126#ifdef DEBUG
127 void DumpToLog(void);
128#endif
129
130 int AddEntryFromGuest(const Utf8Str &strFile, const GuestFsObjData &fsObjData);
131 int AddDirFromGuest(const Utf8Str &strPath, const Utf8Str &strSubDir = "");
132
133 int AddEntryFromHost(const Utf8Str &strFile, PCRTFSOBJINFO pcObjInfo);
134 int AddDirFromHost(const Utf8Str &strPath, const Utf8Str &strSubDir, char *pszPathReal, size_t cbPathReal, PRTDIRENTRYEX pDirEntry);
135
136public:
137
138 /** The guest session task object this list is working on. */
139 const GuestSessionTask &mTask;
140 /** File system filter / options to use for this task. */
141 GuestSessionFsSourceSpec mSourceSpec;
142 /** The source' root path. Always in the source's path style!
143 *
144 * For a single file list this is the full (absolute) path to a file,
145 * for a directory list this is the source root directory. */
146 Utf8Str mSrcRootAbs;
147 /** The destinations's root path. Always in the destination's path style!
148 *
149 * For a single file list this is the full (absolute) path to a file,
150 * for a directory list this is the destination root directory. */
151 Utf8Str mDstRootAbs;
152 /** Total size (in bytes) of all list entries together. */
153 uint64_t mcbTotalSize;
154 /** List of file system entries this list contains. */
155 FsEntries mVecEntries;
156};
157
158/** A set of FsList lists. */
159typedef std::vector<FsList *> FsLists;
160
161/**
162 * Abstract base class for a lenghtly per-session operation which
163 * runs in a Main worker thread.
164 */
165class GuestSessionTask
166 : public ThreadTask
167{
168public:
169 DECLARE_TRANSLATE_METHODS(GuestSessionTask)
170
171 GuestSessionTask(GuestSession *pSession);
172
173 virtual ~GuestSessionTask(void);
174
175public:
176
177 /**
178 * Function which implements the actual task to perform.
179 *
180 * @returns VBox status code.
181 */
182 virtual int Run(void) = 0;
183
184 void handler()
185 {
186 int vrc = Run();
187 if (RT_FAILURE(vrc)) /* Could be VERR_INTERRUPTED if the user manually canceled the task. */
188 {
189 /* Make sure to let users know if there is a buggy task which failed but didn't set the progress object
190 * to a failed state, and if not canceled manually by the user. */
191 BOOL fCanceled;
192 if (SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))))
193 {
194 if (!fCanceled)
195 {
196 BOOL fCompleted;
197 if (SUCCEEDED(mProgress->COMGETTER(Completed(&fCompleted))))
198 {
199 if (!fCompleted)
200 setProgressErrorMsg(E_UNEXPECTED,
201 Utf8StrFmt(tr("Task '%s' failed with %Rrc, but progress is still pending. Please report this bug!\n"),
202 mDesc.c_str(), vrc));
203 }
204 else
205 AssertReleaseMsgFailed(("Guest Control: Unable to retrieve progress completion status for task '%s' (task result is %Rrc)\n",
206 mDesc.c_str(), vrc));
207 }
208 }
209 else
210 AssertReleaseMsgFailed(("Guest Control: Unable to retrieve progress cancellation status for task '%s' (task result is %Rrc)\n",
211 mDesc.c_str(), vrc));
212 }
213 }
214
215 // unused: int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
216
217 virtual HRESULT Init(const Utf8Str &strTaskDesc)
218 {
219 setTaskDesc(strTaskDesc);
220 int vrc = createAndSetProgressObject(); /* Single operation by default. */
221 if (RT_SUCCESS(vrc))
222 return S_OK;
223 return E_FAIL;
224 }
225
226 /** Returns the task's progress object. */
227 const ComObjPtr<Progress>& GetProgressObject(void) const { return mProgress; }
228
229 /** Returns the task's guest session object. */
230 const ComObjPtr<GuestSession>& GetSession(void) const { return mSession; }
231
232protected:
233
234 /** @name Directory handling primitives.
235 * @{ */
236 int directoryCreateOnGuest(const com::Utf8Str &strPath,
237 uint32_t fMode, DirectoryCreateFlag_T enmDirectoryCreateFlags,
238 bool fFollowSymlinks, bool fCanExist);
239 int directoryCreateOnHost(const com::Utf8Str &strPath, uint32_t fMode, uint32_t fCreate, bool fCanExist);
240 /** @} */
241
242 /** @name File handling primitives.
243 * @{ */
244 int fileClose(const ComObjPtr<GuestFile> &file);
245 int fileCopyFromGuestInner(const Utf8Str &strSrcFile, ComObjPtr<GuestFile> &srcFile,
246 const Utf8Str &strDstFile, PRTFILE phDstFile,
247 FileCopyFlag_T fFileCopyFlags, uint64_t offCopy, uint64_t cbSize);
248 int fileCopyFromGuest(const Utf8Str &strSource, const Utf8Str &strDest, FileCopyFlag_T fFileCopyFlags);
249 int fileCopyToGuestInner(const Utf8Str &strSrcFile, RTVFSFILE hSrcFile,
250 const Utf8Str &strDstFile, ComObjPtr<GuestFile> &dstFile,
251 FileCopyFlag_T fFileCopyFlags, uint64_t offCopy, uint64_t cbSize);
252
253 int fileCopyToGuest(const Utf8Str &strSource, const Utf8Str &strDest, FileCopyFlag_T fFileCopyFlags);
254 /** @} */
255
256 /** @name Guest property handling primitives.
257 * @{ */
258 int getGuestProperty(const ComObjPtr<Guest> &pGuest, const Utf8Str &strPath, Utf8Str &strValue);
259 /** @} */
260
261 int setProgress(ULONG uPercent);
262 int setProgressSuccess(void);
263 HRESULT setProgressErrorMsg(HRESULT hrc, const Utf8Str &strMsg);
264 HRESULT setProgressErrorMsg(HRESULT hrc, const Utf8Str &strMsg, const GuestErrorInfo &guestErrorInfo);
265
266 inline void setTaskDesc(const Utf8Str &strTaskDesc) throw()
267 {
268 mDesc = strTaskDesc;
269 }
270
271 int createAndSetProgressObject(ULONG cOperations = 1);
272
273protected:
274
275 Utf8Str mDesc;
276 /** The guest session object this task is working on. */
277 ComObjPtr<GuestSession> mSession;
278 /** Progress object for getting updated when running
279 * asynchronously. Optional. */
280 ComObjPtr<Progress> mProgress;
281 /** The guest's path style as char representation (depending on the guest OS type set). */
282 Utf8Str mstrGuestPathStyle;
283};
284
285/**
286 * Task for opening a guest session.
287 */
288class GuestSessionTaskOpen : public GuestSessionTask
289{
290public:
291
292 GuestSessionTaskOpen(GuestSession *pSession,
293 uint32_t uFlags,
294 uint32_t uTimeoutMS);
295 virtual ~GuestSessionTaskOpen(void);
296 int Run(void);
297
298protected:
299
300 /** Session creation flags. */
301 uint32_t mFlags;
302 /** Session creation timeout (in ms). */
303 uint32_t mTimeoutMS;
304};
305
306class GuestSessionCopyTask : public GuestSessionTask
307{
308public:
309 DECLARE_TRANSLATE_METHODS(GuestSessionCopyTask)
310
311 GuestSessionCopyTask(GuestSession *pSession);
312 virtual ~GuestSessionCopyTask();
313
314protected:
315
316 /** Source set. */
317 GuestSessionFsSourceSet mSources;
318 /** Destination to copy to. */
319 Utf8Str mDest;
320 /** Vector of file system lists to handle.
321 * This either can be from the guest or the host side. */
322 FsLists mVecLists;
323};
324
325/**
326 * Guest session task for copying files / directories from guest to the host.
327 */
328class GuestSessionTaskCopyFrom : public GuestSessionCopyTask
329{
330public:
331 DECLARE_TRANSLATE_METHODS(GuestSessionTaskCopyFrom)
332
333 GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
334 virtual ~GuestSessionTaskCopyFrom(void);
335
336 HRESULT Init(const Utf8Str &strTaskDesc);
337 int Run(void);
338};
339
340/**
341 * Task for copying directories from host to the guest.
342 */
343class GuestSessionTaskCopyTo : public GuestSessionCopyTask
344{
345public:
346 DECLARE_TRANSLATE_METHODS(GuestSessionTaskCopyTo)
347
348 GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
349 virtual ~GuestSessionTaskCopyTo(void);
350
351 HRESULT Init(const Utf8Str &strTaskDesc);
352 int Run(void);
353};
354
355/**
356 * Implementation for a Guest Additions update process for logging process output to the release log.
357 */
358class UpdateAdditionsProcess : public GuestProcessWrapper
359{
360public:
361
362 UpdateAdditionsProcess(void) { }
363
364 virtual ~UpdateAdditionsProcess();
365
366 int onOutputCallback(uint32_t uHandle, const BYTE *pbData, size_t cbData);
367
368protected:
369
370 /** Current line of stdout. */
371 Utf8Str mLineStdOut;
372 /** Current line of stderr. */
373 Utf8Str mLineStdErr;
374};
375
376/**
377 * Tweaked startup info for a guest Guest Additions update process.
378 */
379class UpdateAdditionsStartupInfo : public GuestProcessStartupInfo
380{
381public:
382
383 UpdateAdditionsStartupInfo(void)
384 {
385 /* We want to have stdout / stderr handled by default for update processes. */
386 mFlags = ProcessCreateFlag_WaitForStdOut | ProcessCreateFlag_WaitForStdErr;
387 }
388};
389
390/**
391 * Guest session task for automatically updating the Guest Additions on the guest.
392 */
393class GuestSessionTaskUpdateAdditions : public GuestSessionTask
394{
395public:
396 DECLARE_TRANSLATE_METHODS(GuestSessionTaskUpdateAdditions)
397
398 GuestSessionTaskUpdateAdditions(GuestSession *pSession, const Utf8Str &strSource,
399 const ProcessArguments &aArguments, uint32_t fFlags);
400 virtual ~GuestSessionTaskUpdateAdditions(void);
401 int Run(void);
402
403protected:
404
405 /**
406 * Suported OS types for automatic updating.
407 */
408 enum eOSType
409 {
410 eOSType_Unknown = 0,
411 eOSType_Windows = 1,
412 eOSType_Linux = 2,
413 eOSType_Solaris = 3
414 };
415
416 /**
417 * Structure representing a file to
418 * get off the .ISO, copied to the guest.
419 */
420 struct ISOFile
421 {
422 ISOFile(const Utf8Str &aSource,
423 const Utf8Str &aDest,
424 uint32_t aFlags = 0)
425 : strSource(aSource),
426 strDest(aDest),
427 fFlags(aFlags) { }
428
429 ISOFile(const Utf8Str &aSource,
430 const Utf8Str &aDest,
431 uint32_t aFlags,
432 const GuestProcessStartupInfo &aStartupInfo)
433 : strSource(aSource),
434 strDest(aDest),
435 fFlags(aFlags),
436 mProcInfo(aStartupInfo)
437 {
438 mProcInfo.mExecutable = strDest;
439 if (mProcInfo.mName.isEmpty())
440 mProcInfo.mName = strDest;
441 }
442
443 /** Source file on .ISO. */
444 Utf8Str strSource;
445 /** Destination file on the guest. */
446 Utf8Str strDest;
447 /** ISO file flags (see ISOFILE_FLAG_ defines). */
448 uint32_t fFlags;
449 /** Optional arguments if this file needs to be
450 * executed. */
451 GuestProcessStartupInfo mProcInfo;
452 };
453
454 int addProcessArguments(ProcessArguments &aArgumentsDest, const ProcessArguments &aArgumentsSource);
455 int copyFileToGuest(GuestSession *pSession, RTVFS hVfsIso, Utf8Str const &strFileSource, const Utf8Str &strFileDest, bool fOptional);
456 int runFileOnGuest(GuestSession *pSession, GuestProcessStartupInfo &procInfo, bool fSilent = false);
457 HRESULT setUpdateErrorMsg(HRESULT hrc, const Utf8Str &strMsg);
458 HRESULT setUpdateErrorMsg(HRESULT hrc, const Utf8Str &strMsg, const GuestErrorInfo &guestErrorInfo);
459
460 int checkGuestAdditionsStatus(GuestSession *pSession, eOSType osType);
461 int waitForGuestSession(ComObjPtr<Guest> pGuest, eOSType osType, ComObjPtr<GuestSession> &pNewSession);
462
463 /** Files to handle. */
464 std::vector<ISOFile> mFiles;
465 /** The (optionally) specified Guest Additions .ISO on the host
466 * which will be used for the updating process. */
467 Utf8Str mSource;
468 /** (Optional) installer command line arguments. */
469 ProcessArguments mArguments;
470 /** Update flags. */
471 uint32_t mFlags;
472};
473#endif /* !MAIN_INCLUDED_GuestSessionImplTasks_h */
Note: See TracBrowser for help on using the repository browser.

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