[49181] | 1 | /* $Id: VBoxManageGuestCtrlListener.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * VBoxManage - Guest control listener implementations.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[96407] | 7 | * Copyright (C) 2013-2022 Oracle and/or its affiliates.
|
---|
[49181] | 8 | *
|
---|
[96407] | 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
|
---|
[49181] | 26 | */
|
---|
| 27 |
|
---|
| 28 |
|
---|
[57358] | 29 | /*********************************************************************************************************************************
|
---|
| 30 | * Header Files *
|
---|
| 31 | *********************************************************************************************************************************/
|
---|
[49181] | 32 | #include "VBoxManage.h"
|
---|
| 33 | #include "VBoxManageGuestCtrl.h"
|
---|
| 34 |
|
---|
| 35 | #include <VBox/com/com.h>
|
---|
| 36 | #include <VBox/com/ErrorInfo.h>
|
---|
| 37 | #include <VBox/com/errorprint.h>
|
---|
| 38 |
|
---|
[84519] | 39 | #include <iprt/semaphore.h>
|
---|
[49181] | 40 | #include <iprt/time.h>
|
---|
| 41 |
|
---|
| 42 | #include <map>
|
---|
| 43 | #include <vector>
|
---|
| 44 |
|
---|
[92372] | 45 | DECLARE_TRANSLATION_CONTEXT(GuestCtrlLsnr);
|
---|
[55604] | 46 |
|
---|
[92372] | 47 |
|
---|
[84519] | 48 | /** Event semaphore we're using for notification. */
|
---|
| 49 | extern RTSEMEVENT g_SemEventGuestCtrlCanceled;
|
---|
[55604] | 50 |
|
---|
[84519] | 51 |
|
---|
[55604] | 52 | /*
|
---|
| 53 | * GuestListenerBase
|
---|
| 54 | * GuestListenerBase
|
---|
| 55 | * GuestListenerBase
|
---|
| 56 | */
|
---|
| 57 |
|
---|
[49181] | 58 | GuestListenerBase::GuestListenerBase(void)
|
---|
| 59 | : mfVerbose(false)
|
---|
| 60 | {
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | GuestListenerBase::~GuestListenerBase(void)
|
---|
| 64 | {
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | HRESULT GuestListenerBase::init(bool fVerbose)
|
---|
| 68 | {
|
---|
| 69 | mfVerbose = fVerbose;
|
---|
| 70 | return S_OK;
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 |
|
---|
[55604] | 74 |
|
---|
| 75 | /*
|
---|
| 76 | * GuestFileEventListener
|
---|
| 77 | * GuestFileEventListener
|
---|
| 78 | * GuestFileEventListener
|
---|
| 79 | */
|
---|
| 80 |
|
---|
[49181] | 81 | GuestFileEventListener::GuestFileEventListener(void)
|
---|
| 82 | {
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | GuestFileEventListener::~GuestFileEventListener(void)
|
---|
| 86 | {
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | void GuestFileEventListener::uninit(void)
|
---|
| 90 | {
|
---|
| 91 |
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | STDMETHODIMP GuestFileEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
|
---|
| 95 | {
|
---|
| 96 | switch (aType)
|
---|
| 97 | {
|
---|
| 98 | case VBoxEventType_OnGuestFileStateChanged:
|
---|
| 99 | {
|
---|
[95140] | 100 | HRESULT hrc;
|
---|
[49181] | 101 | do
|
---|
| 102 | {
|
---|
| 103 | ComPtr<IGuestFileStateChangedEvent> pEvent = aEvent;
|
---|
| 104 | Assert(!pEvent.isNull());
|
---|
| 105 |
|
---|
| 106 | ComPtr<IGuestFile> pProcess;
|
---|
| 107 | CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pProcess.asOutParam()));
|
---|
| 108 | AssertBreak(!pProcess.isNull());
|
---|
| 109 | FileStatus_T fileSts;
|
---|
| 110 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&fileSts));
|
---|
| 111 | Bstr strPath;
|
---|
[75926] | 112 | CHECK_ERROR_BREAK(pProcess, COMGETTER(Filename)(strPath.asOutParam()));
|
---|
[49181] | 113 | ULONG uID;
|
---|
| 114 | CHECK_ERROR_BREAK(pProcess, COMGETTER(Id)(&uID));
|
---|
| 115 |
|
---|
[92372] | 116 | RTPrintf(GuestCtrlLsnr::tr("File ID=%RU32 \"%s\" changed status to [%s]\n"),
|
---|
[55604] | 117 | uID, Utf8Str(strPath).c_str(), gctlFileStatusToText(fileSts));
|
---|
[49181] | 118 |
|
---|
| 119 | } while (0);
|
---|
| 120 | break;
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | default:
|
---|
| 124 | AssertFailed();
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | return S_OK;
|
---|
| 128 | }
|
---|
| 129 |
|
---|
[55604] | 130 |
|
---|
| 131 | /*
|
---|
| 132 | * GuestProcessEventListener
|
---|
| 133 | * GuestProcessEventListener
|
---|
| 134 | * GuestProcessEventListener
|
---|
| 135 | */
|
---|
| 136 |
|
---|
[49181] | 137 | GuestProcessEventListener::GuestProcessEventListener(void)
|
---|
| 138 | {
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 | GuestProcessEventListener::~GuestProcessEventListener(void)
|
---|
| 142 | {
|
---|
| 143 | }
|
---|
| 144 |
|
---|
| 145 | void GuestProcessEventListener::uninit(void)
|
---|
| 146 | {
|
---|
| 147 |
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | STDMETHODIMP GuestProcessEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
|
---|
| 151 | {
|
---|
| 152 | switch (aType)
|
---|
| 153 | {
|
---|
| 154 | case VBoxEventType_OnGuestProcessStateChanged:
|
---|
| 155 | {
|
---|
[95140] | 156 | HRESULT hrc;
|
---|
[49181] | 157 | do
|
---|
| 158 | {
|
---|
| 159 | ComPtr<IGuestProcessStateChangedEvent> pEvent = aEvent;
|
---|
| 160 | Assert(!pEvent.isNull());
|
---|
| 161 |
|
---|
| 162 | ComPtr<IGuestProcess> pProcess;
|
---|
| 163 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam()));
|
---|
| 164 | AssertBreak(!pProcess.isNull());
|
---|
| 165 | ProcessStatus_T procSts;
|
---|
| 166 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&procSts));
|
---|
| 167 | Bstr strPath;
|
---|
| 168 | CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam()));
|
---|
| 169 | ULONG uPID;
|
---|
| 170 | CHECK_ERROR_BREAK(pProcess, COMGETTER(PID)(&uPID));
|
---|
| 171 |
|
---|
[92372] | 172 | RTPrintf(GuestCtrlLsnr::tr("Process PID=%RU32 \"%s\" changed status to [%s]\n"),
|
---|
[55604] | 173 | uPID, Utf8Str(strPath).c_str(), gctlProcessStatusToText(procSts));
|
---|
[49181] | 174 |
|
---|
| 175 | } while (0);
|
---|
| 176 | break;
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | default:
|
---|
| 180 | AssertFailed();
|
---|
| 181 | }
|
---|
| 182 |
|
---|
| 183 | return S_OK;
|
---|
| 184 | }
|
---|
| 185 |
|
---|
[55604] | 186 |
|
---|
| 187 | /*
|
---|
| 188 | * GuestSessionEventListener
|
---|
| 189 | * GuestSessionEventListener
|
---|
| 190 | * GuestSessionEventListener
|
---|
| 191 | */
|
---|
| 192 |
|
---|
[49181] | 193 | GuestSessionEventListener::GuestSessionEventListener(void)
|
---|
| 194 | {
|
---|
| 195 | }
|
---|
| 196 |
|
---|
| 197 | GuestSessionEventListener::~GuestSessionEventListener(void)
|
---|
| 198 | {
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 | void GuestSessionEventListener::uninit(void)
|
---|
| 202 | {
|
---|
| 203 | GuestEventProcs::iterator itProc = mProcs.begin();
|
---|
| 204 | while (itProc != mProcs.end())
|
---|
| 205 | {
|
---|
| 206 | if (!itProc->first.isNull())
|
---|
| 207 | {
|
---|
[95140] | 208 | HRESULT hrc;
|
---|
[49181] | 209 | do
|
---|
| 210 | {
|
---|
| 211 | /* Listener unregistration. */
|
---|
| 212 | ComPtr<IEventSource> pES;
|
---|
| 213 | CHECK_ERROR_BREAK(itProc->first, COMGETTER(EventSource)(pES.asOutParam()));
|
---|
| 214 | if (!pES.isNull())
|
---|
| 215 | CHECK_ERROR_BREAK(pES, UnregisterListener(itProc->second.mListener));
|
---|
| 216 | } while (0);
|
---|
| 217 | }
|
---|
| 218 |
|
---|
[56030] | 219 | ++itProc;
|
---|
[49181] | 220 | }
|
---|
| 221 | mProcs.clear();
|
---|
| 222 |
|
---|
| 223 | GuestEventFiles::iterator itFile = mFiles.begin();
|
---|
| 224 | while (itFile != mFiles.end())
|
---|
| 225 | {
|
---|
| 226 | if (!itFile->first.isNull())
|
---|
| 227 | {
|
---|
[95140] | 228 | HRESULT hrc;
|
---|
[49181] | 229 | do
|
---|
| 230 | {
|
---|
| 231 | /* Listener unregistration. */
|
---|
| 232 | ComPtr<IEventSource> pES;
|
---|
| 233 | CHECK_ERROR_BREAK(itFile->first, COMGETTER(EventSource)(pES.asOutParam()));
|
---|
| 234 | if (!pES.isNull())
|
---|
| 235 | CHECK_ERROR_BREAK(pES, UnregisterListener(itFile->second.mListener));
|
---|
| 236 | } while (0);
|
---|
| 237 | }
|
---|
| 238 |
|
---|
[56030] | 239 | ++itFile;
|
---|
[49181] | 240 | }
|
---|
| 241 | mFiles.clear();
|
---|
| 242 | }
|
---|
| 243 |
|
---|
| 244 | STDMETHODIMP GuestSessionEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
|
---|
| 245 | {
|
---|
| 246 | switch (aType)
|
---|
| 247 | {
|
---|
| 248 | case VBoxEventType_OnGuestFileRegistered:
|
---|
| 249 | {
|
---|
[95140] | 250 | HRESULT hrc;
|
---|
[49181] | 251 | do
|
---|
| 252 | {
|
---|
| 253 | ComPtr<IGuestFileRegisteredEvent> pEvent = aEvent;
|
---|
| 254 | Assert(!pEvent.isNull());
|
---|
| 255 |
|
---|
| 256 | ComPtr<IGuestFile> pFile;
|
---|
| 257 | CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pFile.asOutParam()));
|
---|
| 258 | AssertBreak(!pFile.isNull());
|
---|
| 259 | BOOL fRegistered;
|
---|
| 260 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
|
---|
| 261 | Bstr strPath;
|
---|
[75926] | 262 | CHECK_ERROR_BREAK(pFile, COMGETTER(Filename)(strPath.asOutParam()));
|
---|
[49181] | 263 |
|
---|
[92372] | 264 | RTPrintf(GuestCtrlLsnr::tr("File \"%s\" %s\n"),
|
---|
[49181] | 265 | Utf8Str(strPath).c_str(),
|
---|
[92372] | 266 | fRegistered ? GuestCtrlLsnr::tr("registered") : GuestCtrlLsnr::tr("unregistered"));
|
---|
[49181] | 267 | if (fRegistered)
|
---|
| 268 | {
|
---|
| 269 | if (mfVerbose)
|
---|
[92372] | 270 | RTPrintf(GuestCtrlLsnr::tr("Registering ...\n"));
|
---|
[49181] | 271 |
|
---|
| 272 | /* Register for IGuestFile events. */
|
---|
| 273 | ComObjPtr<GuestFileEventListenerImpl> pListener;
|
---|
| 274 | pListener.createObject();
|
---|
| 275 | CHECK_ERROR_BREAK(pListener, init(new GuestFileEventListener()));
|
---|
| 276 |
|
---|
| 277 | ComPtr<IEventSource> es;
|
---|
| 278 | CHECK_ERROR_BREAK(pFile, COMGETTER(EventSource)(es.asOutParam()));
|
---|
| 279 | com::SafeArray<VBoxEventType_T> eventTypes;
|
---|
| 280 | eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);
|
---|
| 281 | CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
|
---|
| 282 | true /* Active listener */));
|
---|
| 283 |
|
---|
| 284 | GuestFileStats fileStats(pListener);
|
---|
| 285 | mFiles[pFile] = fileStats;
|
---|
| 286 | }
|
---|
| 287 | else
|
---|
| 288 | {
|
---|
| 289 | GuestEventFiles::iterator itFile = mFiles.find(pFile);
|
---|
| 290 | if (itFile != mFiles.end())
|
---|
| 291 | {
|
---|
| 292 | if (mfVerbose)
|
---|
[92372] | 293 | RTPrintf(GuestCtrlLsnr::tr("Unregistering file ...\n"));
|
---|
[49181] | 294 |
|
---|
| 295 | if (!itFile->first.isNull())
|
---|
| 296 | {
|
---|
| 297 | /* Listener unregistration. */
|
---|
| 298 | ComPtr<IEventSource> pES;
|
---|
| 299 | CHECK_ERROR(itFile->first, COMGETTER(EventSource)(pES.asOutParam()));
|
---|
| 300 | if (!pES.isNull())
|
---|
| 301 | CHECK_ERROR(pES, UnregisterListener(itFile->second.mListener));
|
---|
| 302 | }
|
---|
| 303 |
|
---|
| 304 | mFiles.erase(itFile);
|
---|
| 305 | }
|
---|
| 306 | }
|
---|
| 307 |
|
---|
| 308 | } while (0);
|
---|
| 309 | break;
|
---|
| 310 | }
|
---|
| 311 |
|
---|
| 312 | case VBoxEventType_OnGuestProcessRegistered:
|
---|
| 313 | {
|
---|
[95140] | 314 | HRESULT hrc;
|
---|
[49181] | 315 | do
|
---|
| 316 | {
|
---|
| 317 | ComPtr<IGuestProcessRegisteredEvent> pEvent = aEvent;
|
---|
| 318 | Assert(!pEvent.isNull());
|
---|
| 319 |
|
---|
| 320 | ComPtr<IGuestProcess> pProcess;
|
---|
| 321 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam()));
|
---|
| 322 | AssertBreak(!pProcess.isNull());
|
---|
| 323 | BOOL fRegistered;
|
---|
| 324 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
|
---|
| 325 | Bstr strPath;
|
---|
| 326 | CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam()));
|
---|
| 327 |
|
---|
[92372] | 328 | RTPrintf(GuestCtrlLsnr::tr("Process \"%s\" %s\n"),
|
---|
[49181] | 329 | Utf8Str(strPath).c_str(),
|
---|
[92372] | 330 | fRegistered ? GuestCtrlLsnr::tr("registered") : GuestCtrlLsnr::tr("unregistered"));
|
---|
[49181] | 331 | if (fRegistered)
|
---|
| 332 | {
|
---|
| 333 | if (mfVerbose)
|
---|
[92372] | 334 | RTPrintf(GuestCtrlLsnr::tr("Registering ...\n"));
|
---|
[49181] | 335 |
|
---|
| 336 | /* Register for IGuestProcess events. */
|
---|
| 337 | ComObjPtr<GuestProcessEventListenerImpl> pListener;
|
---|
| 338 | pListener.createObject();
|
---|
| 339 | CHECK_ERROR_BREAK(pListener, init(new GuestProcessEventListener()));
|
---|
| 340 |
|
---|
| 341 | ComPtr<IEventSource> es;
|
---|
| 342 | CHECK_ERROR_BREAK(pProcess, COMGETTER(EventSource)(es.asOutParam()));
|
---|
| 343 | com::SafeArray<VBoxEventType_T> eventTypes;
|
---|
| 344 | eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged);
|
---|
| 345 | CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
|
---|
| 346 | true /* Active listener */));
|
---|
| 347 |
|
---|
| 348 | GuestProcStats procStats(pListener);
|
---|
| 349 | mProcs[pProcess] = procStats;
|
---|
| 350 | }
|
---|
| 351 | else
|
---|
| 352 | {
|
---|
| 353 | GuestEventProcs::iterator itProc = mProcs.find(pProcess);
|
---|
| 354 | if (itProc != mProcs.end())
|
---|
| 355 | {
|
---|
| 356 | if (mfVerbose)
|
---|
[92372] | 357 | RTPrintf(GuestCtrlLsnr::tr("Unregistering process ...\n"));
|
---|
[49181] | 358 |
|
---|
| 359 | if (!itProc->first.isNull())
|
---|
| 360 | {
|
---|
| 361 | /* Listener unregistration. */
|
---|
| 362 | ComPtr<IEventSource> pES;
|
---|
| 363 | CHECK_ERROR(itProc->first, COMGETTER(EventSource)(pES.asOutParam()));
|
---|
| 364 | if (!pES.isNull())
|
---|
| 365 | CHECK_ERROR(pES, UnregisterListener(itProc->second.mListener));
|
---|
| 366 | }
|
---|
| 367 |
|
---|
| 368 | mProcs.erase(itProc);
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 |
|
---|
| 372 | } while (0);
|
---|
| 373 | break;
|
---|
| 374 | }
|
---|
| 375 |
|
---|
| 376 | case VBoxEventType_OnGuestSessionStateChanged:
|
---|
| 377 | {
|
---|
[95140] | 378 | HRESULT hrc;
|
---|
[49181] | 379 | do
|
---|
| 380 | {
|
---|
| 381 | ComPtr<IGuestSessionStateChangedEvent> pEvent = aEvent;
|
---|
| 382 | Assert(!pEvent.isNull());
|
---|
| 383 | ComPtr<IGuestSession> pSession;
|
---|
| 384 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam()));
|
---|
| 385 | AssertBreak(!pSession.isNull());
|
---|
| 386 |
|
---|
| 387 | GuestSessionStatus_T sessSts;
|
---|
| 388 | CHECK_ERROR_BREAK(pSession, COMGETTER(Status)(&sessSts));
|
---|
| 389 | ULONG uID;
|
---|
| 390 | CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
|
---|
| 391 | Bstr strName;
|
---|
| 392 | CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));
|
---|
| 393 |
|
---|
[92372] | 394 | RTPrintf(GuestCtrlLsnr::tr("Session ID=%RU32 \"%s\" changed status to [%s]\n"),
|
---|
[55604] | 395 | uID, Utf8Str(strName).c_str(), gctlGuestSessionStatusToText(sessSts));
|
---|
[49181] | 396 |
|
---|
| 397 | } while (0);
|
---|
| 398 | break;
|
---|
| 399 | }
|
---|
| 400 |
|
---|
| 401 | default:
|
---|
| 402 | AssertFailed();
|
---|
| 403 | }
|
---|
| 404 |
|
---|
| 405 | return S_OK;
|
---|
| 406 | }
|
---|
| 407 |
|
---|
[55604] | 408 |
|
---|
| 409 | /*
|
---|
| 410 | * GuestEventListener
|
---|
| 411 | * GuestEventListener
|
---|
| 412 | * GuestEventListener
|
---|
| 413 | */
|
---|
| 414 |
|
---|
[49181] | 415 | GuestEventListener::GuestEventListener(void)
|
---|
| 416 | {
|
---|
| 417 | }
|
---|
| 418 |
|
---|
| 419 | GuestEventListener::~GuestEventListener(void)
|
---|
| 420 | {
|
---|
| 421 | }
|
---|
| 422 |
|
---|
| 423 | void GuestEventListener::uninit(void)
|
---|
| 424 | {
|
---|
| 425 | GuestEventSessions::iterator itSession = mSessions.begin();
|
---|
| 426 | while (itSession != mSessions.end())
|
---|
| 427 | {
|
---|
| 428 | if (!itSession->first.isNull())
|
---|
| 429 | {
|
---|
[95140] | 430 | HRESULT hrc;
|
---|
[49181] | 431 | do
|
---|
| 432 | {
|
---|
| 433 | /* Listener unregistration. */
|
---|
| 434 | ComPtr<IEventSource> pES;
|
---|
| 435 | CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam()));
|
---|
| 436 | if (!pES.isNull())
|
---|
| 437 | CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener));
|
---|
| 438 |
|
---|
| 439 | } while (0);
|
---|
| 440 | }
|
---|
| 441 |
|
---|
[56030] | 442 | ++itSession;
|
---|
[49181] | 443 | }
|
---|
| 444 | mSessions.clear();
|
---|
| 445 | }
|
---|
| 446 |
|
---|
| 447 | STDMETHODIMP GuestEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
|
---|
| 448 | {
|
---|
| 449 | switch (aType)
|
---|
| 450 | {
|
---|
| 451 | case VBoxEventType_OnGuestSessionRegistered:
|
---|
| 452 | {
|
---|
[95140] | 453 | HRESULT hrc;
|
---|
[49181] | 454 | do
|
---|
| 455 | {
|
---|
| 456 | ComPtr<IGuestSessionRegisteredEvent> pEvent = aEvent;
|
---|
| 457 | Assert(!pEvent.isNull());
|
---|
| 458 |
|
---|
| 459 | ComPtr<IGuestSession> pSession;
|
---|
| 460 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam()));
|
---|
| 461 | AssertBreak(!pSession.isNull());
|
---|
| 462 | BOOL fRegistered;
|
---|
| 463 | CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
|
---|
| 464 | Bstr strName;
|
---|
| 465 | CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));
|
---|
| 466 | ULONG uID;
|
---|
| 467 | CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
|
---|
| 468 |
|
---|
[92372] | 469 | RTPrintf(GuestCtrlLsnr::tr("Session ID=%RU32 \"%s\" %s\n"),
|
---|
[49181] | 470 | uID, Utf8Str(strName).c_str(),
|
---|
[92372] | 471 | fRegistered ? GuestCtrlLsnr::tr("registered") : GuestCtrlLsnr::tr("unregistered"));
|
---|
[49181] | 472 | if (fRegistered)
|
---|
| 473 | {
|
---|
| 474 | if (mfVerbose)
|
---|
[92372] | 475 | RTPrintf(GuestCtrlLsnr::tr("Registering ...\n"));
|
---|
[49181] | 476 |
|
---|
| 477 | /* Register for IGuestSession events. */
|
---|
| 478 | ComObjPtr<GuestSessionEventListenerImpl> pListener;
|
---|
| 479 | pListener.createObject();
|
---|
| 480 | CHECK_ERROR_BREAK(pListener, init(new GuestSessionEventListener()));
|
---|
| 481 |
|
---|
| 482 | ComPtr<IEventSource> es;
|
---|
| 483 | CHECK_ERROR_BREAK(pSession, COMGETTER(EventSource)(es.asOutParam()));
|
---|
| 484 | com::SafeArray<VBoxEventType_T> eventTypes;
|
---|
| 485 | eventTypes.push_back(VBoxEventType_OnGuestFileRegistered);
|
---|
| 486 | eventTypes.push_back(VBoxEventType_OnGuestProcessRegistered);
|
---|
[92865] | 487 | eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged);
|
---|
[49181] | 488 | CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
|
---|
| 489 | true /* Active listener */));
|
---|
| 490 |
|
---|
| 491 | GuestSessionStats sessionStats(pListener);
|
---|
| 492 | mSessions[pSession] = sessionStats;
|
---|
| 493 | }
|
---|
| 494 | else
|
---|
| 495 | {
|
---|
| 496 | GuestEventSessions::iterator itSession = mSessions.find(pSession);
|
---|
| 497 | if (itSession != mSessions.end())
|
---|
| 498 | {
|
---|
| 499 | if (mfVerbose)
|
---|
[92372] | 500 | RTPrintf(GuestCtrlLsnr::tr("Unregistering ...\n"));
|
---|
[49181] | 501 |
|
---|
| 502 | if (!itSession->first.isNull())
|
---|
| 503 | {
|
---|
| 504 | /* Listener unregistration. */
|
---|
| 505 | ComPtr<IEventSource> pES;
|
---|
| 506 | CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam()));
|
---|
| 507 | if (!pES.isNull())
|
---|
| 508 | CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener));
|
---|
| 509 | }
|
---|
| 510 |
|
---|
| 511 | mSessions.erase(itSession);
|
---|
| 512 | }
|
---|
| 513 | }
|
---|
| 514 |
|
---|
| 515 | } while (0);
|
---|
| 516 | break;
|
---|
| 517 | }
|
---|
| 518 |
|
---|
| 519 | default:
|
---|
| 520 | AssertFailed();
|
---|
| 521 | }
|
---|
| 522 |
|
---|
| 523 | return S_OK;
|
---|
| 524 | }
|
---|
[55604] | 525 |
|
---|
[84519] | 526 | /*
|
---|
| 527 | * GuestAdditionsRunlevelListener
|
---|
| 528 | * GuestAdditionsRunlevelListener
|
---|
| 529 | * GuestAdditionsRunlevelListener
|
---|
| 530 | */
|
---|
| 531 |
|
---|
| 532 | GuestAdditionsRunlevelListener::GuestAdditionsRunlevelListener(AdditionsRunLevelType_T enmRunLevel)
|
---|
| 533 | : mRunLevelTarget(enmRunLevel)
|
---|
| 534 | {
|
---|
| 535 | }
|
---|
| 536 |
|
---|
| 537 | GuestAdditionsRunlevelListener::~GuestAdditionsRunlevelListener(void)
|
---|
| 538 | {
|
---|
| 539 | }
|
---|
| 540 |
|
---|
| 541 | void GuestAdditionsRunlevelListener::uninit(void)
|
---|
| 542 | {
|
---|
| 543 | }
|
---|
| 544 |
|
---|
| 545 | STDMETHODIMP GuestAdditionsRunlevelListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
|
---|
| 546 | {
|
---|
| 547 | Assert(mRunLevelTarget != AdditionsRunLevelType_None);
|
---|
| 548 |
|
---|
[95140] | 549 | HRESULT hrc;
|
---|
[84519] | 550 |
|
---|
| 551 | switch (aType)
|
---|
| 552 | {
|
---|
| 553 | case VBoxEventType_OnGuestAdditionsStatusChanged:
|
---|
| 554 | {
|
---|
| 555 | ComPtr<IGuestAdditionsStatusChangedEvent> pEvent = aEvent;
|
---|
| 556 | Assert(!pEvent.isNull());
|
---|
| 557 |
|
---|
| 558 | AdditionsRunLevelType_T RunLevelCur = AdditionsRunLevelType_None;
|
---|
| 559 | CHECK_ERROR_BREAK(pEvent, COMGETTER(RunLevel)(&RunLevelCur));
|
---|
| 560 |
|
---|
| 561 | if (mfVerbose)
|
---|
[92372] | 562 | RTPrintf(GuestCtrlLsnr::tr("Reached run level %RU32\n"), RunLevelCur);
|
---|
[84519] | 563 |
|
---|
| 564 | if (RunLevelCur == mRunLevelTarget)
|
---|
| 565 | {
|
---|
| 566 | int vrc = RTSemEventSignal(g_SemEventGuestCtrlCanceled);
|
---|
| 567 | AssertRC(vrc);
|
---|
| 568 | }
|
---|
| 569 |
|
---|
| 570 | break;
|
---|
| 571 | }
|
---|
| 572 |
|
---|
| 573 | default:
|
---|
| 574 | AssertFailed();
|
---|
| 575 | }
|
---|
| 576 |
|
---|
| 577 | return S_OK;
|
---|
| 578 | }
|
---|