VirtualBox

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

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

include/GuestSessionImplTasks.h: Added missing initializers in GuestSessionFsSourceSpec(), found by Parfait.

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