VirtualBox

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

Last change on this file since 97626 was 97626, checked in by vboxsync, 2 years ago

Guest Control/Main: Fixed running out of context IDs when copying huge directory listings. Internally IGuestFile::i_closeFile() wasn't unregistering the file object from the guest session, only the public interface IGuestFile::close() did so. bugref:10286

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.1 KB
Line 
1/* $Id: GuestSessionImplTasks.h 97626 2022-11-21 13:34:53Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Guest session tasks header.
4 */
5
6/*
7 * Copyright (C) 2018-2022 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 rc = createAndSetProgressObject(); /* Single operation by default. */
221 if (RT_FAILURE(rc))
222 return E_FAIL;
223
224 return S_OK;
225 }
226
227 /** Returns the task's progress object. */
228 const ComObjPtr<Progress>& GetProgressObject(void) const { return mProgress; }
229
230 /** Returns the task's guest session object. */
231 const ComObjPtr<GuestSession>& GetSession(void) const { return mSession; }
232
233protected:
234
235 /** @name Directory handling primitives.
236 * @{ */
237 int directoryCreateOnGuest(const com::Utf8Str &strPath,
238 uint32_t fMode, DirectoryCreateFlag_T enmDirectoryCreateFlags,
239 bool fFollowSymlinks, bool fCanExist);
240 int directoryCreateOnHost(const com::Utf8Str &strPath, uint32_t fMode, uint32_t fCreate, bool fCanExist);
241 /** @} */
242
243 /** @name File handling primitives.
244 * @{ */
245 int fileClose(const ComObjPtr<GuestFile> &file);
246 int fileCopyFromGuestInner(const Utf8Str &strSrcFile, ComObjPtr<GuestFile> &srcFile,
247 const Utf8Str &strDstFile, PRTFILE phDstFile,
248 FileCopyFlag_T fFileCopyFlags, uint64_t offCopy, uint64_t cbSize);
249 int fileCopyFromGuest(const Utf8Str &strSource, const Utf8Str &strDest, FileCopyFlag_T fFileCopyFlags);
250 int fileCopyToGuestInner(const Utf8Str &strSrcFile, RTVFSFILE hSrcFile,
251 const Utf8Str &strDstFile, ComObjPtr<GuestFile> &dstFile,
252 FileCopyFlag_T fFileCopyFlags, uint64_t offCopy, uint64_t cbSize);
253
254 int fileCopyToGuest(const Utf8Str &strSource, const Utf8Str &strDest, FileCopyFlag_T fFileCopyFlags);
255 /** @} */
256
257 /** @name Guest property handling primitives.
258 * @{ */
259 int getGuestProperty(const ComObjPtr<Guest> &pGuest, const Utf8Str &strPath, Utf8Str &strValue);
260 /** @} */
261
262 int setProgress(ULONG uPercent);
263 int setProgressSuccess(void);
264 HRESULT setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg);
265 HRESULT setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg, const GuestErrorInfo &guestErrorInfo);
266
267 inline void setTaskDesc(const Utf8Str &strTaskDesc) throw()
268 {
269 mDesc = strTaskDesc;
270 }
271
272 int createAndSetProgressObject(ULONG cOperations = 1);
273
274protected:
275
276 Utf8Str mDesc;
277 /** The guest session object this task is working on. */
278 ComObjPtr<GuestSession> mSession;
279 /** Progress object for getting updated when running
280 * asynchronously. Optional. */
281 ComObjPtr<Progress> mProgress;
282 /** The guest's path style as char representation (depending on the guest OS type set). */
283 Utf8Str mstrGuestPathStyle;
284};
285
286/**
287 * Task for opening a guest session.
288 */
289class GuestSessionTaskOpen : public GuestSessionTask
290{
291public:
292
293 GuestSessionTaskOpen(GuestSession *pSession,
294 uint32_t uFlags,
295 uint32_t uTimeoutMS);
296 virtual ~GuestSessionTaskOpen(void);
297 int Run(void);
298
299protected:
300
301 /** Session creation flags. */
302 uint32_t mFlags;
303 /** Session creation timeout (in ms). */
304 uint32_t mTimeoutMS;
305};
306
307class GuestSessionCopyTask : public GuestSessionTask
308{
309public:
310 DECLARE_TRANSLATE_METHODS(GuestSessionCopyTask)
311
312 GuestSessionCopyTask(GuestSession *pSession);
313 virtual ~GuestSessionCopyTask();
314
315protected:
316
317 /** Source set. */
318 GuestSessionFsSourceSet mSources;
319 /** Destination to copy to. */
320 Utf8Str mDest;
321 /** Vector of file system lists to handle.
322 * This either can be from the guest or the host side. */
323 FsLists mVecLists;
324};
325
326/**
327 * Guest session task for copying files / directories from guest to the host.
328 */
329class GuestSessionTaskCopyFrom : public GuestSessionCopyTask
330{
331public:
332 DECLARE_TRANSLATE_METHODS(GuestSessionTaskCopyFrom)
333
334 GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
335 virtual ~GuestSessionTaskCopyFrom(void);
336
337 HRESULT Init(const Utf8Str &strTaskDesc);
338 int Run(void);
339};
340
341/**
342 * Task for copying directories from host to the guest.
343 */
344class GuestSessionTaskCopyTo : public GuestSessionCopyTask
345{
346public:
347 DECLARE_TRANSLATE_METHODS(GuestSessionTaskCopyTo)
348
349 GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
350 virtual ~GuestSessionTaskCopyTo(void);
351
352 HRESULT Init(const Utf8Str &strTaskDesc);
353 int Run(void);
354};
355
356/**
357 * Guest session task for automatically updating the Guest Additions on the guest.
358 */
359class GuestSessionTaskUpdateAdditions : public GuestSessionTask
360{
361public:
362 DECLARE_TRANSLATE_METHODS(GuestSessionTaskUpdateAdditions)
363
364 GuestSessionTaskUpdateAdditions(GuestSession *pSession, const Utf8Str &strSource,
365 const ProcessArguments &aArguments, uint32_t fFlags);
366 virtual ~GuestSessionTaskUpdateAdditions(void);
367 int Run(void);
368
369protected:
370
371 /**
372 * Suported OS types for automatic updating.
373 */
374 enum eOSType
375 {
376 eOSType_Unknown = 0,
377 eOSType_Windows = 1,
378 eOSType_Linux = 2,
379 eOSType_Solaris = 3
380 };
381
382 /**
383 * Structure representing a file to
384 * get off the .ISO, copied to the guest.
385 */
386 struct ISOFile
387 {
388 ISOFile(const Utf8Str &aSource,
389 const Utf8Str &aDest,
390 uint32_t aFlags = 0)
391 : strSource(aSource),
392 strDest(aDest),
393 fFlags(aFlags) { }
394
395 ISOFile(const Utf8Str &aSource,
396 const Utf8Str &aDest,
397 uint32_t aFlags,
398 const GuestProcessStartupInfo &aStartupInfo)
399 : strSource(aSource),
400 strDest(aDest),
401 fFlags(aFlags),
402 mProcInfo(aStartupInfo)
403 {
404 mProcInfo.mExecutable = strDest;
405 if (mProcInfo.mName.isEmpty())
406 mProcInfo.mName = strDest;
407 }
408
409 /** Source file on .ISO. */
410 Utf8Str strSource;
411 /** Destination file on the guest. */
412 Utf8Str strDest;
413 /** ISO file flags (see ISOFILE_FLAG_ defines). */
414 uint32_t fFlags;
415 /** Optional arguments if this file needs to be
416 * executed. */
417 GuestProcessStartupInfo mProcInfo;
418 };
419
420 int addProcessArguments(ProcessArguments &aArgumentsDest, const ProcessArguments &aArgumentsSource);
421 int copyFileToGuest(GuestSession *pSession, RTVFS hVfsIso, Utf8Str const &strFileSource, const Utf8Str &strFileDest, bool fOptional);
422 int runFileOnGuest(GuestSession *pSession, GuestProcessStartupInfo &procInfo);
423 int waitForGuestSession(ComObjPtr<Guest> pGuest);
424
425 /** Files to handle. */
426 std::vector<ISOFile> mFiles;
427 /** The (optionally) specified Guest Additions .ISO on the host
428 * which will be used for the updating process. */
429 Utf8Str mSource;
430 /** (Optional) installer command line arguments. */
431 ProcessArguments mArguments;
432 /** Update flags. */
433 uint32_t mFlags;
434};
435#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