- Timestamp:
- Feb 14, 2018 6:02:21 PM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlInterface.cpp
r70992 r71016 25 25 26 26 /* COM includes: */ 27 # include "CGuestProcess.h" 27 28 # include "CGuestSession.h" 28 29 30 #include <iprt/getopt.h> 29 31 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 32 30 33 31 34 #define SUCCESS_RETURN(strMessage){ \ … … 39 42 } 40 43 44 #define GCTLCMD_COMMON_OPT_USER 999 /**< The --username option number. */ 45 #define GCTLCMD_COMMON_OPT_PASSWORD 998 /**< The --password option number. */ 46 #define GCTLCMD_COMMON_OPT_PASSWORD_FILE 997 /**< The --password-file option number. */ 47 #define GCTLCMD_COMMON_OPT_DOMAIN 996 /**< The --domain option number. */ 48 #define GCTLCMD_COMMON_OPT_SESSION_NAME 995 /**< The --sessionname option number. */ 49 #define GCTLCMD_COMMON_OPT_SESSION_ID 994 /**< The --sessionid option number. */ 50 /** Common option definitions. */ 51 struct CommandData 52 { 53 QString m_strUserName; 54 QString m_strPassword; 55 QString m_strExePath; 56 QString m_strSessionName; 57 ULONG m_uSessionId; 58 QString m_strDomain; 59 QVector<QString> m_arguments; 60 QVector<QString> m_environmentChanges; 61 }; 62 41 63 UIGuestControlInterface::UIGuestControlInterface(QObject* parent, const CGuest &comGuest) 42 64 :QObject(parent) 43 65 , m_comGuest(comGuest) 44 , m_strHelp("start\n" 45 " --session: Starts a new session. It takes following arguments\n" 46 " --username=username: Sets the username. Overrides the username set by 'set --username=username'\n" 47 " --password=password: Sets the password. Overrides the username set by 'set --password=password'\n" 48 " --session-name=name: Optional\n" 49 " --domain=domain: Currently not implemented and siliently ignored\n" 50 " --process: Starts a new process. It takes following arguments\n" 51 " --username=username: Sets the username. Overrides the username set by 'set --username=username'\n" 52 " --password=password: Sets the password. Overrides the username set by 'set --password=password'\n" 53 " --session-name=name: Session name to start the new process under. If not found a new session with this name is created\n" 54 " --exe-path=path: Execuable path\n" 55 " --argument1=argument ... --argumentN=argument: Optional. Arguments to be passed to the new process\n" 56 " --environmentVar1=variable ... --environmentVarN=variable: Optional. Currently no avaible through this interface\n" 57 " --timout=time: (in ms). Optional. Timeout (in ms) for limiting the guest process' running time. Give 0 for an infinite timeout.\n" 58 59 "set\n" 60 " --username=username: Sets user name which is used in subsequent calls (maybe overriden).\n" 61 " --password=password: Sets user name which is used in subsequent calls (maybe overriden).\n" 62 63 //"start --process --username=username --password=password --session-name=name --exepath=path --argument1=argument ... --argumentN=argument --environmentVar1=variable ... --environmentVarN=variable\n" 66 , m_strHelp("[common-options] [--verbose|-v] [--quiet|-q]\n" 67 " [--username <name>] [--domain <domain>]\n" 68 " [--passwordfile <file> | --password <password>]\n" 69 "start [common-options]\n" 70 " [--exe <path to executable>] [--timeout <msec>]\n" 71 " [--sessionid <id> | [sessionname <name>]]\n" 72 " [-E|--putenv <NAME>[=<VALUE>]] [--unquoted-args]\n" 73 " [--ignore-operhaned-processes] [--profile]\n" 74 " -- <program/arg0> [argument1] ... [argumentN]]\n" 75 "create [common-options] [sessionname <name>]\n" 64 76 ) 65 , m_bUsernameIsSet(false) 66 , m_bPasswordIsSet(false) 67 { 77 { 78 prepareSubCommandHandlers(); 79 } 80 81 bool UIGuestControlInterface::handleStart(int argc, char** argv) 82 { 83 enum kGstCtrlRunOpt 84 { 85 kGstCtrlRunOpt_IgnoreOrphanedProcesses = 1000, 86 kGstCtrlRunOpt_NoProfile, /** @todo Deprecated and will be removed soon; use kGstCtrlRunOpt_Profile instead, if needed. */ 87 kGstCtrlRunOpt_Profile, 88 kGstCtrlRunOpt_Dos2Unix, 89 kGstCtrlRunOpt_Unix2Dos, 90 kGstCtrlRunOpt_WaitForStdOut, 91 kGstCtrlRunOpt_NoWaitForStdOut, 92 kGstCtrlRunOpt_WaitForStdErr, 93 kGstCtrlRunOpt_NoWaitForStdErr 94 }; 95 96 CommandData commandData; 97 parseCommonOptions(argc, argv, commandData); 98 99 static const RTGETOPTDEF s_aOptions[] = 100 { 101 { "--sessionname", GCTLCMD_COMMON_OPT_SESSION_NAME, RTGETOPT_REQ_STRING }, 102 { "--sessionid", GCTLCMD_COMMON_OPT_SESSION_ID, RTGETOPT_REQ_UINT32 }, 103 { "--putenv", 'E', RTGETOPT_REQ_STRING }, 104 { "--exe", 'e', RTGETOPT_REQ_STRING }, 105 { "--timeout", 't', RTGETOPT_REQ_UINT32 }, 106 { "--unquoted-args", 'u', RTGETOPT_REQ_NOTHING }, 107 { "--ignore-operhaned-processes", kGstCtrlRunOpt_IgnoreOrphanedProcesses, RTGETOPT_REQ_NOTHING }, 108 { "--no-profile", kGstCtrlRunOpt_NoProfile, RTGETOPT_REQ_NOTHING }, /** @todo Deprecated. */ 109 { "--profile", kGstCtrlRunOpt_Profile, RTGETOPT_REQ_NOTHING } 110 }; 111 112 bool sessionNameGiven = false; 113 bool sessionIdGiven = false; 114 115 int ch; 116 RTGETOPTUNION ValueUnion; 117 RTGETOPTSTATE GetState; 118 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0); 119 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 120 { 121 switch (ch) 122 { 123 case GCTLCMD_COMMON_OPT_SESSION_NAME: 124 sessionNameGiven = true; 125 commandData.m_strSessionName = ValueUnion.psz; 126 break; 127 case GCTLCMD_COMMON_OPT_SESSION_ID: 128 sessionIdGiven = true; 129 commandData.m_uSessionId = ValueUnion.i32; 130 break; 131 case 'e': 132 commandData.m_strExePath = ValueUnion.psz; 133 break; 134 default: 135 break; 136 } 137 } 138 139 if (sessionNameGiven && commandData.m_strSessionName.isEmpty()) 140 { 141 emit sigOutputString(QString("'Session Name' is not name valid\n").append(m_strHelp)); 142 return false; 143 } 144 145 CGuestSession guestSession; 146 /* Check if sessionname and sessionid are both supplied */ 147 if (sessionIdGiven && sessionNameGiven) 148 { 149 emit sigOutputString(QString("Both 'Session Name' and 'Session Id' are supplied\n").append(m_strHelp)); 150 return false; 151 } 152 /* If sessionid is given then look for the session. if not found return without starting the process: */ 153 else if (sessionIdGiven && !sessionNameGiven) 154 { 155 if (!findSession(commandData.m_uSessionId, guestSession)) 156 { 157 emit sigOutputString(QString("No session with id %1 found.\n").arg(commandData.m_uSessionId).append(m_strHelp)); 158 return false; 159 } 160 } 161 /* If sessionname is given then look for the session. if not try to create a session with the provided name: */ 162 else if (!sessionIdGiven && sessionNameGiven) 163 { 164 if (!findSession(commandData.m_strSessionName, guestSession)) 165 { 166 if (!createSession(commandData, guestSession)) 167 { 168 emit sigOutputString(QString("Guest session could not be created")); 169 return false; 170 } 171 } 172 } 173 /* if neither sessionname and session id is given then create a new session */ 174 else 175 { 176 if (!createSession(commandData, guestSession)) 177 { 178 emit sigOutputString(QString("Guest session could not be created")); 179 return false; 180 } 181 182 } 183 if (!guestSession.isOk()) 184 return false; 185 startProcess(commandData, guestSession); 186 return true; 187 } 188 189 bool UIGuestControlInterface::handleHelp(int, char**) 190 { 191 emit sigOutputString(m_strHelp); 192 return true; 193 } 194 195 bool UIGuestControlInterface::handleCreate(int argc, char** argv) 196 { 197 CommandData commandData; 198 if (!parseCommonOptions(argc, argv, commandData)) 199 return false; 200 201 static const RTGETOPTDEF s_aOptions[] = 202 { 203 { "--sessionname", GCTLCMD_COMMON_OPT_SESSION_NAME, RTGETOPT_REQ_STRING } 204 }; 205 206 int ch; 207 RTGETOPTUNION ValueUnion; 208 RTGETOPTSTATE GetState; 209 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0); 210 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 211 { 212 switch (ch) 213 { 214 case GCTLCMD_COMMON_OPT_SESSION_NAME: 215 commandData.m_strSessionName = ValueUnion.psz; 216 if (commandData.m_strSessionName.isEmpty()) 217 { 218 emit sigOutputString(QString("'Session Name' is not name valid\n").append(m_strHelp)); 219 return false; 220 } 221 break; 222 default: 223 break; 224 } 225 } 226 CGuestSession guestSession; 227 if (!createSession(commandData, guestSession)) 228 return false; 229 return true; 230 } 231 232 bool UIGuestControlInterface::parseCommonOptions(int argc, char** argv, CommandData& commandData) 233 { 234 static const RTGETOPTDEF s_aOptions[] = 235 { 236 { "--username", GCTLCMD_COMMON_OPT_USER, RTGETOPT_REQ_STRING }, 237 { "--passwordfile", GCTLCMD_COMMON_OPT_PASSWORD_FILE, RTGETOPT_REQ_STRING }, 238 { "--password", GCTLCMD_COMMON_OPT_PASSWORD, RTGETOPT_REQ_STRING }, 239 { "--domain", GCTLCMD_COMMON_OPT_DOMAIN, RTGETOPT_REQ_STRING }, 240 { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, 241 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 242 { "--help", 'h', RTGETOPT_REQ_NOTHING } 243 }; 244 245 246 int ch; 247 RTGETOPTUNION ValueUnion; 248 RTGETOPTSTATE GetState; 249 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0); 250 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 251 { 252 switch (ch) 253 { 254 /* Username: */ 255 case GCTLCMD_COMMON_OPT_USER: 256 commandData.m_strUserName = ValueUnion.psz; 257 break; 258 /* Paaword: */ 259 case GCTLCMD_COMMON_OPT_PASSWORD: 260 commandData.m_strPassword = ValueUnion.psz; 261 break; 262 default: 263 break; 264 } 265 } 266 267 return true; 268 } 269 270 bool UIGuestControlInterface::startProcess(const CommandData &commandData, CGuestSession &guestSession) 271 { 272 QVector<KProcessCreateFlag> createFlags; 273 createFlags.push_back(KProcessCreateFlag_WaitForProcessStartOnly); 274 275 CGuestProcess process = guestSession.ProcessCreate(commandData.m_strExePath, 276 commandData.m_arguments, 277 commandData.m_environmentChanges, 278 createFlags, 279 0); 280 if (!process.isOk()) 281 return false; 282 return true; 283 } 284 285 UIGuestControlInterface::~UIGuestControlInterface() 286 { 287 } 288 289 void UIGuestControlInterface::prepareSubCommandHandlers() 290 { 291 m_subCommandHandlers.insert("create" , &UIGuestControlInterface::handleCreate); 292 m_subCommandHandlers.insert("start", &UIGuestControlInterface::handleStart); 293 m_subCommandHandlers.insert("help" , &UIGuestControlInterface::handleHelp); 68 294 } 69 295 70 296 void UIGuestControlInterface::putCommand(const QString &strCommand) 71 297 { 72 parseCommand(strCommand); 73 } 74 75 bool UIGuestControlInterface::parseCommand(const QString &strCommand) 76 { 77 reset(); 78 QStringList commandStrList = strCommand.split(" ", QString::SkipEmptyParts, Qt::CaseSensitive); 79 80 if (commandStrList.isEmpty()) 81 ERROR_RETURN("Syntax Error! Type 'help' for usage") 82 else if (commandStrList.at(0) == "help") 83 SUCCESS_RETURN(m_strHelp) 84 85 if (!createArgumentMap(commandStrList)) 86 return false; 87 88 if (commandStrList.at(0) == "start") 89 return parseStartCommand(); 90 return parseSetCommand(); 91 //ERROR_RETURN("Syntax Error! Type 'help' for usage") 92 } 93 94 bool UIGuestControlInterface::createArgumentMap(const QStringList &commandList) 95 { 96 if (commandList.size() <= 1) 97 ERROR_RETURN("Syntax Error! Type 'help' for usage") 98 99 /* All arguments start with '--' and may have a value: */ 100 for (int i = 1; i < commandList.size(); ++i) 101 { 102 const QString &strArgument = commandList.at(i); 103 if (strArgument.size() <= 2 || strArgument.left(2) != "--") 104 ERROR_RETURN("Syntax Error! Type 'help' for usage") 105 106 QString strKey; 107 QString strValue; 108 /* If argument includes a '=' then we have a two parts: */ 109 int indexOfEqual = strArgument.indexOf("="); 110 strKey = strArgument.mid(2 /* -- prefix */, indexOfEqual - 2); 111 if (indexOfEqual != -1) 112 strValue = strArgument.mid(indexOfEqual + 1); 113 if (indexOfEqual != -1 && strValue.isEmpty()) 114 ERROR_RETURN("Syntax Error! Type 'help' for usage") 115 if (strKey.isEmpty()) 116 ERROR_RETURN("Syntax Error! Type 'help' for usage") 117 118 m_argumentMap.insert(strKey, strValue); 119 } 120 return true; 121 } 122 123 bool UIGuestControlInterface::parseStartCommand() 124 { 125 if (m_argumentMap.contains("session")) 126 return parseStartSessionCommand(); 127 128 ERROR_RETURN("Syntax Error! Type 'help' for usage") 129 } 130 131 //CGuestProcess CGuestSession::ProcessCreate(const QString & aExecutable, 132 //const QVector<QString> & aArguments, 133 //const QVector<QString> & aEnvironmentChanges, const QVector<KProcessCreateFlag> & aFlags, ULONG aTimeoutMS) 134 135 136 bool UIGuestControlInterface::parseStartSessionCommand() 137 { 138 /* Each "start" command requires username and password: */ 139 QString username; 140 QString password; 141 if (!getUsername(username)) 142 return false; 143 if (!getPassword(password)) 144 return false; 145 /* Check if session name is supplied: */ 146 QString sessionname = m_argumentMap.value("session-name", QString()); 298 299 char **argv; 300 int argc; 301 QByteArray array = strCommand.toLocal8Bit(); 302 RTGetOptArgvFromString(&argv, &argc, array.data(), RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, 0); 303 304 static const RTGETOPTDEF s_aOptions[] = {}; 305 306 int ch; 307 RTGETOPTUNION ValueUnion; 308 RTGETOPTSTATE GetState; 309 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0); 310 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 311 { 312 switch (ch) 313 { 314 case VINF_GETOPT_NOT_OPTION: 315 { 316 /* Try to map ValueUnion.psz to a sub command handler: */ 317 QString strNoOption(ValueUnion.psz); 318 if (!strNoOption.isNull()) 319 { 320 QMap<QString, HandleFuncPtr>::iterator iterator = 321 m_subCommandHandlers.find(strNoOption); 322 if (iterator != m_subCommandHandlers.end()) 323 { 324 (this->*(iterator.value()))(argc, argv); 325 RTGetOptArgvFree(argv); 326 return; 327 } 328 else 329 { 330 emit sigOutputString(QString("Unknown Command '%1'\n").arg(ValueUnion.psz).append(m_strHelp)); 331 RTGetOptArgvFree(argv); 332 return; 333 } 334 } 335 break; 336 } 337 default: 338 break; 339 } 340 } 341 342 RTGetOptArgvFree(argv); 343 } 344 345 bool UIGuestControlInterface::findSession(ULONG sessionId, CGuestSession& outSession) 346 { 147 347 if (!m_comGuest.isOk()) 148 ERROR_RETURN("No Valid guest object found") 149 150 CGuestSession comGuestSession = 151 m_comGuest.CreateSession(username, password, QString() /*domain name*/, sessionname); 152 if (!comGuestSession.isOk()) 153 ERROR_RETURN("Could not create guest session") 154 155 SUCCESS_RETURN("Guest Session started"); 156 } 157 158 bool UIGuestControlInterface::parseSetCommand() 159 { 160 /* After 'set' we should have a single argument with value: */ 161 if (m_argumentMap.size() != 1) 162 ERROR_RETURN("Syntax Error! Type 'help' for usage") 163 /* Look for username: */ 164 if (m_argumentMap.contains("username")) 165 { 166 QString strName = m_argumentMap.value("username", QString()); 167 if (strName.isEmpty()) 168 ERROR_RETURN("Syntax Error! Type 'help' for usage") 169 m_strUsername = strName; 170 return true; 171 } 172 else if (m_argumentMap.contains("password")) 173 { 174 QString strPassword = m_argumentMap.value("password", QString()); 175 if (strPassword.isEmpty()) 176 ERROR_RETURN("Syntax Error! Type 'help' for usage") 177 m_strPassword = strPassword; 178 return true; 179 } 180 /* Found neither 'usernanme' nor 'password' after set: */ 181 ERROR_RETURN("Syntax Error! Type 'help' for usage") 182 } 183 184 bool UIGuestControlInterface::getUsername(QString &outStrUsername) 185 { 186 /* First check argument map for a valid username string: */ 187 QString mapValue = m_argumentMap.value("username", QString()); 188 if (!mapValue.isEmpty()) 189 { 190 outStrUsername = mapValue; 191 return true; 192 } 193 /* Check to see if username is set previously. */ 194 if (m_bUsernameIsSet) 195 { 196 outStrUsername = m_strUsername; 197 return true; 198 } 199 ERROR_RETURN("No username is set. Type 'help' for usage"); 200 } 201 202 bool UIGuestControlInterface::getPassword(QString &outStrPassword) 203 { 204 /* First check argument map for a valid password string: */ 205 QString mapValue = m_argumentMap.value("password", QString()); 206 if (!mapValue.isEmpty()) 207 { 208 outStrPassword = mapValue; 209 return true; 210 } 211 212 /* Check to see if username is set previously. */ 213 if (m_bPasswordIsSet) 214 { 215 outStrPassword = m_strPassword; 216 return true; 217 } 218 ERROR_RETURN("No password is set. Type 'help' for usage") 219 } 220 221 void UIGuestControlInterface::reset() 222 { 223 m_argumentMap.clear(); 224 m_bUsernameIsSet = false; 225 m_bPasswordIsSet = false; 226 } 348 return false; 349 QVector<CGuestSession> sessionVector = m_comGuest.GetSessions(); 350 if (sessionVector.isEmpty()) 351 return false; 352 for(int i = 0; i < sessionVector.size(); ++i) 353 { 354 if (sessionVector.at(i).isOk() && sessionId == sessionVector.at(i).GetId()) 355 { 356 outSession = sessionVector.at(i); 357 return true; 358 } 359 } 360 return false; 361 } 362 363 bool UIGuestControlInterface::findSession(const QString& strSessionName, CGuestSession& outSession) 364 { 365 if (!m_comGuest.isOk()) 366 return false; 367 QVector<CGuestSession> sessionVector = m_comGuest.FindSession(strSessionName); 368 if (sessionVector.isEmpty()) 369 return false; 370 /* Return the first session with @a sessionName */ 371 outSession = sessionVector.at(0); 372 return false; 373 } 374 375 bool UIGuestControlInterface::createSession(const CommandData &commandData, CGuestSession& outSession) 376 { 377 CGuestSession guestSession = m_comGuest.CreateSession(commandData.m_strUserName, 378 commandData.m_strPassword, 379 commandData.m_strDomain, 380 commandData.m_strSessionName); 381 if (!guestSession.isOk()) 382 { 383 emit sigOutputString(QString("Guest session could not be created")); 384 return false; 385 } 386 /* Wait session to start: */ 387 const ULONG waitTimeout = 1;//2000; 388 KGuestSessionWaitResult waitResult = guestSession.WaitFor(KGuestSessionWaitForFlag_Start, waitTimeout); 389 if (waitResult != KGuestSessionWaitResult_Start) 390 { 391 emit sigOutputString("Guest Session has not started yet"); 392 return false; 393 } 394 outSession = guestSession; 395 return true; 396 } -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlInterface.h
r70988 r71016 28 28 #include "CGuest.h" 29 29 30 30 class UIGuestControlSubCommandBase; 31 class CommandData; 31 32 class UIGuestControlInterface : public QObject 32 33 { … … 41 42 42 43 UIGuestControlInterface(QObject *parent, const CGuest &comGeust); 44 ~UIGuestControlInterface(); 45 43 46 /** Receives a command string */ 44 47 void putCommand(const QString &strCommand); … … 48 51 private: 49 52 50 bool parseCommand(const QString &strCommand); 51 bool createArgumentMap(const QStringList &commandList); 52 bool parseStartCommand(); 53 bool parseStartSessionCommand(); 54 bool parseSetCommand(); 53 typedef bool (UIGuestControlInterface::*HandleFuncPtr)(int, char**); 55 54 56 /* Search username/password withing argument map if not 57 check if username/password is set previously. Return false 58 if username/string could not be found. */ 59 bool getUsername(QString &outStrUsername); 60 bool getPassword(QString &outStrUsername); 61 void reset(); 55 bool findSession(const QString& strSessionName, CGuestSession& outSession); 56 bool findSession(ULONG strSessionId, CGuestSession& outSession); 57 bool createSession(const CommandData &commandData, CGuestSession &outSession); 62 58 63 /** @name API call wrappers 64 * @{ */ 65 void createSession(const QString &username, const QString &password, 66 const QString &sessionName); 67 /** @} */ 59 void prepareSubCommandHandlers(); 60 bool startProcess(const CommandData &commandData, CGuestSession &guestSession); 68 61 62 /* Handles the 'start' process command */ 63 bool handleStart(int, char**); 64 /* Handles the 'help' process command */ 65 bool handleHelp(int, char**); 66 /* Handles the 'create' session command */ 67 bool handleCreate(int, char**); 68 bool parseCommonOptions(int argc, char** argv, CommandData& commandData); 69 69 70 70 CGuest m_comGuest; 71 71 const QString m_strHelp; 72 QString m_strStatus; 73 QString m_strUsername; 74 QString m_strPassword; 75 bool m_bUsernameIsSet; 76 bool m_bPasswordIsSet; 77 78 /* Key is argument and value is value (possibly empty). */ 79 QMap<QString, QString> m_argumentMap; 80 72 /* A map of function pointers to handleXXXX functions */ 73 QMap<QString, HandleFuncPtr> m_subCommandHandlers; 81 74 }; 82 75
Note:
See TracChangeset
for help on using the changeset viewer.