Changeset 48014 in vbox for trunk/src/VBox
- Timestamp:
- Aug 23, 2013 9:01:29 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r47926 r48014 62 62 using namespace com; 63 63 64 /** @todo Move this into a helper module. */ 65 static const char *ctrlFileStatusToText(FileStatus_T enmStatus); 66 static const char *ctrlProcessStatusToText(ProcessStatus_T enmStatus); 67 static const char *ctrlSessionStatusToText(GuestSessionStatus_T enmStatus); 68 69 class GuestFileEventListener; 70 typedef ListenerImpl<GuestFileEventListener> GuestFileEventListenerImpl; 71 VBOX_LISTENER_DECLARE(GuestFileEventListenerImpl) 72 73 class GuestProcessEventListener; 74 typedef ListenerImpl<GuestProcessEventListener> GuestProcessEventListenerImpl; 75 VBOX_LISTENER_DECLARE(GuestProcessEventListenerImpl) 76 77 class GuestSessionEventListener; 78 typedef ListenerImpl<GuestSessionEventListener> GuestSessionEventListenerImpl; 79 VBOX_LISTENER_DECLARE(GuestSessionEventListenerImpl) 80 81 /** Simple statistics class for binding locally 82 * held data to a specific guest object. */ 83 class GuestEventStats 84 { 85 86 public: 87 88 GuestEventStats(void) 89 : uLastUpdatedMS(RTTimeMilliTS()) 90 { 91 } 92 93 /** @todo Make this more a class than a structure. */ 94 public: 95 96 uint64_t uLastUpdatedMS; 97 }; 98 99 class GuestFileStats : public GuestEventStats 100 { 101 102 public: 103 104 GuestFileStats(void) { } 105 106 GuestFileStats(ComObjPtr<GuestFileEventListenerImpl> pListenerImpl) 107 : mListener(pListenerImpl) 108 { 109 } 110 111 public: /** @todo */ 112 113 ComObjPtr<GuestFileEventListenerImpl> mListener; 114 }; 115 116 class GuestProcStats : public GuestEventStats 117 { 118 119 public: 120 121 GuestProcStats(void) { } 122 123 GuestProcStats(ComObjPtr<GuestProcessEventListenerImpl> pListenerImpl) 124 : mListener(pListenerImpl) 125 { 126 } 127 128 public: /** @todo */ 129 130 ComObjPtr<GuestProcessEventListenerImpl> mListener; 131 }; 132 133 class GuestSessionStats : public GuestEventStats 134 { 135 136 public: 137 138 GuestSessionStats(void) { } 139 140 GuestSessionStats(ComObjPtr<GuestSessionEventListenerImpl> pListenerImpl) 141 : mListener(pListenerImpl) 142 { 143 } 144 145 public: /** @todo */ 146 147 ComObjPtr<GuestSessionEventListenerImpl> mListener; 148 }; 149 150 /** Map containing all watched guest files. */ 151 typedef std::map< ComPtr<IGuestFile>, GuestFileStats > GuestEventFiles; 152 /** Map containing all watched guest processes. */ 153 typedef std::map< ComPtr<IGuestProcess>, GuestProcStats > GuestEventProcs; 154 /** Map containing all watched guest sessions. */ 155 typedef std::map< ComPtr<IGuestSession>, GuestSessionStats > GuestEventSessions; 156 157 class GuestListenerBase 158 { 159 public: 160 161 GuestListenerBase(void) 162 : mfVerbose(false) 163 { 164 } 165 166 virtual ~GuestListenerBase(void) 167 { 168 } 169 170 HRESULT init(bool fVerbose = false) 171 { 172 mfVerbose = fVerbose; 173 return S_OK; 174 } 175 176 protected: 177 178 /** Verbose flag. */ 179 bool mfVerbose; 180 }; 181 182 /** 183 * Handler for guest process events. 184 */ 185 class GuestFileEventListener : public GuestListenerBase 186 { 187 public: 188 189 GuestFileEventListener(void) 190 { 191 } 192 193 virtual ~GuestFileEventListener(void) 194 { 195 } 196 197 void uninit(void) 198 { 199 200 } 201 202 STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent) 203 { 204 switch (aType) 205 { 206 case VBoxEventType_OnGuestFileStateChanged: 207 { 208 HRESULT rc; 209 do 210 { 211 ComPtr<IGuestFileStateChangedEvent> pEvent = aEvent; 212 Assert(!pEvent.isNull()); 213 214 ComPtr<IGuestFile> pProcess; 215 CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pProcess.asOutParam())); 216 AssertBreak(!pProcess.isNull()); 217 FileStatus_T fileSts; 218 CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&fileSts)); 219 Bstr strPath; 220 CHECK_ERROR_BREAK(pProcess, COMGETTER(FileName)(strPath.asOutParam())); 221 ULONG uID; 222 CHECK_ERROR_BREAK(pProcess, COMGETTER(Id)(&uID)); 223 224 RTPrintf("File ID=%RU32 \"%s\" changed status to [%s]\n", 225 uID, Utf8Str(strPath).c_str(), 226 ctrlFileStatusToText(fileSts)); 227 228 } while (0); 229 break; 230 } 231 232 default: 233 AssertFailed(); 234 } 235 236 return S_OK; 237 } 238 239 protected: 240 241 }; 242 243 /** 244 * Handler for guest process events. 245 */ 246 class GuestProcessEventListener : public GuestListenerBase 247 { 248 public: 249 250 GuestProcessEventListener(void) 251 { 252 } 253 254 virtual ~GuestProcessEventListener(void) 255 { 256 } 257 258 void uninit(void) 259 { 260 261 } 262 263 STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent) 264 { 265 switch (aType) 266 { 267 case VBoxEventType_OnGuestProcessStateChanged: 268 { 269 HRESULT rc; 270 do 271 { 272 ComPtr<IGuestProcessStateChangedEvent> pEvent = aEvent; 273 Assert(!pEvent.isNull()); 274 275 ComPtr<IGuestProcess> pProcess; 276 CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam())); 277 AssertBreak(!pProcess.isNull()); 278 ProcessStatus_T procSts; 279 CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&procSts)); 280 Bstr strPath; 281 CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam())); 282 ULONG uPID; 283 CHECK_ERROR_BREAK(pProcess, COMGETTER(PID)(&uPID)); 284 285 RTPrintf("Process PID=%RU32 \"%s\" changed status to [%s]\n", 286 uPID, Utf8Str(strPath).c_str(), 287 ctrlProcessStatusToText(procSts)); 288 289 } while (0); 290 break; 291 } 292 293 default: 294 AssertFailed(); 295 } 296 297 return S_OK; 298 } 299 300 protected: 301 302 }; 303 304 /** 305 * Handler for guest session events. 306 */ 307 class GuestSessionEventListener : public GuestListenerBase 308 { 309 public: 310 311 GuestSessionEventListener(void) 312 { 313 } 314 315 virtual ~GuestSessionEventListener(void) 316 { 317 } 318 319 void uninit(void) 320 { 321 GuestEventProcs::iterator itProc = mProcs.begin(); 322 while (itProc != mProcs.end()) 323 { 324 if (!itProc->first.isNull()) 325 { 326 HRESULT rc; 327 do 328 { 329 /* Listener unregistration. */ 330 ComPtr<IEventSource> pES; 331 CHECK_ERROR_BREAK(itProc->first, COMGETTER(EventSource)(pES.asOutParam())); 332 if (!pES.isNull()) 333 CHECK_ERROR_BREAK(pES, UnregisterListener(itProc->second.mListener)); 334 } while (0); 335 itProc->first->Release(); 336 } 337 338 itProc++; 339 } 340 mProcs.clear(); 341 342 GuestEventFiles::iterator itFile = mFiles.begin(); 343 while (itFile != mFiles.end()) 344 { 345 if (!itFile->first.isNull()) 346 { 347 HRESULT rc; 348 do 349 { 350 /* Listener unregistration. */ 351 ComPtr<IEventSource> pES; 352 CHECK_ERROR_BREAK(itFile->first, COMGETTER(EventSource)(pES.asOutParam())); 353 if (!pES.isNull()) 354 CHECK_ERROR_BREAK(pES, UnregisterListener(itFile->second.mListener)); 355 } while (0); 356 itFile->first->Release(); 357 } 358 359 itFile++; 360 } 361 mFiles.clear(); 362 } 363 364 STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent) 365 { 366 switch (aType) 367 { 368 case VBoxEventType_OnGuestFileRegistered: 369 { 370 HRESULT rc; 371 do 372 { 373 ComPtr<IGuestFileRegisteredEvent> pEvent = aEvent; 374 Assert(!pEvent.isNull()); 375 376 ComPtr<IGuestFile> pFile; 377 CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pFile.asOutParam())); 378 AssertBreak(!pFile.isNull()); 379 BOOL fRegistered; 380 CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); 381 Bstr strPath; 382 CHECK_ERROR_BREAK(pFile, COMGETTER(FileName)(strPath.asOutParam())); 383 384 RTPrintf("File \"%s\" %s\n", 385 Utf8Str(strPath).c_str(), 386 fRegistered ? "registered" : "unregistered"); 387 if (fRegistered) 388 { 389 if (mfVerbose) 390 RTPrintf("Registering ...\n"); 391 392 /* Register for IGuestFile events. */ 393 ComObjPtr<GuestFileEventListenerImpl> pListener; 394 pListener.createObject(); 395 CHECK_ERROR_BREAK(pListener, init(new GuestFileEventListener())); 396 397 ComPtr<IEventSource> es; 398 CHECK_ERROR_BREAK(pFile, COMGETTER(EventSource)(es.asOutParam())); 399 com::SafeArray<VBoxEventType_T> eventTypes; 400 eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); 401 CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), 402 true /* Active listener */)); 403 404 GuestFileStats fileStats(pListener); 405 mFiles[pFile] = fileStats; 406 } 407 else 408 { 409 GuestEventFiles::iterator itFile = mFiles.find(pFile); 410 if (itFile != mFiles.end()) 411 { 412 if (mfVerbose) 413 RTPrintf("Unregistering file ...\n"); 414 415 if (!itFile->first.isNull()) 416 { 417 /* Listener unregistration. */ 418 ComPtr<IEventSource> pES; 419 CHECK_ERROR(itFile->first, COMGETTER(EventSource)(pES.asOutParam())); 420 if (!pES.isNull()) 421 CHECK_ERROR(pES, UnregisterListener(itFile->second.mListener)); 422 itFile->first->Release(); 423 } 424 425 mFiles.erase(itFile); 426 } 427 } 428 429 } while (0); 430 break; 431 } 432 433 case VBoxEventType_OnGuestProcessRegistered: 434 { 435 HRESULT rc; 436 do 437 { 438 ComPtr<IGuestProcessRegisteredEvent> pEvent = aEvent; 439 Assert(!pEvent.isNull()); 440 441 ComPtr<IGuestProcess> pProcess; 442 CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam())); 443 AssertBreak(!pProcess.isNull()); 444 BOOL fRegistered; 445 CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); 446 Bstr strPath; 447 CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam())); 448 449 RTPrintf("Process \"%s\" %s\n", 450 Utf8Str(strPath).c_str(), 451 fRegistered ? "registered" : "unregistered"); 452 if (fRegistered) 453 { 454 if (mfVerbose) 455 RTPrintf("Registering ...\n"); 456 457 /* Register for IGuestProcess events. */ 458 ComObjPtr<GuestProcessEventListenerImpl> pListener; 459 pListener.createObject(); 460 CHECK_ERROR_BREAK(pListener, init(new GuestProcessEventListener())); 461 462 ComPtr<IEventSource> es; 463 CHECK_ERROR_BREAK(pProcess, COMGETTER(EventSource)(es.asOutParam())); 464 com::SafeArray<VBoxEventType_T> eventTypes; 465 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 466 CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), 467 true /* Active listener */)); 468 469 GuestProcStats procStats(pListener); 470 mProcs[pProcess] = procStats; 471 } 472 else 473 { 474 GuestEventProcs::iterator itProc = mProcs.find(pProcess); 475 if (itProc != mProcs.end()) 476 { 477 if (mfVerbose) 478 RTPrintf("Unregistering process ...\n"); 479 480 if (!itProc->first.isNull()) 481 { 482 /* Listener unregistration. */ 483 ComPtr<IEventSource> pES; 484 CHECK_ERROR(itProc->first, COMGETTER(EventSource)(pES.asOutParam())); 485 if (!pES.isNull()) 486 CHECK_ERROR(pES, UnregisterListener(itProc->second.mListener)); 487 itProc->first->Release(); 488 } 489 490 mProcs.erase(itProc); 491 } 492 } 493 494 } while (0); 495 break; 496 } 497 498 case VBoxEventType_OnGuestSessionStateChanged: 499 { 500 HRESULT rc; 501 do 502 { 503 ComPtr<IGuestSessionStateChangedEvent> pEvent = aEvent; 504 Assert(!pEvent.isNull()); 505 ComPtr<IGuestSession> pSession; 506 CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam())); 507 AssertBreak(!pSession.isNull()); 508 509 GuestSessionStatus_T sessSts; 510 CHECK_ERROR_BREAK(pSession, COMGETTER(Status)(&sessSts)); 511 ULONG uID; 512 CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID)); 513 Bstr strName; 514 CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam())); 515 516 RTPrintf("Session ID=%RU32 \"%s\" changed status to [%s]\n", 517 uID, Utf8Str(strName).c_str(), 518 ctrlSessionStatusToText(sessSts)); 519 520 } while (0); 521 break; 522 } 523 524 default: 525 AssertFailed(); 526 } 527 528 return S_OK; 529 } 530 531 protected: 532 533 GuestEventFiles mFiles; 534 GuestEventProcs mProcs; 535 }; 536 64 537 /** 65 538 * Handler for guest events. 66 539 */ 67 class GuestEventListener 540 class GuestEventListener : public GuestListenerBase 68 541 { 69 542 public: … … 76 549 } 77 550 78 HRESULT init(void)79 {80 return S_OK;81 }82 83 551 void uninit(void) 84 552 { 85 mSession.setNull(); 553 GuestEventSessions::iterator itSession = mSessions.begin(); 554 while (itSession != mSessions.end()) 555 { 556 if (!itSession->first.isNull()) 557 { 558 HRESULT rc; 559 do 560 { 561 /* Listener unregistration. */ 562 ComPtr<IEventSource> pES; 563 CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam())); 564 if (!pES.isNull()) 565 CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener)); 566 567 } while (0); 568 itSession->first->Release(); 569 } 570 571 itSession++; 572 } 573 mSessions.clear(); 86 574 } 87 575 … … 90 578 switch (aType) 91 579 { 92 case VBoxEventType_OnGuestFileRegistered:93 break;94 95 case VBoxEventType_OnGuestProcessRegistered:96 break;97 98 580 case VBoxEventType_OnGuestSessionRegistered: 99 581 { … … 104 586 Assert(!pEvent.isNull()); 105 587 106 CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(mSession.asOutParam())); 107 AssertBreak(!mSession.isNull()); 588 ComPtr<IGuestSession> pSession; 589 CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam())); 590 AssertBreak(!pSession.isNull()); 108 591 BOOL fRegistered; 109 592 CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); 110 593 Bstr strName; 111 CHECK_ERROR_BREAK( mSession, COMGETTER(Name)(strName.asOutParam()));594 CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam())); 112 595 ULONG uID; 113 CHECK_ERROR_BREAK( mSession, COMGETTER(Id)(&uID));596 CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID)); 114 597 115 598 RTPrintf("Session ID=%RU32 \"%s\" %s\n", … … 118 601 if (fRegistered) 119 602 { 120 #if 0 603 if (mfVerbose) 604 RTPrintf("Registering ...\n"); 605 121 606 /* Register for IGuestSession events. */ 607 ComObjPtr<GuestSessionEventListenerImpl> pListener; 608 pListener.createObject(); 609 CHECK_ERROR_BREAK(pListener, init(new GuestSessionEventListener())); 610 122 611 ComPtr<IEventSource> es; 123 612 CHECK_ERROR_BREAK(pSession, COMGETTER(EventSource)(es.asOutParam())); … … 125 614 eventTypes.push_back(VBoxEventType_OnGuestFileRegistered); 126 615 eventTypes.push_back(VBoxEventType_OnGuestProcessRegistered); 127 CHECK_ERROR_BREAK(es, RegisterListener( this, ComSafeArrayAsInParam(eventTypes),616 CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), 128 617 true /* Active listener */)); 129 #endif 618 619 GuestSessionStats sessionStats(pListener); 620 mSessions[pSession] = sessionStats; 130 621 } 131 622 else 132 623 { 133 mSession.setNull(); 624 GuestEventSessions::iterator itSession = mSessions.find(pSession); 625 if (itSession != mSessions.end()) 626 { 627 if (mfVerbose) 628 RTPrintf("Unregistering ...\n"); 629 630 if (!itSession->first.isNull()) 631 { 632 /* Listener unregistration. */ 633 ComPtr<IEventSource> pES; 634 CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam())); 635 if (!pES.isNull()) 636 CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener)); 637 itSession->first->Release(); 638 } 639 640 mSessions.erase(itSession); 641 } 134 642 } 135 643 … … 147 655 protected: 148 656 149 ComPtr<IGuestSession> mSession;657 GuestEventSessions mSessions; 150 658 }; 151 659 typedef ListenerImpl<GuestEventListener> GuestEventListenerImpl; … … 475 983 * string. 476 984 */ 477 static const char *ctrl ExecProcessStatusToText(ProcessStatus_T enmStatus)985 static const char *ctrlProcessStatusToText(ProcessStatus_T enmStatus) 478 986 { 479 987 switch (enmStatus) … … 1202 1710 if (fVerbose) 1203 1711 RTPrintf("Exit code=%u (Status=%u [%s])\n", 1204 exitCode, procStatus, ctrl ExecProcessStatusToText(procStatus));1712 exitCode, procStatus, ctrlProcessStatusToText(procStatus)); 1205 1713 1206 1714 rcExit = (RTEXITCODE)ctrlExecProcessStatusToExitCode(procStatus, exitCode); 1207 1715 } 1208 1716 else if (fVerbose) 1209 RTPrintf("Process now is in status [%s]\n", ctrl ExecProcessStatusToText(procStatus));1717 RTPrintf("Process now is in status [%s]\n", ctrlProcessStatusToText(procStatus)); 1210 1718 } 1211 1719 else … … 3097 3605 3098 3606 RTPrintf("\n\t\tProcess #%-03zu PID=%-6RU32 Status=[%s] Command=%ls", 3099 a, uPID, ctrl ExecProcessStatusToText(procStatus), strExecPath.raw());3607 a, uPID, ctrlProcessStatusToText(procStatus), strExecPath.raw()); 3100 3608 } 3101 3609 } … … 3587 4095 { 3588 4096 /** @todo Timeout handling (see above)? */ 3589 RTThread Yield();4097 RTThreadSleep(10); 3590 4098 } 3591 4099
Note:
See TracChangeset
for help on using the changeset viewer.