VirtualBox

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

Last change on this file since 61572 was 60063, checked in by vboxsync, 9 years ago

Frontends etc: convert more code to use VirtualBoxClient instead of direct creation of VirtualBox instances, to improve error handling

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