VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstAPI.cpp@ 105016

Last change on this file since 105016 was 104780, checked in by vboxsync, 4 months ago

Main: Added new API IPlatformProperties::getSupportedVRAMRange() to return the VRAM range of a given graphics controller. bugref:​10693

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 64.0 KB
Line 
1/* $Id: tstAPI.cpp 104780 2024-05-24 14:15:44Z vboxsync $ */
2/** @file
3 * tstAPI - test program for our COM/XPCOM interface
4 */
5
6/*
7 * Copyright (C) 2006-2023 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#include <stdio.h>
29#include <stdlib.h>
30
31#include <VBox/com/com.h>
32#include <VBox/com/string.h>
33#include <VBox/com/Guid.h>
34#include <VBox/com/ErrorInfo.h>
35#include <VBox/com/errorprint.h>
36
37#include <VBox/com/VirtualBox.h>
38
39using namespace com;
40
41#define LOG_ENABLED
42#define LOG_GROUP LOG_GROUP_MAIN
43#include <VBox/log.h>
44
45#include <iprt/initterm.h>
46#include <iprt/path.h>
47#include <iprt/param.h>
48#include <iprt/stream.h>
49#include <iprt/thread.h>
50
51
52// forward declarations
53///////////////////////////////////////////////////////////////////////////////
54
55#ifdef VBOX_WITH_RESOURCE_USAGE_API
56static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox, ComPtr<IUnknown> aObject);
57static void queryMetrics(ComPtr<IVirtualBox> aVirtualBox,
58 ComPtr<IPerformanceCollector> collector,
59 ComSafeArrayIn(IUnknown *, objects));
60static void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
61 ComSafeArrayIn(IPerformanceMetric*, aMetrics));
62#endif
63
64// funcs
65///////////////////////////////////////////////////////////////////////////////
66
67#if 0 /* unused */
68static HRESULT readAndChangeMachineSettings(IMachine *machine, IMachine *readonlyMachine = 0)
69{
70 HRESULT hrc = S_OK;
71
72 Bstr name;
73 RTPrintf("Getting machine name...\n");
74 CHECK_ERROR_RET(machine, COMGETTER(Name)(name.asOutParam()), hrc);
75 RTPrintf("Name: {%ls}\n", name.raw());
76
77 RTPrintf("Getting machine GUID...\n");
78 Bstr guid;
79 CHECK_ERROR(machine, COMGETTER(Id)(guid.asOutParam()));
80 if (SUCCEEDED(hrc) && !guid.isEmpty()) {
81 RTPrintf("Guid::toString(): {%s}\n", Utf8Str(guid).c_str());
82 } else {
83 RTPrintf("WARNING: there's no GUID!");
84 }
85
86 ULONG memorySize;
87 RTPrintf("Getting memory size...\n");
88 CHECK_ERROR_RET(machine, COMGETTER(MemorySize)(&memorySize), hrc);
89 RTPrintf("Memory size: %d\n", memorySize);
90
91 MachineState_T machineState;
92 RTPrintf("Getting machine state...\n");
93 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), hrc);
94 RTPrintf("Machine state: %d\n", machineState);
95
96 BOOL modified;
97 RTPrintf("Are any settings modified?...\n");
98 CHECK_ERROR(machine, COMGETTER(SettingsModified)(&modified));
99 if (SUCCEEDED(hrc))
100 RTPrintf("%s\n", modified ? "yes" : "no");
101
102 ULONG memorySizeBig = memorySize * 10;
103 RTPrintf("Changing memory size to %d...\n", memorySizeBig);
104 CHECK_ERROR(machine, COMSETTER(MemorySize)(memorySizeBig));
105
106 if (SUCCEEDED(hrc))
107 {
108 RTPrintf("Are any settings modified now?...\n");
109 CHECK_ERROR_RET(machine, COMGETTER(SettingsModified)(&modified), hrc);
110 RTPrintf("%s\n", modified ? "yes" : "no");
111 ASSERT_RET(modified, 0);
112
113 ULONG memorySizeGot;
114 RTPrintf("Getting memory size again...\n");
115 CHECK_ERROR_RET(machine, COMGETTER(MemorySize)(&memorySizeGot), hrc);
116 RTPrintf("Memory size: %d\n", memorySizeGot);
117 ASSERT_RET(memorySizeGot == memorySizeBig, 0);
118
119 if (readonlyMachine)
120 {
121 RTPrintf("Getting memory size of the counterpart readonly machine...\n");
122 ULONG memorySizeRO;
123 readonlyMachine->COMGETTER(MemorySize)(&memorySizeRO);
124 RTPrintf("Memory size: %d\n", memorySizeRO);
125 ASSERT_RET(memorySizeRO != memorySizeGot, 0);
126 }
127
128 RTPrintf("Discarding recent changes...\n");
129 CHECK_ERROR_RET(machine, DiscardSettings(), hrc);
130 RTPrintf("Are any settings modified after discarding?...\n");
131 CHECK_ERROR_RET(machine, COMGETTER(SettingsModified)(&modified), hrc);
132 RTPrintf("%s\n", modified ? "yes" : "no");
133 ASSERT_RET(!modified, 0);
134
135 RTPrintf("Getting memory size once more...\n");
136 CHECK_ERROR_RET(machine, COMGETTER(MemorySize)(&memorySizeGot), hrc);
137 RTPrintf("Memory size: %d\n", memorySizeGot);
138 ASSERT_RET(memorySizeGot == memorySize, 0);
139
140 memorySize = memorySize > 128 ? memorySize / 2 : memorySize * 2;
141 RTPrintf("Changing memory size to %d...\n", memorySize);
142 CHECK_ERROR_RET(machine, COMSETTER(MemorySize)(memorySize), hrc);
143 }
144
145 Bstr desc;
146 RTPrintf("Getting description...\n");
147 CHECK_ERROR_RET(machine, COMGETTER(Description)(desc.asOutParam()), hrc);
148 RTPrintf("Description is: \"%ls\"\n", desc.raw());
149
150 desc = L"This is an exemplary description (changed).";
151 RTPrintf("Setting description to \"%ls\"...\n", desc.raw());
152 CHECK_ERROR_RET(machine, COMSETTER(Description)(desc.raw()), hrc);
153
154 RTPrintf("Saving machine settings...\n");
155 CHECK_ERROR(machine, SaveSettings());
156 if (SUCCEEDED(hrc))
157 {
158 RTPrintf("Are any settings modified after saving?...\n");
159 CHECK_ERROR_RET(machine, COMGETTER(SettingsModified)(&modified), hrc);
160 RTPrintf("%s\n", modified ? "yes" : "no");
161 ASSERT_RET(!modified, 0);
162
163 if (readonlyMachine) {
164 RTPrintf("Getting memory size of the counterpart readonly machine...\n");
165 ULONG memorySizeRO;
166 readonlyMachine->COMGETTER(MemorySize)(&memorySizeRO);
167 RTPrintf("Memory size: %d\n", memorySizeRO);
168 ASSERT_RET(memorySizeRO == memorySize, 0);
169 }
170 }
171
172 Bstr extraDataKey = L"Blafasel";
173 Bstr extraData;
174 RTPrintf("Getting extra data key {%ls}...\n", extraDataKey.raw());
175 CHECK_ERROR_RET(machine, GetExtraData(extraDataKey.raw(), extraData.asOutParam()), hrc);
176 if (!extraData.isEmpty()) {
177 RTPrintf("Extra data value: {%ls}\n", extraData.raw());
178 } else {
179 RTPrintf("No extra data exists\n");
180 }
181
182 if (extraData.isEmpty())
183 extraData = L"Das ist die Berliner Luft, Luft, Luft...";
184 else
185 extraData.setNull();
186 RTPrintf("Setting extra data key {%ls} to {%ls}...\n",
187 extraDataKey.raw(), extraData.raw());
188 CHECK_ERROR(machine, SetExtraData(extraDataKey.raw(), extraData.raw()));
189
190 if (SUCCEEDED(hrc)) {
191 RTPrintf("Getting extra data key {%ls} again...\n", extraDataKey.raw());
192 CHECK_ERROR_RET(machine, GetExtraData(extraDataKey.raw(), extraData.asOutParam()), hrc);
193 if (!extraData.isEmpty()) {
194 RTPrintf("Extra data value: {%ls}\n", extraData.raw());
195 } else {
196 RTPrintf("No extra data exists\n");
197 }
198 }
199
200 return hrc;
201}
202#endif
203
204// main
205///////////////////////////////////////////////////////////////////////////////
206
207int main(int argc, char *argv[])
208{
209 /*
210 * Initialize the VBox runtime without loading
211 * the support driver.
212 */
213 RTR3InitExe(argc, &argv, 0);
214
215 HRESULT hrc;
216
217 {
218 char homeDir[RTPATH_MAX];
219 GetVBoxUserHomeDirectory(homeDir, sizeof(homeDir));
220 RTPrintf("VirtualBox Home Directory = '%s'\n", homeDir);
221 }
222
223 RTPrintf("Initializing COM...\n");
224
225 hrc = com::Initialize();
226 if (FAILED(hrc))
227 {
228 RTPrintf("ERROR: failed to initialize COM!\n");
229 return hrc;
230 }
231
232 do
233 {
234 // scopes all the stuff till shutdown
235 ////////////////////////////////////////////////////////////////////////////
236
237 ComPtr<IVirtualBoxClient> virtualBoxClient;
238 ComPtr<IVirtualBox> virtualBox;
239 ComPtr<ISession> session;
240
241#if 0
242 // Utf8Str test
243 ////////////////////////////////////////////////////////////////////////////
244
245 Utf8Str nullUtf8Str;
246 RTPrintf("nullUtf8Str='%s'\n", nullUtf8Str.raw());
247
248 Utf8Str simpleUtf8Str = "simpleUtf8Str";
249 RTPrintf("simpleUtf8Str='%s'\n", simpleUtf8Str.raw());
250
251 Utf8Str utf8StrFmt = Utf8StrFmt("[0=%d]%s[1=%d]", 0, "utf8StrFmt", 1);
252 RTPrintf("utf8StrFmt='%s'\n", utf8StrFmt.raw());
253
254#endif
255
256 RTPrintf("Creating VirtualBox object...\n");
257 hrc = virtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
258 if (SUCCEEDED(hrc))
259 hrc = virtualBoxClient->COMGETTER(VirtualBox)(virtualBox.asOutParam());
260 if (FAILED(hrc))
261 RTPrintf("ERROR: failed to create the VirtualBox object!\n");
262 else
263 {
264 hrc = session.createInprocObject(CLSID_Session);
265 if (FAILED(hrc))
266 RTPrintf("ERROR: failed to create a session object!\n");
267 }
268
269 if (FAILED(hrc))
270 {
271 com::ErrorInfo info;
272 if (!info.isFullAvailable() && !info.isBasicAvailable())
273 {
274 com::GluePrintRCMessage(hrc);
275 RTPrintf("Most likely, the VirtualBox COM server is not running or failed to start.\n");
276 }
277 else
278 com::GluePrintErrorInfo(info);
279 break;
280 }
281
282#if 0
283 // Testing VirtualBox::COMGETTER(ProgressOperations).
284 // This is designed to be tested while running
285 // "./VBoxManage clonehd src.vdi clone.vdi" in parallel.
286 // It will then display the progress every 2 seconds.
287 ////////////////////////////////////////////////////////////////////////////
288 {
289 RTPrintf("Testing VirtualBox::COMGETTER(ProgressOperations)...\n");
290
291 for (;;) {
292 com::SafeIfaceArray<IProgress> operations;
293
294 CHECK_ERROR_BREAK(virtualBox,
295 COMGETTER(ProgressOperations)(ComSafeArrayAsOutParam(operations)));
296
297 RTPrintf("operations: %d\n", operations.size());
298 if (operations.size() == 0)
299 break; // No more operations left.
300
301 for (size_t i = 0; i < operations.size(); ++i) {
302 PRInt32 percent;
303
304 operations[i]->COMGETTER(Percent)(&percent);
305 RTPrintf("operations[%u]: %ld\n", (unsigned)i, (long)percent);
306 }
307 RTThreadSleep(2000); // msec
308 }
309 }
310#endif
311
312#if 0
313 // IUnknown identity test
314 ////////////////////////////////////////////////////////////////////////////
315 {
316 {
317 ComPtr<IVirtualBox> virtualBox2;
318
319 RTPrintf("Creating one more VirtualBox object...\n");
320 CHECK_RC(virtualBoxClient->COMGETTER(virtualBox2.asOutParam()));
321 if (FAILED(rc))
322 {
323 CHECK_ERROR_NOCALL();
324 break;
325 }
326
327 RTPrintf("IVirtualBox(virtualBox)=%p IVirtualBox(virtualBox2)=%p\n",
328 (IVirtualBox *)virtualBox, (IVirtualBox *)virtualBox2);
329 Assert((IVirtualBox *)virtualBox == (IVirtualBox *)virtualBox2);
330
331 ComPtr<IUnknown> unk(virtualBox);
332 ComPtr<IUnknown> unk2;
333 unk2 = virtualBox2;
334
335 RTPrintf("IUnknown(virtualBox)=%p IUnknown(virtualBox2)=%p\n",
336 (IUnknown *)unk, (IUnknown *)unk2);
337 Assert((IUnknown *)unk == (IUnknown *)unk2);
338
339 ComPtr<IVirtualBox> vb = unk;
340 ComPtr<IVirtualBox> vb2 = unk;
341
342 RTPrintf("IVirtualBox(IUnknown(virtualBox))=%p IVirtualBox(IUnknown(virtualBox2))=%p\n",
343 (IVirtualBox *)vb, (IVirtualBox *)vb2);
344 Assert((IVirtualBox *)vb == (IVirtualBox *)vb2);
345 }
346
347 {
348 ComPtr<IHost> host;
349 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
350 RTPrintf(" IHost(host)=%p\n", (IHost *)host);
351 ComPtr<IUnknown> unk = host;
352 RTPrintf(" IUnknown(host)=%p\n", (IUnknown *)unk);
353 ComPtr<IHost> host_copy = unk;
354 RTPrintf(" IHost(host_copy)=%p\n", (IHost *)host_copy);
355 ComPtr<IUnknown> unk_copy = host_copy;
356 RTPrintf(" IUnknown(host_copy)=%p\n", (IUnknown *)unk_copy);
357 Assert((IUnknown *)unk == (IUnknown *)unk_copy);
358
359 /* query IUnknown on IUnknown */
360 ComPtr<IUnknown> unk_copy_copy;
361 unk_copy.queryInterfaceTo(unk_copy_copy.asOutParam());
362 RTPrintf(" IUnknown(unk_copy)=%p\n", (IUnknown *)unk_copy_copy);
363 Assert((IUnknown *)unk_copy == (IUnknown *)unk_copy_copy);
364 /* query IUnknown on IUnknown in the opposite direction */
365 unk_copy_copy.queryInterfaceTo(unk_copy.asOutParam());
366 RTPrintf(" IUnknown(unk_copy_copy)=%p\n", (IUnknown *)unk_copy);
367 Assert((IUnknown *)unk_copy == (IUnknown *)unk_copy_copy);
368
369 /* query IUnknown again after releasing all previous IUnknown instances
370 * but keeping IHost -- it should remain the same (Identity Rule) */
371 IUnknown *oldUnk = unk;
372 unk.setNull();
373 unk_copy.setNull();
374 unk_copy_copy.setNull();
375 unk = host;
376 RTPrintf(" IUnknown(host)=%p\n", (IUnknown *)unk);
377 Assert(oldUnk == (IUnknown *)unk);
378 }
379
380// RTPrintf("Will be now released (press Enter)...");
381// getchar();
382 }
383#endif
384
385#if 0
386 // the simplest COM API test
387 ////////////////////////////////////////////////////////////////////////////
388 {
389 Bstr version;
390 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Version)(version.asOutParam()));
391 RTPrintf("VirtualBox version = %ls\n", version.raw());
392 }
393#endif
394
395#if 0
396 // Array test
397 ////////////////////////////////////////////////////////////////////////////
398 {
399 RTPrintf("Calling IVirtualBox::Machines...\n");
400
401 com::SafeIfaceArray<IMachine> machines;
402 CHECK_ERROR_BREAK(virtualBox,
403 COMGETTER(Machines)(ComSafeArrayAsOutParam(machines)));
404
405 RTPrintf("%u machines registered (machines.isNull()=%d).\n",
406 machines.size(), machines.isNull());
407
408 for (size_t i = 0; i < machines.size(); ++ i)
409 {
410 Bstr name;
411 CHECK_ERROR_BREAK(machines[i], COMGETTER(Name)(name.asOutParam()));
412 RTPrintf("machines[%u]='%s'\n", i, Utf8Str(name).raw());
413 }
414
415#if 0
416 {
417 RTPrintf("Testing [out] arrays...\n");
418 com::SafeGUIDArray uuids;
419 CHECK_ERROR_BREAK(virtualBox,
420 COMGETTER(Uuids)(ComSafeArrayAsOutParam(uuids)));
421
422 for (size_t i = 0; i < uuids.size(); ++ i)
423 RTPrintf("uuids[%u]=%RTuuid\n", i, &uuids[i]);
424 }
425
426 {
427 RTPrintf("Testing [in] arrays...\n");
428 com::SafeGUIDArray uuids(5);
429 for (size_t i = 0; i < uuids.size(); ++ i)
430 {
431 Guid id;
432 id.create();
433 uuids[i] = id;
434 RTPrintf("uuids[%u]=%RTuuid\n", i, &uuids[i]);
435 }
436
437 CHECK_ERROR_BREAK(virtualBox,
438 SetUuids(ComSafeArrayAsInParam(uuids)));
439 }
440#endif
441
442 }
443#endif
444
445#if 0
446 // some outdated stuff
447 ////////////////////////////////////////////////////////////////////////////
448
449 RTPrintf("Getting IHost interface...\n");
450 IHost *host;
451 rc = virtualBox->GetHost(&host);
452 if (SUCCEEDED(rc))
453 {
454 IHostDVDDriveCollection *dvdColl;
455 rc = host->GetHostDVDDrives(&dvdColl);
456 if (SUCCEEDED(rc))
457 {
458 IHostDVDDrive *dvdDrive = NULL;
459 dvdColl->GetNextHostDVDDrive(dvdDrive, &dvdDrive);
460 while (dvdDrive)
461 {
462 BSTR driveName;
463 char *driveNameUtf8;
464 dvdDrive->GetDriveName(&driveName);
465 RTUtf16ToUtf8((PCRTUTF16)driveName, &driveNameUtf8);
466 RTPrintf("Host DVD drive name: %s\n", driveNameUtf8);
467 RTStrFree(driveNameUtf8);
468 SysFreeString(driveName);
469 IHostDVDDrive *dvdDriveTemp = dvdDrive;
470 dvdColl->GetNextHostDVDDrive(dvdDriveTemp, &dvdDrive);
471 dvdDriveTemp->Release();
472 }
473 dvdColl->Release();
474 } else
475 {
476 RTPrintf("Could not get host DVD drive collection\n");
477 }
478
479 IHostFloppyDriveCollection *floppyColl;
480 rc = host->GetHostFloppyDrives(&floppyColl);
481 if (SUCCEEDED(rc))
482 {
483 IHostFloppyDrive *floppyDrive = NULL;
484 floppyColl->GetNextHostFloppyDrive(floppyDrive, &floppyDrive);
485 while (floppyDrive)
486 {
487 BSTR driveName;
488 char *driveNameUtf8;
489 floppyDrive->GetDriveName(&driveName);
490 RTUtf16ToUtf8((PCRTUTF16)driveName, &driveNameUtf8);
491 RTPrintf("Host floppy drive name: %s\n", driveNameUtf8);
492 RTStrFree(driveNameUtf8);
493 SysFreeString(driveName);
494 IHostFloppyDrive *floppyDriveTemp = floppyDrive;
495 floppyColl->GetNextHostFloppyDrive(floppyDriveTemp, &floppyDrive);
496 floppyDriveTemp->Release();
497 }
498 floppyColl->Release();
499 } else
500 {
501 RTPrintf("Could not get host floppy drive collection\n");
502 }
503 host->Release();
504 } else
505 {
506 RTPrintf("Call failed\n");
507 }
508 RTPrintf("\n");
509#endif
510
511#if 0
512 // IVirtualBoxErrorInfo test
513 ////////////////////////////////////////////////////////////////////////////
514 {
515 // RPC calls
516
517 // call a method that will definitely fail
518 Guid uuid;
519 ComPtr<IHardDisk> hardDisk;
520 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
521 RTPrintf("virtualBox->GetHardDisk(null-uuid)=%08X\n", rc);
522
523// {
524// com::ErrorInfo info(virtualBox);
525// PRINT_ERROR_INFO(info);
526// }
527
528 // call a method that will definitely succeed
529 Bstr version;
530 rc = virtualBox->COMGETTER(Version)(version.asOutParam());
531 RTPrintf("virtualBox->COMGETTER(Version)=%08X\n", rc);
532
533 {
534 com::ErrorInfo info(virtualBox);
535 PRINT_ERROR_INFO(info);
536 }
537
538 // Local calls
539
540 // call a method that will definitely fail
541 ComPtr<IMachine> machine;
542 rc = session->COMGETTER(Machine)(machine.asOutParam());
543 RTPrintf("session->COMGETTER(Machine)=%08X\n", rc);
544
545// {
546// com::ErrorInfo info(virtualBox);
547// PRINT_ERROR_INFO(info);
548// }
549
550 // call a method that will definitely succeed
551 SessionState_T state;
552 rc = session->COMGETTER(State)(&state);
553 RTPrintf("session->COMGETTER(State)=%08X\n", rc);
554
555 {
556 com::ErrorInfo info(virtualBox);
557 PRINT_ERROR_INFO(info);
558 }
559 }
560#endif
561
562#if 0
563 // register the existing hard disk image
564 ///////////////////////////////////////////////////////////////////////////
565 do
566 {
567 ComPtr<IHardDisk> hd;
568 Bstr src = L"E:\\develop\\innotek\\images\\NewHardDisk.vdi";
569 RTPrintf("Opening the existing hard disk '%ls'...\n", src.raw());
570 CHECK_ERROR_BREAK(virtualBox, OpenHardDisk(src, AccessMode_ReadWrite, hd.asOutParam()));
571 RTPrintf("Enter to continue...\n");
572 getchar();
573 RTPrintf("Registering the existing hard disk '%ls'...\n", src.raw());
574 CHECK_ERROR_BREAK(virtualBox, RegisterHardDisk(hd));
575 RTPrintf("Enter to continue...\n");
576 getchar();
577 }
578 while (FALSE);
579 RTPrintf("\n");
580#endif
581
582#if 0
583 // find and unregister the existing hard disk image
584 ///////////////////////////////////////////////////////////////////////////
585 do
586 {
587 ComPtr<IVirtualDiskImage> vdi;
588 Bstr src = L"CreatorTest.vdi";
589 RTPrintf("Unregistering the hard disk '%ls'...\n", src.raw());
590 CHECK_ERROR_BREAK(virtualBox, FindVirtualDiskImage(src, vdi.asOutParam()));
591 ComPtr<IHardDisk> hd = vdi;
592 Guid id;
593 CHECK_ERROR_BREAK(hd, COMGETTER(Id)(id.asOutParam()));
594 CHECK_ERROR_BREAK(virtualBox, UnregisterHardDisk(id, hd.asOutParam()));
595 }
596 while (FALSE);
597 RTPrintf("\n");
598#endif
599
600#if 0
601 // clone the registered hard disk
602 ///////////////////////////////////////////////////////////////////////////
603 do
604 {
605#if defined RT_OS_LINUX
606 Bstr src = L"/mnt/hugaida/common/develop/innotek/images/freedos-linux.vdi";
607#else
608 Bstr src = L"E:/develop/innotek/images/freedos.vdi";
609#endif
610 Bstr dst = L"./clone.vdi";
611 RTPrintf("Cloning '%ls' to '%ls'...\n", src.raw(), dst.raw());
612 ComPtr<IVirtualDiskImage> vdi;
613 CHECK_ERROR_BREAK(virtualBox, FindVirtualDiskImage(src, vdi.asOutParam()));
614 ComPtr<IHardDisk> hd = vdi;
615 ComPtr<IProgress> progress;
616 CHECK_ERROR_BREAK(hd, CloneToImage(dst, vdi.asOutParam(), progress.asOutParam()));
617 RTPrintf("Waiting for completion...\n");
618 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
619 ProgressErrorInfo ei(progress);
620 if (FAILED(ei.getResultCode()))
621 {
622 PRINT_ERROR_INFO(ei);
623 }
624 else
625 {
626 vdi->COMGETTER(FilePath)(dst.asOutParam());
627 RTPrintf("Actual clone path is '%ls'\n", dst.raw());
628 }
629 }
630 while (FALSE);
631 RTPrintf("\n");
632#endif
633
634#if 0
635 // find a registered hard disk by location and get properties
636 ///////////////////////////////////////////////////////////////////////////
637 do
638 {
639 ComPtr<IHardDisk> hd;
640 static const wchar_t *Names[] =
641 {
642#ifndef RT_OS_LINUX
643 L"freedos.vdi",
644 L"MS-DOS.vmdk",
645 L"iscsi",
646 L"some/path/and/disk.vdi",
647#else
648 L"xp.vdi",
649 L"Xp.vDI",
650#endif
651 };
652
653 RTPrintf("\n");
654
655 for (size_t i = 0; i < RT_ELEMENTS(Names); ++ i)
656 {
657 Bstr src = Names[i];
658 RTPrintf("Searching for hard disk '%ls'...\n", src.raw());
659 rc = virtualBox->FindHardDisk(src, hd.asOutParam());
660 if (SUCCEEDED(rc))
661 {
662 Guid id;
663 Bstr location;
664 CHECK_ERROR_BREAK(hd, COMGETTER(Id)(id.asOutParam()));
665 CHECK_ERROR_BREAK(hd, COMGETTER(Location)(location.asOutParam()));
666 RTPrintf("Found, UUID={%RTuuid}, location='%ls'.\n",
667 id.raw(), location.raw());
668
669 com::SafeArray<BSTR> names;
670 com::SafeArray<BSTR> values;
671
672 CHECK_ERROR_BREAK(hd, GetProperties(NULL,
673 ComSafeArrayAsOutParam(names),
674 ComSafeArrayAsOutParam(values)));
675
676 RTPrintf("Properties:\n");
677 for (size_t i = 0; i < names.size(); ++ i)
678 RTPrintf(" %ls = %ls\n", names[i], values[i]);
679
680 if (names.size() == 0)
681 RTPrintf(" <none>\n");
682
683#if 0
684 Bstr name("TargetAddress");
685 Bstr value = Utf8StrFmt("lalala (%llu)", RTTimeMilliTS());
686
687 RTPrintf("Settings property %ls to %ls...\n", name.raw(), value.raw());
688 CHECK_ERROR(hd, SetProperty(name, value));
689#endif
690 }
691 else
692 {
693 com::ErrorInfo info(virtualBox);
694 PRINT_ERROR_INFO(info);
695 }
696 RTPrintf("\n");
697 }
698 }
699 while (FALSE);
700 RTPrintf("\n");
701#endif
702
703#if 0
704 // access the machine in read-only mode
705 ///////////////////////////////////////////////////////////////////////////
706 do
707 {
708 ComPtr<IMachine> machine;
709 Bstr name = argc > 1 ? argv[1] : "dos";
710 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
711 CHECK_ERROR_BREAK(virtualBox, FindMachine(name, machine.asOutParam()));
712 RTPrintf("Accessing the machine in read-only mode:\n");
713 readAndChangeMachineSettings(machine);
714 }
715 while (0);
716 RTPrintf("\n");
717#endif
718
719#if 0
720 // create a new machine (w/o registering it)
721 ///////////////////////////////////////////////////////////////////////////
722 do
723 {
724 ComPtr<IMachine> machine;
725#if defined(RT_OS_LINUX)
726 Bstr baseDir = L"/tmp/vbox";
727#else
728 Bstr baseDir = L"C:\\vbox";
729#endif
730 Bstr name = L"machina";
731
732 RTPrintf("Creating a new machine object(base dir '%ls', name '%ls')...\n",
733 baseDir.raw(), name.raw());
734 CHECK_ERROR_BREAK(virtualBox, CreateMachine(name, L"", baseDir, L"",
735 false,
736 machine.asOutParam()));
737
738 RTPrintf("Getting name...\n");
739 CHECK_ERROR_BREAK(machine, COMGETTER(Name)(name.asOutParam()));
740 RTPrintf("Name: {%ls}\n", name.raw());
741
742 BOOL modified = FALSE;
743 RTPrintf("Are any settings modified?...\n");
744 CHECK_ERROR_BREAK(machine, COMGETTER(SettingsModified)(&modified));
745 RTPrintf("%s\n", modified ? "yes" : "no");
746
747 ASSERT_BREAK(modified == TRUE);
748
749 name = L"Kakaya prekrasnaya virtual'naya mashina!";
750 RTPrintf("Setting new name ({%ls})...\n", name.raw());
751 CHECK_ERROR_BREAK(machine, COMSETTER(Name)(name));
752
753 RTPrintf("Setting memory size to 111...\n");
754 CHECK_ERROR_BREAK(machine, COMSETTER(MemorySize)(111));
755
756 Bstr desc = L"This is an exemplary description.";
757 RTPrintf("Setting description to \"%ls\"...\n", desc.raw());
758 CHECK_ERROR_BREAK(machine, COMSETTER(Description)(desc));
759
760 ComPtr<IGuestOSType> guestOSType;
761 Bstr type = L"os2warp45";
762 CHECK_ERROR_BREAK(virtualBox, GetGuestOSType(type, guestOSType.asOutParam()));
763
764 RTPrintf("Saving new machine settings...\n");
765 CHECK_ERROR_BREAK(machine, SaveSettings());
766
767 RTPrintf("Accessing the newly created machine:\n");
768 readAndChangeMachineSettings(machine);
769 }
770 while (FALSE);
771 RTPrintf("\n");
772#endif
773
774#if 0
775 // enumerate host DVD drives
776 ///////////////////////////////////////////////////////////////////////////
777 do
778 {
779 ComPtr<IHost> host;
780 CHECK_RC_BREAK(virtualBox->COMGETTER(Host)(host.asOutParam()));
781
782 {
783 ComPtr<IHostDVDDriveCollection> coll;
784 CHECK_RC_BREAK(host->COMGETTER(DVDDrives)(coll.asOutParam()));
785 ComPtr<IHostDVDDriveEnumerator> enumerator;
786 CHECK_RC_BREAK(coll->Enumerate(enumerator.asOutParam()));
787 BOOL hasmore;
788 while (SUCCEEDED(enumerator->HasMore(&hasmore)) && hasmore)
789 {
790 ComPtr<IHostDVDDrive> drive;
791 CHECK_RC_BREAK(enumerator->GetNext(drive.asOutParam()));
792 Bstr name;
793 CHECK_RC_BREAK(drive->COMGETTER(Name)(name.asOutParam()));
794 RTPrintf("Host DVD drive: name={%ls}\n", name.raw());
795 }
796 CHECK_RC_BREAK(rc);
797
798 ComPtr<IHostDVDDrive> drive;
799 CHECK_ERROR(enumerator, GetNext(drive.asOutParam()));
800 CHECK_ERROR(coll, GetItemAt(1000, drive.asOutParam()));
801 CHECK_ERROR(coll, FindByName(Bstr("R:"), drive.asOutParam()));
802 if (SUCCEEDED(rc))
803 {
804 Bstr name;
805 CHECK_RC_BREAK(drive->COMGETTER(Name)(name.asOutParam()));
806 RTPrintf("Found by name: name={%ls}\n", name.raw());
807 }
808 }
809 }
810 while (FALSE);
811 RTPrintf("\n");
812#endif
813
814#if 0
815 // check for available hd backends
816 ///////////////////////////////////////////////////////////////////////////
817 {
818 RTPrintf("Supported hard disk backends: --------------------------\n");
819 ComPtr<ISystemProperties> systemProperties;
820 CHECK_ERROR_BREAK(virtualBox,
821 COMGETTER(SystemProperties)(systemProperties.asOutParam()));
822 com::SafeIfaceArray<IHardDiskFormat> hardDiskFormats;
823 CHECK_ERROR_BREAK(systemProperties,
824 COMGETTER(HardDiskFormats)(ComSafeArrayAsOutParam(hardDiskFormats)));
825
826 for (size_t i = 0; i < hardDiskFormats.size(); ++ i)
827 {
828 /* General information */
829 Bstr id;
830 CHECK_ERROR_BREAK(hardDiskFormats[i],
831 COMGETTER(Id)(id.asOutParam()));
832
833 Bstr description;
834 CHECK_ERROR_BREAK(hardDiskFormats[i],
835 COMGETTER(Id)(description.asOutParam()));
836
837 ULONG caps;
838 CHECK_ERROR_BREAK(hardDiskFormats[i],
839 COMGETTER(Capabilities)(&caps));
840
841 RTPrintf("Backend %u: id='%ls' description='%ls' capabilities=%#06x extensions='",
842 i, id.raw(), description.raw(), caps);
843
844 /* File extensions */
845 com::SafeArray<BSTR> fileExtensions;
846 CHECK_ERROR_BREAK(hardDiskFormats[i],
847 COMGETTER(FileExtensions)(ComSafeArrayAsOutParam(fileExtensions)));
848 for (size_t a = 0; a < fileExtensions.size(); ++ a)
849 {
850 RTPrintf("%ls", Bstr(fileExtensions[a]).raw());
851 if (a != fileExtensions.size()-1)
852 RTPrintf(",");
853 }
854 RTPrintf("'");
855
856 /* Configuration keys */
857 com::SafeArray<BSTR> propertyNames;
858 com::SafeArray<BSTR> propertyDescriptions;
859 com::SafeArray<ULONG> propertyTypes;
860 com::SafeArray<ULONG> propertyFlags;
861 com::SafeArray<BSTR> propertyDefaults;
862 CHECK_ERROR_BREAK(hardDiskFormats[i],
863 DescribeProperties(ComSafeArrayAsOutParam(propertyNames),
864 ComSafeArrayAsOutParam(propertyDescriptions),
865 ComSafeArrayAsOutParam(propertyTypes),
866 ComSafeArrayAsOutParam(propertyFlags),
867 ComSafeArrayAsOutParam(propertyDefaults)));
868
869 RTPrintf(" config=(");
870 if (propertyNames.size() > 0)
871 {
872 for (size_t a = 0; a < propertyNames.size(); ++ a)
873 {
874 RTPrintf("key='%ls' desc='%ls' type=", Bstr(propertyNames[a]).raw(), Bstr(propertyDescriptions[a]).raw());
875 switch (propertyTypes[a])
876 {
877 case DataType_Int32Type: RTPrintf("int"); break;
878 case DataType_Int8Type: RTPrintf("byte"); break;
879 case DataType_StringType: RTPrintf("string"); break;
880 }
881 RTPrintf(" flags=%#04x", propertyFlags[a]);
882 RTPrintf(" default='%ls'", Bstr(propertyDefaults[a]).raw());
883 if (a != propertyNames.size()-1)
884 RTPrintf(",");
885 }
886 }
887 RTPrintf(")\n");
888 }
889 RTPrintf("-------------------------------------------------------\n");
890 }
891#endif
892
893#if 0
894 // enumerate hard disks & dvd images
895 ///////////////////////////////////////////////////////////////////////////
896 do
897 {
898 {
899 com::SafeIfaceArray<IHardDisk> disks;
900 CHECK_ERROR_BREAK(virtualBox,
901 COMGETTER(HardDisks)(ComSafeArrayAsOutParam(disks)));
902
903 RTPrintf("%u base hard disks registered (disks.isNull()=%d).\n",
904 disks.size(), disks.isNull());
905
906 for (size_t i = 0; i < disks.size(); ++ i)
907 {
908 Bstr loc;
909 CHECK_ERROR_BREAK(disks[i], COMGETTER(Location)(loc.asOutParam()));
910 Guid id;
911 CHECK_ERROR_BREAK(disks[i], COMGETTER(Id)(id.asOutParam()));
912 MediaState_T state;
913 CHECK_ERROR_BREAK(disks[i], COMGETTER(State)(&state));
914 Bstr format;
915 CHECK_ERROR_BREAK(disks[i], COMGETTER(Format)(format.asOutParam()));
916
917 RTPrintf(" disks[%u]: '%ls'\n"
918 " UUID: {%RTuuid}\n"
919 " State: %s\n"
920 " Format: %ls\n",
921 i, loc.raw(), id.raw(),
922 state == MediaState_NotCreated ? "Not Created" :
923 state == MediaState_Created ? "Created" :
924 state == MediaState_Inaccessible ? "Inaccessible" :
925 state == MediaState_LockedRead ? "Locked Read" :
926 state == MediaState_LockedWrite ? "Locked Write" :
927 "???",
928 format.raw());
929
930 if (state == MediaState_Inaccessible)
931 {
932 Bstr error;
933 CHECK_ERROR_BREAK(disks[i],
934 COMGETTER(LastAccessError)(error.asOutParam()));
935 RTPrintf(" Access Error: %ls\n", error.raw());
936 }
937
938 /* get usage */
939
940 RTPrintf(" Used by VMs:\n");
941
942 com::SafeGUIDArray ids;
943 CHECK_ERROR_BREAK(disks[i],
944 COMGETTER(MachineIds)(ComSafeArrayAsOutParam(ids)));
945 if (ids.size() == 0)
946 {
947 RTPrintf(" <not used>\n");
948 }
949 else
950 {
951 for (size_t j = 0; j < ids.size(); ++ j)
952 {
953 RTPrintf(" {%RTuuid}\n", &ids[j]);
954 }
955 }
956 }
957 }
958 {
959 com::SafeIfaceArray<IDVDImage> images;
960 CHECK_ERROR_BREAK(virtualBox,
961 COMGETTER(DVDImages)(ComSafeArrayAsOutParam(images)));
962
963 RTPrintf("%u DVD images registered (images.isNull()=%d).\n",
964 images.size(), images.isNull());
965
966 for (size_t i = 0; i < images.size(); ++ i)
967 {
968 Bstr loc;
969 CHECK_ERROR_BREAK(images[i], COMGETTER(Location)(loc.asOutParam()));
970 Guid id;
971 CHECK_ERROR_BREAK(images[i], COMGETTER(Id)(id.asOutParam()));
972 MediaState_T state;
973 CHECK_ERROR_BREAK(images[i], COMGETTER(State)(&state));
974
975 RTPrintf(" images[%u]: '%ls'\n"
976 " UUID: {%RTuuid}\n"
977 " State: %s\n",
978 i, loc.raw(), id.raw(),
979 state == MediaState_NotCreated ? "Not Created" :
980 state == MediaState_Created ? "Created" :
981 state == MediaState_Inaccessible ? "Inaccessible" :
982 state == MediaState_LockedRead ? "Locked Read" :
983 state == MediaState_LockedWrite ? "Locked Write" :
984 "???");
985
986 if (state == MediaState_Inaccessible)
987 {
988 Bstr error;
989 CHECK_ERROR_BREAK(images[i],
990 COMGETTER(LastAccessError)(error.asOutParam()));
991 RTPrintf(" Access Error: %ls\n", error.raw());
992 }
993
994 /* get usage */
995
996 RTPrintf(" Used by VMs:\n");
997
998 com::SafeGUIDArray ids;
999 CHECK_ERROR_BREAK(images[i],
1000 COMGETTER(MachineIds)(ComSafeArrayAsOutParam(ids)));
1001 if (ids.size() == 0)
1002 {
1003 RTPrintf(" <not used>\n");
1004 }
1005 else
1006 {
1007 for (size_t j = 0; j < ids.size(); ++ j)
1008 {
1009 RTPrintf(" {%RTuuid}\n", &ids[j]);
1010 }
1011 }
1012 }
1013 }
1014 }
1015 while (FALSE);
1016 RTPrintf("\n");
1017#endif
1018
1019#if 0
1020 // open a (direct) session
1021 ///////////////////////////////////////////////////////////////////////////
1022 do
1023 {
1024 ComPtr<IMachine> machine;
1025 Bstr name = argc > 1 ? argv[1] : "dos";
1026 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1027 CHECK_ERROR_BREAK(virtualBox, FindMachine(name, machine.asOutParam()));
1028 Guid guid;
1029 CHECK_RC_BREAK(machine->COMGETTER(Id)(guid.asOutParam()));
1030 RTPrintf("Opening a session for this machine...\n");
1031 CHECK_RC_BREAK(virtualBox->OpenSession(session, guid));
1032#if 1
1033 ComPtr<IMachine> sessionMachine;
1034 RTPrintf("Getting machine session object...\n");
1035 CHECK_RC_BREAK(session->COMGETTER(Machine)(sessionMachine.asOutParam()));
1036 RTPrintf("Accessing the machine within the session:\n");
1037 readAndChangeMachineSettings(sessionMachine, machine);
1038#if 0
1039 RTPrintf("\n");
1040 RTPrintf("Enabling the VRDE server (must succeed even if the VM is saved):\n");
1041 ComPtr<IVRDEServer> vrdeServer;
1042 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(VRDEServer)(vrdeServer.asOutParam()));
1043 if (FAILED(vrdeServer->COMSETTER(Enabled)(TRUE)))
1044 {
1045 PRINT_ERROR_INFO(com::ErrorInfo(vrdeServer));
1046 }
1047 else
1048 {
1049 BOOL enabled = FALSE;
1050 CHECK_ERROR_BREAK(vrdeServer, COMGETTER(Enabled)(&enabled));
1051 RTPrintf("VRDE server is %s\n", enabled ? "enabled" : "disabled");
1052 }
1053#endif
1054#endif
1055#if 0
1056 ComPtr<IConsole> console;
1057 RTPrintf("Getting the console object...\n");
1058 CHECK_RC_BREAK(session->COMGETTER(Console)(console.asOutParam()));
1059 RTPrintf("Discarding the current machine state...\n");
1060 ComPtr<IProgress> progress;
1061 CHECK_ERROR_BREAK(console, DiscardCurrentState(progress.asOutParam()));
1062 RTPrintf("Waiting for completion...\n");
1063 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
1064 ProgressErrorInfo ei(progress);
1065 if (FAILED(ei.getResultCode()))
1066 {
1067 PRINT_ERROR_INFO(ei);
1068
1069 ComPtr<IUnknown> initiator;
1070 CHECK_ERROR_BREAK(progress, COMGETTER(Initiator)(initiator.asOutParam()));
1071
1072 RTPrintf("initiator(unk) = %p\n", (IUnknown *)initiator);
1073 RTPrintf("console(unk) = %p\n", (IUnknown *)ComPtr<IUnknown>((IConsole *)console));
1074 RTPrintf("console = %p\n", (IConsole *)console);
1075 }
1076#endif
1077 RTPrintf("Press enter to close session...");
1078 getchar();
1079 session->Close();
1080 }
1081 while (FALSE);
1082 RTPrintf("\n");
1083#endif
1084
1085#if 0
1086 // open a remote session
1087 ///////////////////////////////////////////////////////////////////////////
1088 do
1089 {
1090 ComPtr<IMachine> machine;
1091 Bstr name = L"dos";
1092 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1093 CHECK_RC_BREAK(virtualBox->FindMachine(name, machine.asOutParam()));
1094 Guid guid;
1095 CHECK_RC_BREAK(machine->COMGETTER(Id)(guid.asOutParam()));
1096 RTPrintf("Opening a remote session for this machine...\n");
1097 ComPtr<IProgress> progress;
1098 CHECK_RC_BREAK(virtualBox->OpenRemoteSession(session, guid, Bstr("gui"),
1099 NULL, progress.asOutParam()));
1100 RTPrintf("Waiting for the session to open...\n");
1101 CHECK_RC_BREAK(progress->WaitForCompletion(-1));
1102 ComPtr<IMachine> sessionMachine;
1103 RTPrintf("Getting machine session object...\n");
1104 CHECK_RC_BREAK(session->COMGETTER(Machine)(sessionMachine.asOutParam()));
1105 ComPtr<IConsole> console;
1106 RTPrintf("Getting console object...\n");
1107 CHECK_RC_BREAK(session->COMGETTER(Console)(console.asOutParam()));
1108 RTPrintf("Press enter to pause the VM execution in the remote session...");
1109 getchar();
1110 CHECK_RC(console->Pause());
1111 RTPrintf("Press enter to close this session...");
1112 getchar();
1113 session->Close();
1114 }
1115 while (FALSE);
1116 RTPrintf("\n");
1117#endif
1118
1119#if 0
1120 // open an existing remote session
1121 ///////////////////////////////////////////////////////////////////////////
1122 do
1123 {
1124 ComPtr<IMachine> machine;
1125 Bstr name = "dos";
1126 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1127 CHECK_RC_BREAK(virtualBox->FindMachine(name, machine.asOutParam()));
1128 Guid guid;
1129 CHECK_RC_BREAK(machine->COMGETTER(Id)(guid.asOutParam()));
1130 RTPrintf("Opening an existing remote session for this machine...\n");
1131 CHECK_RC_BREAK(virtualBox->OpenExistingSession(session, guid));
1132 ComPtr<IMachine> sessionMachine;
1133 RTPrintf("Getting machine session object...\n");
1134 CHECK_RC_BREAK(session->COMGETTER(Machine)(sessionMachine.asOutParam()));
1135#if 0
1136 ComPtr<IConsole> console;
1137 RTPrintf("Getting console object...\n");
1138 CHECK_RC_BREAK(session->COMGETTER(Console)(console.asOutParam()));
1139 RTPrintf("Press enter to pause the VM execution in the remote session...");
1140 getchar();
1141 CHECK_RC(console->Pause());
1142 RTPrintf("Press enter to close this session...");
1143 getchar();
1144#endif
1145 session->Close();
1146 }
1147 while (FALSE);
1148 RTPrintf("\n");
1149#endif
1150
1151 do {
1152 PlatformArchitecture_T platformArch = PlatformArchitecture_x86;
1153 ComPtr<IPlatformProperties> platformProperties;
1154 CHECK_ERROR_BREAK(virtualBox, GetPlatformProperties(platformArch, platformProperties.asOutParam()));
1155 ULONG uMinMB, uMaxMB, uStrideMB;
1156 CHECK_ERROR_BREAK(platformProperties, GetSupportedVRAMRange(GraphicsControllerType_VBoxVGA, TRUE /* fAccelerate3DEnabled */, &uMinMB, &uMaxMB, &uStrideMB));
1157 ASSERT_BREAK(uMinMB && RT_IS_POWER_OF_TWO(uMinMB));
1158 ASSERT_BREAK(uMaxMB && RT_IS_POWER_OF_TWO(uMaxMB));
1159 ASSERT_BREAK(uStrideMB && RT_IS_POWER_OF_TWO(uStrideMB));
1160 } while (0);
1161
1162#if 1
1163 do {
1164 // Get host
1165 ComPtr<IHost> host;
1166 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1167
1168 ULONG uMemSize, uMemAvail;
1169 CHECK_ERROR_BREAK(host, COMGETTER(MemorySize)(&uMemSize));
1170 RTPrintf("Total memory (MB): %u\n", uMemSize);
1171 CHECK_ERROR_BREAK(host, COMGETTER(MemoryAvailable)(&uMemAvail));
1172 RTPrintf("Free memory (MB): %u\n", uMemAvail);
1173 } while (0);
1174#endif
1175
1176#if 0
1177 do {
1178 // Get host
1179 ComPtr<IHost> host;
1180 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1181
1182 com::SafeIfaceArray<IHostNetworkInterface> hostNetworkInterfaces;
1183 CHECK_ERROR_BREAK(host,
1184 COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(hostNetworkInterfaces)));
1185 if (hostNetworkInterfaces.size() > 0)
1186 {
1187 ComPtr<IHostNetworkInterface> networkInterface = hostNetworkInterfaces[0];
1188 Bstr interfaceName;
1189 networkInterface->COMGETTER(Name)(interfaceName.asOutParam());
1190 RTPrintf("Found %d network interfaces, testing with %ls...\n", hostNetworkInterfaces.size(), interfaceName.raw());
1191 Bstr interfaceGuid;
1192 networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam());
1193 // Find the interface by its name
1194 networkInterface.setNull();
1195 CHECK_ERROR_BREAK(host,
1196 FindHostNetworkInterfaceByName(interfaceName.raw(), networkInterface.asOutParam()));
1197 Bstr interfaceGuid2;
1198 networkInterface->COMGETTER(Id)(interfaceGuid2.asOutParam());
1199 if (interfaceGuid2 != interfaceGuid)
1200 RTPrintf("Failed to retrieve an interface by name %ls.\n", interfaceName.raw());
1201 // Find the interface by its guid
1202 networkInterface.setNull();
1203 CHECK_ERROR_BREAK(host,
1204 FindHostNetworkInterfaceById(interfaceGuid.raw(), networkInterface.asOutParam()));
1205 Bstr interfaceName2;
1206 networkInterface->COMGETTER(Name)(interfaceName2.asOutParam());
1207 if (interfaceName != interfaceName2)
1208 RTPrintf("Failed to retrieve an interface by GUID %ls.\n", interfaceGuid.raw());
1209 }
1210 else
1211 {
1212 RTPrintf("No network interfaces found!\n");
1213 }
1214 } while (0);
1215#endif
1216
1217#if 0
1218 // DNS & Co.
1219 ///////////////////////////////////////////////////////////////////////////
1220 /* XXX: Note it's endless loop */
1221 do
1222 {
1223 ComPtr<IHost> host;
1224 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1225
1226 {
1227 Bstr domainName;
1228 CHECK_ERROR_BREAK(host,COMGETTER(DomainName)(domainName.asOutParam()));
1229 RTPrintf("Domain name: %ls\n", domainName.raw());
1230 }
1231
1232 com::SafeArray<BSTR> strs;
1233 CHECK_ERROR_BREAK(host, COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs)));
1234
1235 unsigned int i;
1236 for (i = 0; i < strs.size(); ++i)
1237 RTPrintf("Name server[%d]:%s\n", i, com::Utf8Str(strs[i]).c_str());
1238
1239 RTThreadSleep(1000);
1240 }
1241 while (1);
1242 RTPrintf("\n");
1243#endif
1244
1245
1246#if 0 && defined(VBOX_WITH_RESOURCE_USAGE_API)
1247 do {
1248 // Get collector
1249 ComPtr<IPerformanceCollector> collector;
1250 CHECK_ERROR_BREAK(virtualBox,
1251 COMGETTER(PerformanceCollector)(collector.asOutParam()));
1252
1253
1254 // Fill base metrics array
1255 Bstr baseMetricNames[] = { L"Net/eth0/Load" };
1256 com::SafeArray<BSTR> baseMetrics(1);
1257 baseMetricNames[0].cloneTo(&baseMetrics[0]);
1258
1259 // Get host
1260 ComPtr<IHost> host;
1261 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1262
1263 // Get host network interfaces
1264 // com::SafeIfaceArray<IHostNetworkInterface> hostNetworkInterfaces;
1265 // CHECK_ERROR_BREAK(host,
1266 // COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(hostNetworkInterfaces)));
1267
1268 // Setup base metrics
1269 // Note that one needs to set up metrics after a session is open for a machine.
1270 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
1271 com::SafeIfaceArray<IUnknown> objects(1);
1272 host.queryInterfaceTo(&objects[0]);
1273 CHECK_ERROR_BREAK(collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
1274 ComSafeArrayAsInParam(objects), 1u, 10u,
1275 ComSafeArrayAsOutParam(affectedMetrics)));
1276 listAffectedMetrics(virtualBox,
1277 ComSafeArrayAsInParam(affectedMetrics));
1278 affectedMetrics.setNull();
1279
1280 RTPrintf("Sleeping for 5 seconds...\n");
1281 RTThreadSleep(5000); // Sleep for 5 seconds
1282
1283 RTPrintf("\nMetrics collected: --------------------\n");
1284 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1285 } while (false);
1286#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1287#if 0 && defined(VBOX_WITH_RESOURCE_USAGE_API)
1288 do {
1289 // Get collector
1290 ComPtr<IPerformanceCollector> collector;
1291 CHECK_ERROR_BREAK(virtualBox,
1292 COMGETTER(PerformanceCollector)(collector.asOutParam()));
1293
1294
1295 // Fill base metrics array
1296 //Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" };
1297 Bstr baseMetricNames[] = { L"RAM/VMM" };
1298 com::SafeArray<BSTR> baseMetrics(1);
1299 baseMetricNames[0].cloneTo(&baseMetrics[0]);
1300
1301 // Get host
1302 ComPtr<IHost> host;
1303 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1304
1305 // Get machine
1306 ComPtr<IMachine> machine;
1307 Bstr name = argc > 1 ? argv[1] : "dsl";
1308 Bstr sessionType = argc > 2 ? argv[2] : "headless";
1309 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1310 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
1311
1312 // Open session
1313 ComPtr<IProgress> progress;
1314 RTPrintf("Launching VM process...\n");
1315 CHECK_ERROR_BREAK(machine, LaunchVMProcess(session, sessionType.raw(),
1316 ComSafeArrayNullInParam(), progress.asOutParam()));
1317 RTPrintf("Waiting for the VM to power on...\n");
1318 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
1319
1320 // ComPtr<IMachine> sessionMachine;
1321 // RTPrintf("Getting machine session object...\n");
1322 // CHECK_ERROR_BREAK(session, COMGETTER(Machine)(sessionMachine.asOutParam()));
1323
1324 // Setup base metrics
1325 // Note that one needs to set up metrics after a session is open for a machine.
1326 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
1327 com::SafeIfaceArray<IUnknown> objects(1);
1328 host.queryInterfaceTo(&objects[0]);
1329 //machine.queryInterfaceTo(&objects[1]);
1330 CHECK_ERROR_BREAK(collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
1331 ComSafeArrayAsInParam(objects), 1u, 10u,
1332 ComSafeArrayAsOutParam(affectedMetrics)));
1333 listAffectedMetrics(virtualBox,
1334 ComSafeArrayAsInParam(affectedMetrics));
1335 affectedMetrics.setNull();
1336
1337 // Get console
1338 ComPtr<IConsole> console;
1339 RTPrintf("Getting console object...\n");
1340 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
1341
1342 RTThreadSleep(5000); // Sleep for 5 seconds
1343
1344 RTPrintf("\nMetrics collected with VM running: --------------------\n");
1345 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1346
1347 // Pause
1348 //RTPrintf("Press enter to pause the VM execution in the remote session...");
1349 //getchar();
1350 CHECK_ERROR_BREAK(console, Pause());
1351
1352 RTThreadSleep(5000); // Sleep for 5 seconds
1353
1354 RTPrintf("\nMetrics collected with VM paused: ---------------------\n");
1355 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1356
1357 RTPrintf("\nDrop collected metrics: ----------------------------------------\n");
1358 CHECK_ERROR_BREAK(collector,
1359 SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
1360 ComSafeArrayAsInParam(objects),
1361 1u, 5u, ComSafeArrayAsOutParam(affectedMetrics)));
1362 listAffectedMetrics(virtualBox,
1363 ComSafeArrayAsInParam(affectedMetrics));
1364 affectedMetrics.setNull();
1365 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1366
1367 com::SafeIfaceArray<IUnknown> vmObject(1);
1368 machine.queryInterfaceTo(&vmObject[0]);
1369
1370 RTPrintf("\nDisable collection of VM metrics: ------------------------------\n");
1371 CHECK_ERROR_BREAK(collector,
1372 DisableMetrics(ComSafeArrayAsInParam(baseMetrics),
1373 ComSafeArrayAsInParam(vmObject),
1374 ComSafeArrayAsOutParam(affectedMetrics)));
1375 listAffectedMetrics(virtualBox,
1376 ComSafeArrayAsInParam(affectedMetrics));
1377 affectedMetrics.setNull();
1378 RTThreadSleep(5000); // Sleep for 5 seconds
1379 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1380
1381 RTPrintf("\nRe-enable collection of all metrics: ---------------------------\n");
1382 CHECK_ERROR_BREAK(collector,
1383 EnableMetrics(ComSafeArrayAsInParam(baseMetrics),
1384 ComSafeArrayAsInParam(objects),
1385 ComSafeArrayAsOutParam(affectedMetrics)));
1386 listAffectedMetrics(virtualBox,
1387 ComSafeArrayAsInParam(affectedMetrics));
1388 affectedMetrics.setNull();
1389 RTThreadSleep(5000); // Sleep for 5 seconds
1390 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1391
1392 // Power off
1393 RTPrintf("Press enter to power off VM...");
1394 getchar();
1395 CHECK_ERROR_BREAK(console, PowerDown(progress.asOutParam()));
1396 RTPrintf("Waiting for the VM to power down...\n");
1397 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
1398 RTPrintf("Press enter to close this session...");
1399 getchar();
1400 session->UnlockMachine();
1401 } while (false);
1402#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1403#if 0
1404 // check of OVF appliance handling
1405 ///////////////////////////////////////////////////////////////////////////
1406 do
1407 {
1408 Bstr ovf = argc > 1 ? argv[1] : "someOVF.ovf";
1409 RTPrintf("Try to open %ls ...\n", ovf.raw());
1410
1411 ComPtr<IAppliance> appliance;
1412 CHECK_ERROR_BREAK(virtualBox,
1413 CreateAppliance(appliance.asOutParam()));
1414 CHECK_ERROR_BREAK(appliance, Read(ovf));
1415 Bstr path;
1416 CHECK_ERROR_BREAK(appliance, COMGETTER(Path)(path.asOutParam()));
1417 RTPrintf("Successfully opened %ls.\n", path.raw());
1418 CHECK_ERROR_BREAK(appliance, Interpret());
1419 RTPrintf("Successfully interpreted %ls.\n", path.raw());
1420 RTPrintf("Appliance:\n");
1421 // Fetch all disks
1422 com::SafeArray<BSTR> retDisks;
1423 CHECK_ERROR_BREAK(appliance,
1424 COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks)));
1425 if (retDisks.size() > 0)
1426 {
1427 RTPrintf("Disks:");
1428 for (unsigned i = 0; i < retDisks.size(); i++)
1429 RTPrintf(" %ls", Bstr(retDisks[i]).raw());
1430 RTPrintf("\n");
1431 }
1432 /* Fetch all virtual system descriptions */
1433 com::SafeIfaceArray<IVirtualSystemDescription> retVSD;
1434 CHECK_ERROR_BREAK(appliance,
1435 COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(retVSD)));
1436 if (retVSD.size() > 0)
1437 {
1438 for (unsigned i = 0; i < retVSD.size(); ++i)
1439 {
1440 com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
1441 com::SafeArray<BSTR> retRefValues;
1442 com::SafeArray<BSTR> retOrigValues;
1443 com::SafeArray<BSTR> retAutoValues;
1444 com::SafeArray<BSTR> retConfiguration;
1445 CHECK_ERROR_BREAK(retVSD[i],
1446 GetDescription(ComSafeArrayAsOutParam(retTypes),
1447 ComSafeArrayAsOutParam(retRefValues),
1448 ComSafeArrayAsOutParam(retOrigValues),
1449 ComSafeArrayAsOutParam(retAutoValues),
1450 ComSafeArrayAsOutParam(retConfiguration)));
1451
1452 RTPrintf("VirtualSystemDescription:\n");
1453 for (unsigned a = 0; a < retTypes.size(); ++a)
1454 {
1455 RTPrintf(" %d %ls %ls %ls\n",
1456 retTypes[a],
1457 Bstr(retOrigValues[a]).raw(),
1458 Bstr(retAutoValues[a]).raw(),
1459 Bstr(retConfiguration[a]).raw());
1460 }
1461 /* Show warnings from interpret */
1462 com::SafeArray<BSTR> retWarnings;
1463 CHECK_ERROR_BREAK(retVSD[i],
1464 GetWarnings(ComSafeArrayAsOutParam(retWarnings)));
1465 if (retWarnings.size() > 0)
1466 {
1467 RTPrintf("The following warnings occurs on interpret:\n");
1468 for (unsigned r = 0; r < retWarnings.size(); ++r)
1469 RTPrintf("%ls\n", Bstr(retWarnings[r]).raw());
1470 RTPrintf("\n");
1471 }
1472 }
1473 RTPrintf("\n");
1474 }
1475 RTPrintf("Try to import the appliance ...\n");
1476 ComPtr<IProgress> progress;
1477 CHECK_ERROR_BREAK(appliance,
1478 ImportMachines(progress.asOutParam()));
1479 CHECK_ERROR(progress, WaitForCompletion(-1));
1480 if (SUCCEEDED(rc))
1481 {
1482 /* Check if the import was successfully */
1483 progress->COMGETTER(ResultCode)(&rc);
1484 if (FAILED(rc))
1485 {
1486 com::ProgressErrorInfo info(progress);
1487 if (info.isBasicAvailable())
1488 RTPrintf("Error: failed to import appliance. Error message: %ls\n", info.getText().raw());
1489 else
1490 RTPrintf("Error: failed to import appliance. No error message available!\n");
1491 }
1492 else
1493 RTPrintf("Successfully imported the appliance.\n");
1494 }
1495
1496 }
1497 while (FALSE);
1498 RTPrintf("\n");
1499#endif
1500#if 0
1501 // check of network bandwidth control
1502 ///////////////////////////////////////////////////////////////////////////
1503 do
1504 {
1505 Bstr name = argc > 1 ? argv[1] : "ubuntu";
1506 Bstr sessionType = argc > 2 ? argv[2] : "headless";
1507 Bstr grpName = "tstAPI";
1508 {
1509 // Get machine
1510 ComPtr<IMachine> machine;
1511 ComPtr<IBandwidthControl> bwCtrl;
1512 ComPtr<IBandwidthGroup> bwGroup;
1513 ComPtr<INetworkAdapter> nic;
1514 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1515 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
1516 /* open a session for the VM (new or shared) */
1517 CHECK_ERROR_BREAK(machine, LockMachine(session, LockType_Shared));
1518 SessionType_T st;
1519 CHECK_ERROR_BREAK(session, COMGETTER(Type)(&st));
1520 bool fRunTime = (st == SessionType_Shared);
1521 if (fRunTime)
1522 {
1523 RTPrintf("Machine %ls must not be running!\n");
1524 break;
1525 }
1526 /* get the mutable session machine */
1527 session->COMGETTER(Machine)(machine.asOutParam());
1528 CHECK_ERROR_BREAK(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
1529
1530 RTPrintf("Creating bandwidth group named '%ls'...\n", grpName.raw());
1531 CHECK_ERROR_BREAK(bwCtrl, CreateBandwidthGroup(grpName.raw(), BandwidthGroupType_Network, 123));
1532
1533
1534 CHECK_ERROR_BREAK(bwCtrl, GetBandwidthGroup(grpName.raw(), bwGroup.asOutParam()));
1535 CHECK_ERROR_BREAK(machine, GetNetworkAdapter(0, nic.asOutParam()));
1536 RTPrintf("Assigning the group to the first network adapter...\n");
1537 CHECK_ERROR_BREAK(nic, COMSETTER(BandwidthGroup)(bwGroup));
1538 CHECK_ERROR_BREAK(machine, SaveSettings());
1539 RTPrintf("Press enter to close this session...");
1540 getchar();
1541 session->UnlockMachine();
1542 }
1543 {
1544 // Get machine
1545 ComPtr<IMachine> machine;
1546 ComPtr<IBandwidthControl> bwCtrl;
1547 ComPtr<IBandwidthGroup> bwGroup;
1548 Bstr grpNameReadFromNic;
1549 ComPtr<INetworkAdapter> nic;
1550 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1551 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
1552 /* open a session for the VM (new or shared) */
1553 CHECK_ERROR_BREAK(machine, LockMachine(session, LockType_Shared));
1554 /* get the mutable session machine */
1555 session->COMGETTER(Machine)(machine.asOutParam());
1556 CHECK_ERROR_BREAK(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
1557 CHECK_ERROR_BREAK(machine, GetNetworkAdapter(0, nic.asOutParam()));
1558
1559 RTPrintf("Reading the group back from the first network adapter...\n");
1560 CHECK_ERROR_BREAK(nic, COMGETTER(BandwidthGroup)(bwGroup.asOutParam()));
1561 if (bwGroup.isNull())
1562 RTPrintf("Error: Bandwidth group is null at the first network adapter!\n");
1563 else
1564 {
1565 CHECK_ERROR_BREAK(bwGroup, COMGETTER(Name)(grpNameReadFromNic.asOutParam()));
1566 if (grpName != grpNameReadFromNic)
1567 RTPrintf("Error: Bandwidth group names do not match (%ls != %ls)!\n", grpName.raw(), grpNameReadFromNic.raw());
1568 else
1569 RTPrintf("Successfully retrieved bandwidth group attribute from NIC (name=%ls)\n", grpNameReadFromNic.raw());
1570 ComPtr<IBandwidthGroup> bwGroupEmpty;
1571 RTPrintf("Assigning an empty group to the first network adapter...\n");
1572 CHECK_ERROR_BREAK(nic, COMSETTER(BandwidthGroup)(bwGroupEmpty));
1573 }
1574 RTPrintf("Removing bandwidth group named '%ls'...\n", grpName.raw());
1575 CHECK_ERROR_BREAK(bwCtrl, DeleteBandwidthGroup(grpName.raw()));
1576 CHECK_ERROR_BREAK(machine, SaveSettings());
1577 RTPrintf("Press enter to close this session...");
1578 getchar();
1579 session->UnlockMachine();
1580 }
1581 } while (FALSE);
1582 RTPrintf("\n");
1583#endif
1584
1585 RTPrintf("Press enter to release Session and VirtualBox instances...");
1586 getchar();
1587
1588 // end "all-stuff" scope
1589 ////////////////////////////////////////////////////////////////////////////
1590 }
1591 while (0);
1592
1593 RTPrintf("Press enter to shutdown COM...");
1594 getchar();
1595
1596 com::Shutdown();
1597
1598 RTPrintf("tstAPI FINISHED.\n");
1599
1600 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1601}
1602
1603#ifdef VBOX_WITH_RESOURCE_USAGE_API
1604
1605static void queryMetrics(ComPtr<IVirtualBox> aVirtualBox,
1606 ComPtr<IPerformanceCollector> collector,
1607 ComSafeArrayIn(IUnknown *, objects))
1608{
1609 HRESULT rc;
1610
1611 //Bstr metricNames[] = { L"CPU/Load/User:avg,CPU/Load/System:avg,CPU/Load/Idle:avg,RAM/Usage/Total,RAM/Usage/Used:avg" };
1612 Bstr metricNames[] = { L"*" };
1613 com::SafeArray<BSTR> metrics(1);
1614 metricNames[0].cloneTo(&metrics[0]);
1615 com::SafeArray<BSTR> retNames;
1616 com::SafeIfaceArray<IUnknown> retObjects;
1617 com::SafeArray<BSTR> retUnits;
1618 com::SafeArray<ULONG> retScales;
1619 com::SafeArray<ULONG> retSequenceNumbers;
1620 com::SafeArray<ULONG> retIndices;
1621 com::SafeArray<ULONG> retLengths;
1622 com::SafeArray<LONG> retData;
1623 CHECK_ERROR(collector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
1624 ComSafeArrayInArg(objects),
1625 ComSafeArrayAsOutParam(retNames),
1626 ComSafeArrayAsOutParam(retObjects),
1627 ComSafeArrayAsOutParam(retUnits),
1628 ComSafeArrayAsOutParam(retScales),
1629 ComSafeArrayAsOutParam(retSequenceNumbers),
1630 ComSafeArrayAsOutParam(retIndices),
1631 ComSafeArrayAsOutParam(retLengths),
1632 ComSafeArrayAsOutParam(retData)));
1633 RTPrintf("Object Metric Values\n"
1634 "---------- -------------------- --------------------------------------------\n");
1635 for (unsigned i = 0; i < retNames.size(); i++)
1636 {
1637 Bstr metricUnit(retUnits[i]);
1638 Bstr metricName(retNames[i]);
1639 RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
1640 const char *separator = "";
1641 for (unsigned j = 0; j < retLengths[i]; j++)
1642 {
1643 if (retScales[i] == 1)
1644 RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
1645 else
1646 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
1647 (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
1648 separator = ", ";
1649 }
1650 RTPrintf("\n");
1651 }
1652}
1653
1654static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox,
1655 ComPtr<IUnknown> aObject)
1656{
1657 HRESULT rc;
1658
1659 ComPtr<IHost> host = aObject;
1660 if (!host.isNull())
1661 return Bstr("host");
1662
1663 ComPtr<IMachine> machine = aObject;
1664 if (!machine.isNull())
1665 {
1666 Bstr name;
1667 CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
1668 if (SUCCEEDED(rc))
1669 return name;
1670 }
1671 return Bstr("unknown");
1672}
1673
1674static void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
1675 ComSafeArrayIn(IPerformanceMetric*, aMetrics))
1676{
1677 HRESULT rc;
1678 com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
1679 if (metrics.size())
1680 {
1681 ComPtr<IUnknown> object;
1682 Bstr metricName;
1683 RTPrintf("The following metrics were modified:\n\n"
1684 "Object Metric\n"
1685 "---------- --------------------\n");
1686 for (size_t i = 0; i < metrics.size(); i++)
1687 {
1688 CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
1689 CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
1690 RTPrintf("%-10ls %-20ls\n",
1691 getObjectName(aVirtualBox, object).raw(), metricName.raw());
1692 }
1693 RTPrintf("\n");
1694 }
1695 else
1696 {
1697 RTPrintf("No metrics match the specified filter!\n");
1698 }
1699}
1700
1701#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1702/* vim: set shiftwidth=4 tabstop=4 expandtab: */
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