VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIGuestControlInterface.cpp@ 82781

Last change on this file since 82781 was 79365, checked in by vboxsync, 5 years ago

Renaming VBoxGlobal to UICommon for bugref:9049 as planned.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.0 KB
Line 
1/* $Id: UIGuestControlInterface.cpp 79365 2019-06-26 15:57:32Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIGuestControlInterface class implementation.
4 */
5
6/*
7 * Copyright (C) 2016-2019 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/* GUI includes: */
19#include "UIErrorString.h"
20#include "UIGuestControlInterface.h"
21#include "UICommon.h"
22
23/* COM includes: */
24#include "CFsObjInfo.h"
25#include "CGuestDirectory.h"
26#include "CGuestProcess.h"
27#include "CGuestSession.h"
28#include "CGuestFsObjInfo.h"
29
30/* Misc. includes: */
31#include <iprt/err.h>
32#include <iprt/getopt.h>
33
34
35#define GCTLCMD_COMMON_OPT_USER 999 /**< The --username option number. */
36#define GCTLCMD_COMMON_OPT_PASSWORD 998 /**< The --password option number. */
37#define GCTLCMD_COMMON_OPT_PASSWORD_FILE 997 /**< The --password-file option number. */
38#define GCTLCMD_COMMON_OPT_DOMAIN 996 /**< The --domain option number. */
39#define GCTLCMD_COMMON_OPT_SESSION_NAME 995 /**< The --sessionname option number. */
40#define GCTLCMD_COMMON_OPT_SESSION_ID 994 /**< The --sessionid option number. */
41
42#define RETURN_ERROR(strError) \
43 do { \
44 m_strStatus.append(strError); \
45 return false; \
46 } while (0)
47
48#define RETURN_MESSAGE(strMessage) \
49 do { \
50 m_strStatus.append(strMessage); \
51 return true; \
52 } while (0)
53
54#define GCTLCMD_COMMON_OPTION_DEFS() \
55 { "--username", GCTLCMD_COMMON_OPT_USER, RTGETOPT_REQ_STRING }, \
56 { "--passwordfile", GCTLCMD_COMMON_OPT_PASSWORD_FILE, RTGETOPT_REQ_STRING }, \
57 { "--password", GCTLCMD_COMMON_OPT_PASSWORD, RTGETOPT_REQ_STRING }, \
58 { "--domain", GCTLCMD_COMMON_OPT_DOMAIN, RTGETOPT_REQ_STRING }, \
59 { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, \
60 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
61
62#define HANDLE_COMMON_OPTION_DEFS() \
63 case GCTLCMD_COMMON_OPT_USER: \
64 commandData.m_strUserName = ValueUnion.psz; \
65 break; \
66 case GCTLCMD_COMMON_OPT_PASSWORD: \
67 commandData.m_strPassword = ValueUnion.psz; \
68 break;
69
70/* static */ QString UIGuestControlInterface::getFsObjTypeString(KFsObjType type)
71{
72 QString strType;
73 switch(type)
74 {
75 case KFsObjType_Unknown:
76 strType = "Unknown";
77 break;
78 case KFsObjType_Fifo:
79 strType = "Fifo";
80 break;
81 case KFsObjType_DevChar:
82 strType = "DevChar";
83 break;
84 case KFsObjType_Directory:
85 strType = "Directory";
86 break;
87 case KFsObjType_DevBlock:
88 strType = "DevBlock";
89 break;
90 case KFsObjType_File:
91 strType = "File";
92 break;
93 case KFsObjType_Symlink:
94 strType = "Symlink";
95 break;
96 case KFsObjType_Socket:
97 strType = "Socket";
98 break;
99 case KFsObjType_WhiteOut:
100 strType = "WhiteOut";
101 break;
102 default:
103 strType = "Unknown";
104 break;
105 }
106 return strType;
107};
108
109QString generateErrorString(int getOptErrorCode, const RTGETOPTUNION &/*valueUnion*/)
110{
111 QString errorString;
112 // if (valueUnion.pDef)
113 // {
114 // if (valueUnion.pDef->pszLong)
115 // {
116 // errorString = QString(valueUnion.pDef->pszLong);
117 // }
118 // }
119
120 switch (getOptErrorCode)
121 {
122 case VERR_GETOPT_UNKNOWN_OPTION:
123 errorString = errorString.append("RTGetOpt: Command line option not recognized.");
124 break;
125 case VERR_GETOPT_REQUIRED_ARGUMENT_MISSING:
126 errorString = errorString.append("RTGetOpt: Command line option needs argument.");
127 break;
128 case VERR_GETOPT_INVALID_ARGUMENT_FORMAT:
129 errorString = errorString.append("RTGetOpt: Command line option has argument with bad format.");
130 break;
131 case VINF_GETOPT_NOT_OPTION:
132 errorString = errorString.append("RTGetOpt: Not an option.");
133 break;
134 case VERR_GETOPT_INDEX_MISSING:
135 errorString = errorString.append("RTGetOpt: Command line option needs an index.");
136 break;
137 default:
138 break;
139 }
140 return errorString;
141}
142
143/** Common option definitions: */
144class CommandData
145{
146public:
147 CommandData()
148 : m_bSessionIdGiven(false)
149 , m_bSessionNameGiven(false)
150 , m_bCreateParentDirectories(false){}
151 QString m_strUserName;
152 QString m_strPassword;
153 QString m_strExePath;
154 QString m_strSessionName;
155 QString m_strPath;
156 ULONG m_uSessionId;
157 QString m_strDomain;
158 bool m_bSessionIdGiven;
159 bool m_bSessionNameGiven;
160 /* Create the whole path during mkdir */
161 bool m_bCreateParentDirectories;
162 QVector<QString> m_arguments;
163 QVector<QString> m_environmentChanges;
164};
165
166UIGuestControlInterface::UIGuestControlInterface(QObject* parent, const CGuest &comGuest)
167 :QObject(parent)
168 , m_comGuest(comGuest)
169 , m_strHelp("[common-options]\t[--username <name>] [--domain <domain>]\n"
170 "\t\t[--passwordfile <file> | --password <password>]\n"
171 "start\t\t[common-options]\n"
172 "\t\t[--exe <path to executable>] [--timeout <msec>]\n"
173 "\t\t[--sessionid <id> | [sessionname <name>]]\n"
174 "\t\t[-E|--putenv <NAME>[=<VALUE>]] [--unquoted-args]\n"
175 "\t\t[--ignore-operhaned-processes] [--profile]\n"
176 "\t\t-- <program/arg0> [argument1] ... [argumentN]]\n"
177 "createsession\t\t[common-options] [--sessionname <name>]\n"
178 "mkdir\t\t[common-options]\n"
179 "\t\t[-P|--parents] [<guest directory>\n"
180 "\t\t[--sessionid <id> | --sessionname <name>]\n"
181 "stat|ls\t\t[common-options]\n"
182 "\t\t[--sessionid <id> | --sessionname <name>]\n"
183 "list\n"
184 )
185{
186 prepareSubCommandHandlers();
187}
188
189bool UIGuestControlInterface::handleMkdir(int argc , char** argv)
190{
191
192 CommandData commandData;
193
194 static const RTGETOPTDEF s_aOptions[] =
195 {
196 GCTLCMD_COMMON_OPTION_DEFS()
197 { "--sessionname", GCTLCMD_COMMON_OPT_SESSION_NAME, RTGETOPT_REQ_STRING },
198 { "--sessionid", GCTLCMD_COMMON_OPT_SESSION_ID, RTGETOPT_REQ_UINT32 },
199 { "--parents", 'P', RTGETOPT_REQ_NOTHING }
200 };
201
202 int ch;
203 bool pathFound = false;
204 RTGETOPTUNION ValueUnion;
205 RTGETOPTSTATE GetState;
206 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1 /* ignore 0th element (command) */, 0);
207 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
208 {
209 switch (ch)
210 {
211 HANDLE_COMMON_OPTION_DEFS()
212 case GCTLCMD_COMMON_OPT_SESSION_NAME:
213 commandData.m_bSessionNameGiven = true;
214 commandData.m_strSessionName = ValueUnion.psz;
215 break;
216 case GCTLCMD_COMMON_OPT_SESSION_ID:
217 commandData.m_bSessionIdGiven = true;
218 commandData.m_uSessionId = ValueUnion.i32;
219 break;
220 case 'P':
221 commandData.m_bCreateParentDirectories = true;
222 break;
223 case VINF_GETOPT_NOT_OPTION:
224 if (!pathFound)
225 {
226 commandData.m_strPath = ValueUnion.psz;
227 pathFound = true;
228 }
229 /* Allow only a single NOT_OPTION */
230 else
231 RETURN_ERROR(generateErrorString(ch, ValueUnion));
232
233 break;
234 default:
235 RETURN_ERROR(generateErrorString(ch, ValueUnion));
236 }
237 }
238 if (commandData.m_strPath.isEmpty())
239 RETURN_ERROR(QString(m_strHelp).append("Syntax error! No path is given\n"));
240
241 CGuestSession guestSession;
242 if (!findOrCreateSession(commandData, guestSession) || !guestSession.isOk())
243 return false;
244
245
246 //const QString &strErr = comProgressInstall.GetErrorInfo().GetText();
247 QVector<KDirectoryCreateFlag> creationFlags;
248 if (commandData.m_bCreateParentDirectories)
249 creationFlags.push_back(KDirectoryCreateFlag_None);
250 else
251 creationFlags.push_back(KDirectoryCreateFlag_Parents);
252
253 guestSession.DirectoryCreate(commandData.m_strPath, 0 /*ULONG aMode*/, creationFlags);
254
255 //startProcess(commandData, guestSession);
256 return true;
257}
258
259bool UIGuestControlInterface::handleStat(int argc, char** argv)
260{
261 CommandData commandData;
262
263 static const RTGETOPTDEF s_aOptions[] =
264 {
265 GCTLCMD_COMMON_OPTION_DEFS()
266 { "--sessionname", GCTLCMD_COMMON_OPT_SESSION_NAME, RTGETOPT_REQ_STRING },
267 { "--sessionid", GCTLCMD_COMMON_OPT_SESSION_ID, RTGETOPT_REQ_UINT32 }
268 };
269
270 int ch;
271 bool pathFound = false;
272 RTGETOPTUNION ValueUnion;
273 RTGETOPTSTATE GetState;
274 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1 /* ignore 0th element (command) */, 0);
275 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
276 {
277 switch (ch)
278 {
279 HANDLE_COMMON_OPTION_DEFS()
280 case GCTLCMD_COMMON_OPT_SESSION_NAME:
281 commandData.m_bSessionNameGiven = true;
282 commandData.m_strSessionName = ValueUnion.psz;
283 break;
284 case GCTLCMD_COMMON_OPT_SESSION_ID:
285 commandData.m_bSessionIdGiven = true;
286 commandData.m_uSessionId = ValueUnion.i32;
287 break;
288 case 'P':
289 commandData.m_bCreateParentDirectories = true;
290 break;
291 case VINF_GETOPT_NOT_OPTION:
292 if (!pathFound)
293 {
294 commandData.m_strPath = ValueUnion.psz;
295 pathFound = true;
296 }
297 /* Allow only a single NOT_OPTION */
298 else
299 RETURN_ERROR(generateErrorString(ch, ValueUnion));
300
301 break;
302 default:
303 RETURN_ERROR(generateErrorString(ch, ValueUnion));
304 }
305 }
306 if (commandData.m_strPath.isEmpty())
307 RETURN_ERROR(QString(m_strHelp).append("Syntax error! No path is given\n"));
308
309 CGuestSession guestSession;
310 if (!findOrCreateSession(commandData, guestSession) || !guestSession.isOk())
311 return false;
312 if (guestSession.GetStatus() != KGuestSessionStatus_Started)
313 RETURN_ERROR("The guest session is not valid");
314
315 bool isADirectory =
316 guestSession.DirectoryExists(commandData.m_strPath, false /*BOOL aFollowSymlinks*/);
317
318 bool isAFile = false;
319 if (!isADirectory)
320 isAFile = guestSession.FileExists(commandData.m_strPath, false /*BOOL aFollowSymlinks*/);
321
322 if (!isADirectory && !isAFile)
323 RETURN_ERROR("Specified object does not exist");
324
325 CGuestFsObjInfo fsObjectInfo = guestSession.FsObjQueryInfo(commandData.m_strPath, false /*BOOL aFollowSymlinks*/);
326 if (!fsObjectInfo.isOk())
327 RETURN_ERROR("Cannot get object info");
328 QString strObjectInfo = getFsObjInfoString<CGuestFsObjInfo>(fsObjectInfo);
329
330 /* In case it is a directory get a list of its content: */
331 if (isADirectory)
332 {
333 QVector<KDirectoryOpenFlag> aFlags;
334 aFlags.push_back(KDirectoryOpenFlag_None);
335 CGuestDirectory directory = guestSession.DirectoryOpen(commandData.m_strPath, /*aFilter*/ "", aFlags);
336 if (directory.isOk())
337 {
338 CFsObjInfo directoryInfo = directory.Read();
339 while (directoryInfo.isOk())
340 {
341 strObjectInfo.append("\n");
342 strObjectInfo.append(getFsObjInfoString<CFsObjInfo>(directoryInfo));
343 directoryInfo = directory.Read();
344 }
345 }
346 }
347 RETURN_MESSAGE(strObjectInfo);
348}
349
350bool UIGuestControlInterface::handleList(int, char**)
351{
352 if (!m_comGuest.isOk())
353 RETURN_ERROR("The guest session is not valid");
354
355 QString strSessionInfo;
356 QVector<CGuestSession> sessions = m_comGuest.GetSessions();
357 if (sessions.isEmpty())
358 {
359 strSessionInfo.append("No guest sessions");
360 RETURN_MESSAGE(strSessionInfo);
361 }
362 strSessionInfo += QString("Listing %1 guest sessions in total:\n").arg(QString::number(sessions.size()));
363 //strSessionInfo += QString("\t%1\t%2\n").arg("Session Name").arg("Session Id");
364
365 for (int i = 0; i < sessions.size(); ++i)
366 {
367 strSessionInfo += QString("\tName: %1\t\tID: %2\n").arg(sessions[i].GetName()).arg(QString::number(sessions[i].GetId()));
368 QVector<CGuestProcess> processes = sessions[i].GetProcesses();
369 strSessionInfo += QString("\t%1 guest prcesses for this session:\n").arg(QString::number(processes.size()));
370
371 for (int j = 0; j < processes.size(); ++j)
372 {
373 strSessionInfo += QString("\t\tName: %1\t\tID: %2\n").arg(processes[j].GetName()).arg(QString::number(processes[j].GetPID()));
374
375 }
376 }
377 RETURN_MESSAGE(strSessionInfo);
378}
379
380bool UIGuestControlInterface::handleStart(int argc, char** argv)
381{
382 enum kGstCtrlRunOpt
383 {
384 kGstCtrlRunOpt_IgnoreOrphanedProcesses = 1000,
385 kGstCtrlRunOpt_NoProfile, /** @todo Deprecated and will be removed soon; use kGstCtrlRunOpt_Profile instead, if needed. */
386 kGstCtrlRunOpt_Profile,
387 kGstCtrlRunOpt_Dos2Unix,
388 kGstCtrlRunOpt_Unix2Dos,
389 kGstCtrlRunOpt_WaitForStdOut,
390 kGstCtrlRunOpt_NoWaitForStdOut,
391 kGstCtrlRunOpt_WaitForStdErr,
392 kGstCtrlRunOpt_NoWaitForStdErr
393 };
394
395 CommandData commandData;
396
397 static const RTGETOPTDEF s_aOptions[] =
398 {
399 GCTLCMD_COMMON_OPTION_DEFS()
400 { "--sessionname", GCTLCMD_COMMON_OPT_SESSION_NAME, RTGETOPT_REQ_STRING },
401 { "--sessionid", GCTLCMD_COMMON_OPT_SESSION_ID, RTGETOPT_REQ_UINT32 },
402 { "--putenv", 'E', RTGETOPT_REQ_STRING },
403 { "--exe", 'e', RTGETOPT_REQ_STRING },
404 { "--timeout", 't', RTGETOPT_REQ_UINT32 },
405 { "--unquoted-args", 'u', RTGETOPT_REQ_NOTHING },
406 { "--ignore-operhaned-processes", kGstCtrlRunOpt_IgnoreOrphanedProcesses, RTGETOPT_REQ_NOTHING },
407 { "--no-profile", kGstCtrlRunOpt_NoProfile, RTGETOPT_REQ_NOTHING }, /** @todo Deprecated. */
408 { "--profile", kGstCtrlRunOpt_Profile, RTGETOPT_REQ_NOTHING }
409 };
410
411 int ch;
412 RTGETOPTUNION ValueUnion;
413 RTGETOPTSTATE GetState;
414 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1 /* ignore 0th element (command) */, 0);
415 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
416 {
417 switch (ch)
418 {
419 HANDLE_COMMON_OPTION_DEFS()
420 case GCTLCMD_COMMON_OPT_SESSION_NAME:
421 commandData.m_bSessionNameGiven = true;
422 commandData.m_strSessionName = ValueUnion.psz;
423 break;
424 case GCTLCMD_COMMON_OPT_SESSION_ID:
425 commandData.m_bSessionIdGiven = true;
426 commandData.m_uSessionId = ValueUnion.i32;
427 break;
428 case 'e':
429 commandData.m_strExePath = ValueUnion.psz;
430 break;
431 default:
432 RETURN_ERROR(generateErrorString(ch, ValueUnion));
433 }
434 }
435 if (commandData.m_strExePath.isEmpty())
436 RETURN_ERROR(QString(m_strHelp).append("Syntax error! No executable is given\n"));
437
438 CGuestSession guestSession;
439 if (!findOrCreateSession(commandData, guestSession) || !guestSession.isOk())
440 return false;
441 startProcess(commandData, guestSession);
442 return true;
443}
444
445bool UIGuestControlInterface::findOrCreateSession(const CommandData &commandData, CGuestSession &outGuestSession)
446{
447 if (commandData.m_bSessionNameGiven && commandData.m_strSessionName.isEmpty())
448 RETURN_ERROR(QString(m_strHelp).append("'Session Name' is not name valid\n"));
449
450 /* Check if sessionname and sessionid are both supplied */
451 if (commandData.m_bSessionIdGiven && commandData.m_bSessionNameGiven)
452 RETURN_ERROR(QString(m_strHelp).append("Both 'Session Name' and 'Session Id' are supplied\n"));
453
454 /* If sessionid is given then look for the session. if not found return without starting the process: */
455 else if (commandData.m_bSessionIdGiven && !commandData.m_bSessionNameGiven)
456 {
457 if (!findSession(commandData.m_uSessionId, outGuestSession))
458 {
459 RETURN_ERROR(QString(m_strHelp).append("No session with id %1 found.\n").arg(commandData.m_uSessionId));
460 }
461 else
462 return true;
463 }
464 /* If sessionname is given then look for the session. if not try to create a session with the provided name: */
465 else if (!commandData.m_bSessionIdGiven && commandData.m_bSessionNameGiven)
466 {
467 if (!findSession(commandData.m_strSessionName, outGuestSession))
468 {
469 if (!createSession(commandData, outGuestSession))
470 return false;
471 else
472 return true;
473 }
474 else
475 return true;
476 }
477 /* search within the existing CGuestSessions and return a valid one if found: */
478 if (findAValidGuestSession(outGuestSession))
479 return true;
480 /* if neither sessionname and session id is given then create a new session */
481 if (!createSession(commandData, outGuestSession))
482 return false;
483 return true;
484}
485
486bool UIGuestControlInterface::findAValidGuestSession(CGuestSession &outGuestSession)
487{
488 if (!m_comGuest.isOk())
489 return false;
490
491 QVector<CGuestSession> sessions = m_comGuest.GetSessions();
492 for (int i = 0; i < sessions.size(); ++i)
493 {
494 if (sessions[i].isOk() && sessions[i].GetStatus() == KGuestSessionStatus_Started)
495 {
496 outGuestSession = sessions[i];
497 return true;
498 }
499 }
500 return false;
501}
502
503bool UIGuestControlInterface::handleHelp(int, char**)
504{
505 emit sigOutputString(m_strHelp);
506 return true;
507}
508
509bool UIGuestControlInterface::handleCreateSession(int argc, char** argv)
510{
511 CommandData commandData;
512
513 static const RTGETOPTDEF s_aOptions[] =
514 {
515 GCTLCMD_COMMON_OPTION_DEFS()
516 { "--sessionname", GCTLCMD_COMMON_OPT_SESSION_NAME, RTGETOPT_REQ_STRING }
517 };
518
519 int ch;
520 RTGETOPTUNION ValueUnion;
521 RTGETOPTSTATE GetState;
522 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
523 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
524 {
525 switch (ch)
526 {
527 HANDLE_COMMON_OPTION_DEFS()
528 case GCTLCMD_COMMON_OPT_SESSION_NAME:
529 commandData.m_strSessionName = ValueUnion.psz;
530 if (commandData.m_strSessionName.isEmpty())
531 {
532 RETURN_ERROR(QString("'Session Name' is not name valid\n").append(m_strHelp));
533 }
534 break;
535 default:
536 break;
537 }
538 }
539 CGuestSession guestSession;
540 if (!createSession(commandData, guestSession))
541 return false;
542 return true;
543}
544
545bool UIGuestControlInterface::startProcess(const CommandData &commandData, CGuestSession &guestSession)
546{
547 QVector<KProcessCreateFlag> createFlags;
548 createFlags.push_back(KProcessCreateFlag_WaitForProcessStartOnly);
549 CGuestProcess process = guestSession.ProcessCreate(commandData.m_strExePath,
550 commandData.m_arguments,
551 commandData.m_environmentChanges,
552 createFlags,
553 0);
554 if (!process.isOk())
555 return false;
556 return true;
557}
558
559UIGuestControlInterface::~UIGuestControlInterface()
560{
561}
562
563void UIGuestControlInterface::prepareSubCommandHandlers()
564{
565 m_subCommandHandlers.insert("createsession" , &UIGuestControlInterface::handleCreateSession);
566 m_subCommandHandlers.insert("start", &UIGuestControlInterface::handleStart);
567 m_subCommandHandlers.insert("help" , &UIGuestControlInterface::handleHelp);
568 m_subCommandHandlers.insert("mkdir" , &UIGuestControlInterface::handleMkdir);
569 m_subCommandHandlers.insert("stat" , &UIGuestControlInterface::handleStat);
570 m_subCommandHandlers.insert("ls" , &UIGuestControlInterface::handleStat);
571 m_subCommandHandlers.insert("list" , &UIGuestControlInterface::handleList);
572}
573
574void UIGuestControlInterface::putCommand(const QString &strCommand)
575{
576 if (!isGuestAdditionsAvailable(m_comGuest))
577 {
578 emit sigOutputString("No guest addtions detected. Guest control requires guest additions");
579 return;
580 }
581
582 char **argv;
583 int argc;
584 QByteArray array = strCommand.toLocal8Bit();
585 RTGetOptArgvFromString(&argv, &argc, array.data(), RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, 0);
586 m_strStatus.clear();
587 static const RTGETOPTDEF s_aOptions[] =
588 {
589 GCTLCMD_COMMON_OPTION_DEFS()
590 };
591
592 int ch;
593 RTGETOPTUNION ValueUnion;
594 RTGETOPTSTATE GetState;
595 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
596 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
597 {
598 switch (ch)
599 {
600 case VINF_GETOPT_NOT_OPTION:
601 {
602 /* Try to map ValueUnion.psz to a sub command handler: */
603 QString strNoOption(ValueUnion.psz);
604 if (!strNoOption.isNull())
605 {
606 QMap<QString, HandleFuncPtr>::iterator iterator =
607 m_subCommandHandlers.find(strNoOption);
608 if (iterator != m_subCommandHandlers.end())
609 {
610 (this->*(iterator.value()))(argc, argv);
611 RTGetOptArgvFree(argv);
612 if (!m_strStatus.isEmpty())
613 emit sigOutputString(m_strStatus);
614 return;
615 }
616 else
617 {
618 emit sigOutputString(QString(m_strHelp).append("\nSyntax Error. Unknown Command '%1'").arg(ValueUnion.psz));
619 RTGetOptArgvFree(argv);
620 return;
621 }
622 }
623 break;
624 }
625 default:
626 break;
627 }
628 }
629 if (!m_strStatus.isEmpty())
630 emit sigOutputString(m_strStatus);
631
632 RTGetOptArgvFree(argv);
633}
634
635bool UIGuestControlInterface::findSession(ULONG sessionId, CGuestSession& outSession)
636{
637 if (!m_comGuest.isOk())
638 return false;
639 QVector<CGuestSession> sessionVector = m_comGuest.GetSessions();
640 if (sessionVector.isEmpty())
641 return false;
642 for (int i = 0; i < sessionVector.size(); ++i)
643 {
644 if (sessionVector.at(i).isOk() && sessionId == sessionVector.at(i).GetId())
645 {
646 outSession = sessionVector.at(i);
647 return true;
648 }
649 }
650 return false;
651}
652
653bool UIGuestControlInterface::findSession(const QString& strSessionName, CGuestSession& outSession)
654{
655 if (!m_comGuest.isOk())
656 return false;
657 QVector<CGuestSession> sessionVector = m_comGuest.FindSession(strSessionName);
658 if (sessionVector.isEmpty())
659 return false;
660 /* Return the first session with @a sessionName */
661 outSession = sessionVector.at(0);
662 return false;
663}
664
665bool UIGuestControlInterface::createSession(const CommandData &commandData, CGuestSession& outSession)
666{
667 if (!m_comGuest.isOk())
668 return false;
669 if (commandData.m_strUserName.isEmpty())
670 RETURN_ERROR("No user name has been given");
671 CGuestSession guestSession = m_comGuest.CreateSession(commandData.m_strUserName,
672 commandData.m_strPassword,
673 commandData.m_strDomain,
674 commandData.m_strSessionName);
675
676 if (!guestSession.isOk())
677 return false;
678
679 /* Wait session to start: */
680 const ULONG waitTimeout = 2000;
681 KGuestSessionWaitResult waitResult = guestSession.WaitFor(KGuestSessionWaitForFlag_Start, waitTimeout);
682 if (waitResult != KGuestSessionWaitResult_Start)
683 return false;
684
685 outSession = guestSession;
686 return true;
687}
688
689/* static */ bool UIGuestControlInterface::isGuestAdditionsAvailable(const CGuest &guest)
690{
691 if (!guest.isOk())
692 return false;
693 CGuest guestNonConst = const_cast<CGuest&>(guest);
694 return guestNonConst.GetAdditionsStatus(guestNonConst.GetAdditionsRunLevel());
695}
696
697template<typename T>
698QString UIGuestControlInterface::getFsObjInfoString(const T &fsObjectInfo) const
699{
700 QString strObjectInfo;
701 if (!fsObjectInfo.isOk())
702 return strObjectInfo;
703
704 strObjectInfo.append(getFsObjTypeString(fsObjectInfo.GetType()).append("\t"));
705 strObjectInfo.append(fsObjectInfo.GetName().append("\t"));
706 strObjectInfo.append(QString::number(fsObjectInfo.GetObjectSize()).append("\t"));
707
708 /* Currently I dont know a way to convert these into a meaningful date/time: */
709 // strObjectInfo.append("BirthTime", QString::number(fsObjectInfo.GetBirthTime()));
710 // strObjectInfo.append("ChangeTime", QString::number(fsObjectInfo.GetChangeTime()));
711
712 return strObjectInfo;
713}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use