VirtualBox

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

Last change on this file since 74910 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • 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 69500 2017-10-28 15:14:05Z vboxsync $ */
2/** @file
3 * tstAPI - test program for our COM/XPCOM interface
4 */
5
6/*
7 * Copyright (C) 2006-2017 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
46#ifdef VBOX_WITH_RESOURCE_USAGE_API
47static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox, 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#endif
54
55// funcs
56///////////////////////////////////////////////////////////////////////////////
57
58HRESULT readAndChangeMachineSettings(IMachine *machine, IMachine *readonlyMachine = 0)
59{
60 HRESULT rc = S_OK;
61
62 Bstr name;
63 RTPrintf("Getting machine name...\n");
64 CHECK_ERROR_RET(machine, COMGETTER(Name)(name.asOutParam()), rc);
65 RTPrintf("Name: {%ls}\n", name.raw());
66
67 RTPrintf("Getting machine GUID...\n");
68 Bstr guid;
69 CHECK_ERROR(machine, COMGETTER(Id)(guid.asOutParam()));
70 if (SUCCEEDED(rc) && !guid.isEmpty()) {
71 RTPrintf("Guid::toString(): {%s}\n", Utf8Str(guid).c_str());
72 } else {
73 RTPrintf("WARNING: there's no GUID!");
74 }
75
76 ULONG memorySize;
77 RTPrintf("Getting memory size...\n");
78 CHECK_ERROR_RET(machine, COMGETTER(MemorySize)(&memorySize), rc);
79 RTPrintf("Memory size: %d\n", memorySize);
80
81 MachineState_T machineState;
82 RTPrintf("Getting machine state...\n");
83 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), rc);
84 RTPrintf("Machine state: %d\n", machineState);
85
86 BOOL modified;
87 RTPrintf("Are any settings modified?...\n");
88 CHECK_ERROR(machine, COMGETTER(SettingsModified)(&modified));
89 if (SUCCEEDED(rc))
90 RTPrintf("%s\n", modified ? "yes" : "no");
91
92 ULONG memorySizeBig = memorySize * 10;
93 RTPrintf("Changing memory size to %d...\n", memorySizeBig);
94 CHECK_ERROR(machine, COMSETTER(MemorySize)(memorySizeBig));
95
96 if (SUCCEEDED(rc))
97 {
98 RTPrintf("Are any settings modified now?...\n");
99 CHECK_ERROR_RET(machine, COMGETTER(SettingsModified)(&modified), rc);
100 RTPrintf("%s\n", modified ? "yes" : "no");
101 ASSERT_RET(modified, 0);
102
103 ULONG memorySizeGot;
104 RTPrintf("Getting memory size again...\n");
105 CHECK_ERROR_RET(machine, COMGETTER(MemorySize)(&memorySizeGot), rc);
106 RTPrintf("Memory size: %d\n", memorySizeGot);
107 ASSERT_RET(memorySizeGot == memorySizeBig, 0);
108
109 if (readonlyMachine)
110 {
111 RTPrintf("Getting memory size of the counterpart readonly machine...\n");
112 ULONG memorySizeRO;
113 readonlyMachine->COMGETTER(MemorySize)(&memorySizeRO);
114 RTPrintf("Memory size: %d\n", memorySizeRO);
115 ASSERT_RET(memorySizeRO != memorySizeGot, 0);
116 }
117
118 RTPrintf("Discarding recent changes...\n");
119 CHECK_ERROR_RET(machine, DiscardSettings(), rc);
120 RTPrintf("Are any settings modified after discarding?...\n");
121 CHECK_ERROR_RET(machine, COMGETTER(SettingsModified)(&modified), rc);
122 RTPrintf("%s\n", modified ? "yes" : "no");
123 ASSERT_RET(!modified, 0);
124
125 RTPrintf("Getting memory size once more...\n");
126 CHECK_ERROR_RET(machine, COMGETTER(MemorySize)(&memorySizeGot), rc);
127 RTPrintf("Memory size: %d\n", memorySizeGot);
128 ASSERT_RET(memorySizeGot == memorySize, 0);
129
130 memorySize = memorySize > 128 ? memorySize / 2 : memorySize * 2;
131 RTPrintf("Changing memory size to %d...\n", memorySize);
132 CHECK_ERROR_RET(machine, COMSETTER(MemorySize)(memorySize), rc);
133 }
134
135 Bstr desc;
136 RTPrintf("Getting description...\n");
137 CHECK_ERROR_RET(machine, COMGETTER(Description)(desc.asOutParam()), rc);
138 RTPrintf("Description is: \"%ls\"\n", desc.raw());
139
140 desc = L"This is an exemplary description (changed).";
141 RTPrintf("Setting description to \"%ls\"...\n", desc.raw());
142 CHECK_ERROR_RET(machine, COMSETTER(Description)(desc.raw()), rc);
143
144 RTPrintf("Saving machine settings...\n");
145 CHECK_ERROR(machine, SaveSettings());
146 if (SUCCEEDED(rc))
147 {
148 RTPrintf("Are any settings modified after saving?...\n");
149 CHECK_ERROR_RET(machine, COMGETTER(SettingsModified)(&modified), rc);
150 RTPrintf("%s\n", modified ? "yes" : "no");
151 ASSERT_RET(!modified, 0);
152
153 if (readonlyMachine) {
154 RTPrintf("Getting memory size of the counterpart readonly machine...\n");
155 ULONG memorySizeRO;
156 readonlyMachine->COMGETTER(MemorySize)(&memorySizeRO);
157 RTPrintf("Memory size: %d\n", memorySizeRO);
158 ASSERT_RET(memorySizeRO == memorySize, 0);
159 }
160 }
161
162 Bstr extraDataKey = L"Blafasel";
163 Bstr extraData;
164 RTPrintf("Getting extra data key {%ls}...\n", extraDataKey.raw());
165 CHECK_ERROR_RET(machine, GetExtraData(extraDataKey.raw(), extraData.asOutParam()), rc);
166 if (!extraData.isEmpty()) {
167 RTPrintf("Extra data value: {%ls}\n", extraData.raw());
168 } else {
169 RTPrintf("No extra data exists\n");
170 }
171
172 if (extraData.isEmpty())
173 extraData = L"Das ist die Berliner Luft, Luft, Luft...";
174 else
175 extraData.setNull();
176 RTPrintf("Setting extra data key {%ls} to {%ls}...\n",
177 extraDataKey.raw(), extraData.raw());
178 CHECK_ERROR(machine, SetExtraData(extraDataKey.raw(), extraData.raw()));
179
180 if (SUCCEEDED(rc)) {
181 RTPrintf("Getting extra data key {%ls} again...\n", extraDataKey.raw());
182 CHECK_ERROR_RET(machine, GetExtraData(extraDataKey.raw(), extraData.asOutParam()), rc);
183 if (!extraData.isEmpty()) {
184 RTPrintf("Extra data value: {%ls}\n", extraData.raw());
185 } else {
186 RTPrintf("No extra data exists\n");
187 }
188 }
189
190 return rc;
191}
192
193// main
194///////////////////////////////////////////////////////////////////////////////
195
196int main(int argc, char *argv[])
197{
198 /*
199 * Initialize the VBox runtime without loading
200 * the support driver.
201 */
202 RTR3InitExe(argc, &argv, 0);
203
204 HRESULT rc;
205
206 {
207 char homeDir[RTPATH_MAX];
208 GetVBoxUserHomeDirectory(homeDir, sizeof(homeDir));
209 RTPrintf("VirtualBox Home Directory = '%s'\n", homeDir);
210 }
211
212 RTPrintf("Initializing COM...\n");
213
214 rc = com::Initialize();
215 if (FAILED(rc))
216 {
217 RTPrintf("ERROR: failed to initialize COM!\n");
218 return rc;
219 }
220
221 do
222 {
223 // scopes all the stuff till shutdown
224 ////////////////////////////////////////////////////////////////////////////
225
226 ComPtr<IVirtualBoxClient> virtualBoxClient;
227 ComPtr<IVirtualBox> virtualBox;
228 ComPtr<ISession> session;
229
230#if 0
231 // Utf8Str test
232 ////////////////////////////////////////////////////////////////////////////
233
234 Utf8Str nullUtf8Str;
235 RTPrintf("nullUtf8Str='%s'\n", nullUtf8Str.raw());
236
237 Utf8Str simpleUtf8Str = "simpleUtf8Str";
238 RTPrintf("simpleUtf8Str='%s'\n", simpleUtf8Str.raw());
239
240 Utf8Str utf8StrFmt = Utf8StrFmt("[0=%d]%s[1=%d]", 0, "utf8StrFmt", 1);
241 RTPrintf("utf8StrFmt='%s'\n", utf8StrFmt.raw());
242
243#endif
244
245 RTPrintf("Creating VirtualBox object...\n");
246 rc = virtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
247 if (SUCCEEDED(rc))
248 rc = virtualBoxClient->COMGETTER(VirtualBox)(virtualBox.asOutParam());
249 if (FAILED(rc))
250 RTPrintf("ERROR: failed to create the VirtualBox object!\n");
251 else
252 {
253 rc = session.createInprocObject(CLSID_Session);
254 if (FAILED(rc))
255 RTPrintf("ERROR: failed to create a session object!\n");
256 }
257
258 if (FAILED(rc))
259 {
260 com::ErrorInfo info;
261 if (!info.isFullAvailable() && !info.isBasicAvailable())
262 {
263 com::GluePrintRCMessage(rc);
264 RTPrintf("Most likely, the VirtualBox COM server is not running or failed to start.\n");
265 }
266 else
267 com::GluePrintErrorInfo(info);
268 break;
269 }
270
271#if 0
272 // Testing VirtualBox::COMGETTER(ProgressOperations).
273 // This is designed to be tested while running
274 // "./VBoxManage clonehd src.vdi clone.vdi" in parallel.
275 // It will then display the progress every 2 seconds.
276 ////////////////////////////////////////////////////////////////////////////
277 {
278 RTPrintf("Testing VirtualBox::COMGETTER(ProgressOperations)...\n");
279
280 for (;;) {
281 com::SafeIfaceArray<IProgress> operations;
282
283 CHECK_ERROR_BREAK(virtualBox,
284 COMGETTER(ProgressOperations)(ComSafeArrayAsOutParam(operations)));
285
286 RTPrintf("operations: %d\n", operations.size());
287 if (operations.size() == 0)
288 break; // No more operations left.
289
290 for (size_t i = 0; i < operations.size(); ++i) {
291 PRInt32 percent;
292
293 operations[i]->COMGETTER(Percent)(&percent);
294 RTPrintf("operations[%u]: %ld\n", (unsigned)i, (long)percent);
295 }
296 RTThreadSleep(2000); // msec
297 }
298 }
299#endif
300
301#if 0
302 // IUnknown identity test
303 ////////////////////////////////////////////////////////////////////////////
304 {
305 {
306 ComPtr<IVirtualBox> virtualBox2;
307
308 RTPrintf("Creating one more VirtualBox object...\n");
309 CHECK_RC(virtualBoxClient->COMGETTER(virtualBox2.asOutParam()));
310 if (FAILED(rc))
311 {
312 CHECK_ERROR_NOCALL();
313 break;
314 }
315
316 RTPrintf("IVirtualBox(virtualBox)=%p IVirtualBox(virtualBox2)=%p\n",
317 (IVirtualBox *)virtualBox, (IVirtualBox *)virtualBox2);
318 Assert((IVirtualBox *)virtualBox == (IVirtualBox *)virtualBox2);
319
320 ComPtr<IUnknown> unk(virtualBox);
321 ComPtr<IUnknown> unk2;
322 unk2 = virtualBox2;
323
324 RTPrintf("IUnknown(virtualBox)=%p IUnknown(virtualBox2)=%p\n",
325 (IUnknown *)unk, (IUnknown *)unk2);
326 Assert((IUnknown *)unk == (IUnknown *)unk2);
327
328 ComPtr<IVirtualBox> vb = unk;
329 ComPtr<IVirtualBox> vb2 = unk;
330
331 RTPrintf("IVirtualBox(IUnknown(virtualBox))=%p IVirtualBox(IUnknown(virtualBox2))=%p\n",
332 (IVirtualBox *)vb, (IVirtualBox *)vb2);
333 Assert((IVirtualBox *)vb == (IVirtualBox *)vb2);
334 }
335
336 {
337 ComPtr<IHost> host;
338 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
339 RTPrintf(" IHost(host)=%p\n", (IHost *)host);
340 ComPtr<IUnknown> unk = host;
341 RTPrintf(" IUnknown(host)=%p\n", (IUnknown *)unk);
342 ComPtr<IHost> host_copy = unk;
343 RTPrintf(" IHost(host_copy)=%p\n", (IHost *)host_copy);
344 ComPtr<IUnknown> unk_copy = host_copy;
345 RTPrintf(" IUnknown(host_copy)=%p\n", (IUnknown *)unk_copy);
346 Assert((IUnknown *)unk == (IUnknown *)unk_copy);
347
348 /* query IUnknown on IUnknown */
349 ComPtr<IUnknown> unk_copy_copy;
350 unk_copy.queryInterfaceTo(unk_copy_copy.asOutParam());
351 RTPrintf(" IUnknown(unk_copy)=%p\n", (IUnknown *)unk_copy_copy);
352 Assert((IUnknown *)unk_copy == (IUnknown *)unk_copy_copy);
353 /* query IUnknown on IUnknown in the opposite direction */
354 unk_copy_copy.queryInterfaceTo(unk_copy.asOutParam());
355 RTPrintf(" IUnknown(unk_copy_copy)=%p\n", (IUnknown *)unk_copy);
356 Assert((IUnknown *)unk_copy == (IUnknown *)unk_copy_copy);
357
358 /* query IUnknown again after releasing all previous IUnknown instances
359 * but keeping IHost -- it should remain the same (Identity Rule) */
360 IUnknown *oldUnk = unk;
361 unk.setNull();
362 unk_copy.setNull();
363 unk_copy_copy.setNull();
364 unk = host;
365 RTPrintf(" IUnknown(host)=%p\n", (IUnknown *)unk);
366 Assert(oldUnk == (IUnknown *)unk);
367 }
368
369// RTPrintf("Will be now released (press Enter)...");
370// getchar();
371 }
372#endif
373
374#if 0
375 // the simplest COM API test
376 ////////////////////////////////////////////////////////////////////////////
377 {
378 Bstr version;
379 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Version)(version.asOutParam()));
380 RTPrintf("VirtualBox version = %ls\n", version.raw());
381 }
382#endif
383
384#if 0
385 // Array test
386 ////////////////////////////////////////////////////////////////////////////
387 {
388 RTPrintf("Calling IVirtualBox::Machines...\n");
389
390 com::SafeIfaceArray<IMachine> machines;
391 CHECK_ERROR_BREAK(virtualBox,
392 COMGETTER(Machines)(ComSafeArrayAsOutParam(machines)));
393
394 RTPrintf("%u machines registered (machines.isNull()=%d).\n",
395 machines.size(), machines.isNull());
396
397 for (size_t i = 0; i < machines.size(); ++ i)
398 {
399 Bstr name;
400 CHECK_ERROR_BREAK(machines[i], COMGETTER(Name)(name.asOutParam()));
401 RTPrintf("machines[%u]='%s'\n", i, Utf8Str(name).raw());
402 }
403
404#if 0
405 {
406 RTPrintf("Testing [out] arrays...\n");
407 com::SafeGUIDArray uuids;
408 CHECK_ERROR_BREAK(virtualBox,
409 COMGETTER(Uuids)(ComSafeArrayAsOutParam(uuids)));
410
411 for (size_t i = 0; i < uuids.size(); ++ i)
412 RTPrintf("uuids[%u]=%RTuuid\n", i, &uuids[i]);
413 }
414
415 {
416 RTPrintf("Testing [in] arrays...\n");
417 com::SafeGUIDArray uuids(5);
418 for (size_t i = 0; i < uuids.size(); ++ i)
419 {
420 Guid id;
421 id.create();
422 uuids[i] = id;
423 RTPrintf("uuids[%u]=%RTuuid\n", i, &uuids[i]);
424 }
425
426 CHECK_ERROR_BREAK(virtualBox,
427 SetUuids(ComSafeArrayAsInParam(uuids)));
428 }
429#endif
430
431 }
432#endif
433
434#if 0
435 // some outdated stuff
436 ////////////////////////////////////////////////////////////////////////////
437
438 RTPrintf("Getting IHost interface...\n");
439 IHost *host;
440 rc = virtualBox->GetHost(&host);
441 if (SUCCEEDED(rc))
442 {
443 IHostDVDDriveCollection *dvdColl;
444 rc = host->GetHostDVDDrives(&dvdColl);
445 if (SUCCEEDED(rc))
446 {
447 IHostDVDDrive *dvdDrive = NULL;
448 dvdColl->GetNextHostDVDDrive(dvdDrive, &dvdDrive);
449 while (dvdDrive)
450 {
451 BSTR driveName;
452 char *driveNameUtf8;
453 dvdDrive->GetDriveName(&driveName);
454 RTUtf16ToUtf8((PCRTUTF16)driveName, &driveNameUtf8);
455 RTPrintf("Host DVD drive name: %s\n", driveNameUtf8);
456 RTStrFree(driveNameUtf8);
457 SysFreeString(driveName);
458 IHostDVDDrive *dvdDriveTemp = dvdDrive;
459 dvdColl->GetNextHostDVDDrive(dvdDriveTemp, &dvdDrive);
460 dvdDriveTemp->Release();
461 }
462 dvdColl->Release();
463 } else
464 {
465 RTPrintf("Could not get host DVD drive collection\n");
466 }
467
468 IHostFloppyDriveCollection *floppyColl;
469 rc = host->GetHostFloppyDrives(&floppyColl);
470 if (SUCCEEDED(rc))
471 {
472 IHostFloppyDrive *floppyDrive = NULL;
473 floppyColl->GetNextHostFloppyDrive(floppyDrive, &floppyDrive);
474 while (floppyDrive)
475 {
476 BSTR driveName;
477 char *driveNameUtf8;
478 floppyDrive->GetDriveName(&driveName);
479 RTUtf16ToUtf8((PCRTUTF16)driveName, &driveNameUtf8);
480 RTPrintf("Host floppy drive name: %s\n", driveNameUtf8);
481 RTStrFree(driveNameUtf8);
482 SysFreeString(driveName);
483 IHostFloppyDrive *floppyDriveTemp = floppyDrive;
484 floppyColl->GetNextHostFloppyDrive(floppyDriveTemp, &floppyDrive);
485 floppyDriveTemp->Release();
486 }
487 floppyColl->Release();
488 } else
489 {
490 RTPrintf("Could not get host floppy drive collection\n");
491 }
492 host->Release();
493 } else
494 {
495 RTPrintf("Call failed\n");
496 }
497 RTPrintf("\n");
498#endif
499
500#if 0
501 // IVirtualBoxErrorInfo test
502 ////////////////////////////////////////////////////////////////////////////
503 {
504 // RPC calls
505
506 // call a method that will definitely fail
507 Guid uuid;
508 ComPtr<IHardDisk> hardDisk;
509 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
510 RTPrintf("virtualBox->GetHardDisk(null-uuid)=%08X\n", rc);
511
512// {
513// com::ErrorInfo info(virtualBox);
514// PRINT_ERROR_INFO(info);
515// }
516
517 // call a method that will definitely succeed
518 Bstr version;
519 rc = virtualBox->COMGETTER(Version)(version.asOutParam());
520 RTPrintf("virtualBox->COMGETTER(Version)=%08X\n", rc);
521
522 {
523 com::ErrorInfo info(virtualBox);
524 PRINT_ERROR_INFO(info);
525 }
526
527 // Local calls
528
529 // call a method that will definitely fail
530 ComPtr<IMachine> machine;
531 rc = session->COMGETTER(Machine)(machine.asOutParam());
532 RTPrintf("session->COMGETTER(Machine)=%08X\n", rc);
533
534// {
535// com::ErrorInfo info(virtualBox);
536// PRINT_ERROR_INFO(info);
537// }
538
539 // call a method that will definitely succeed
540 SessionState_T state;
541 rc = session->COMGETTER(State)(&state);
542 RTPrintf("session->COMGETTER(State)=%08X\n", rc);
543
544 {
545 com::ErrorInfo info(virtualBox);
546 PRINT_ERROR_INFO(info);
547 }
548 }
549#endif
550
551#if 0
552 // register the existing hard disk image
553 ///////////////////////////////////////////////////////////////////////////
554 do
555 {
556 ComPtr<IHardDisk> hd;
557 Bstr src = L"E:\\develop\\innotek\\images\\NewHardDisk.vdi";
558 RTPrintf("Opening the existing hard disk '%ls'...\n", src.raw());
559 CHECK_ERROR_BREAK(virtualBox, OpenHardDisk(src, AccessMode_ReadWrite, hd.asOutParam()));
560 RTPrintf("Enter to continue...\n");
561 getchar();
562 RTPrintf("Registering the existing hard disk '%ls'...\n", src.raw());
563 CHECK_ERROR_BREAK(virtualBox, RegisterHardDisk(hd));
564 RTPrintf("Enter to continue...\n");
565 getchar();
566 }
567 while (FALSE);
568 RTPrintf("\n");
569#endif
570
571#if 0
572 // find and unregister the existing hard disk image
573 ///////////////////////////////////////////////////////////////////////////
574 do
575 {
576 ComPtr<IVirtualDiskImage> vdi;
577 Bstr src = L"CreatorTest.vdi";
578 RTPrintf("Unregistering the hard disk '%ls'...\n", src.raw());
579 CHECK_ERROR_BREAK(virtualBox, FindVirtualDiskImage(src, vdi.asOutParam()));
580 ComPtr<IHardDisk> hd = vdi;
581 Guid id;
582 CHECK_ERROR_BREAK(hd, COMGETTER(Id)(id.asOutParam()));
583 CHECK_ERROR_BREAK(virtualBox, UnregisterHardDisk(id, hd.asOutParam()));
584 }
585 while (FALSE);
586 RTPrintf("\n");
587#endif
588
589#if 0
590 // clone the registered hard disk
591 ///////////////////////////////////////////////////////////////////////////
592 do
593 {
594#if defined RT_OS_LINUX
595 Bstr src = L"/mnt/hugaida/common/develop/innotek/images/freedos-linux.vdi";
596#else
597 Bstr src = L"E:/develop/innotek/images/freedos.vdi";
598#endif
599 Bstr dst = L"./clone.vdi";
600 RTPrintf("Cloning '%ls' to '%ls'...\n", src.raw(), dst.raw());
601 ComPtr<IVirtualDiskImage> vdi;
602 CHECK_ERROR_BREAK(virtualBox, FindVirtualDiskImage(src, vdi.asOutParam()));
603 ComPtr<IHardDisk> hd = vdi;
604 ComPtr<IProgress> progress;
605 CHECK_ERROR_BREAK(hd, CloneToImage(dst, vdi.asOutParam(), progress.asOutParam()));
606 RTPrintf("Waiting for completion...\n");
607 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
608 ProgressErrorInfo ei(progress);
609 if (FAILED(ei.getResultCode()))
610 {
611 PRINT_ERROR_INFO(ei);
612 }
613 else
614 {
615 vdi->COMGETTER(FilePath)(dst.asOutParam());
616 RTPrintf("Actual clone path is '%ls'\n", dst.raw());
617 }
618 }
619 while (FALSE);
620 RTPrintf("\n");
621#endif
622
623#if 0
624 // find a registered hard disk by location and get properties
625 ///////////////////////////////////////////////////////////////////////////
626 do
627 {
628 ComPtr<IHardDisk> hd;
629 static const wchar_t *Names[] =
630 {
631#ifndef RT_OS_LINUX
632 L"freedos.vdi",
633 L"MS-DOS.vmdk",
634 L"iscsi",
635 L"some/path/and/disk.vdi",
636#else
637 L"xp.vdi",
638 L"Xp.vDI",
639#endif
640 };
641
642 RTPrintf("\n");
643
644 for (size_t i = 0; i < RT_ELEMENTS(Names); ++ i)
645 {
646 Bstr src = Names[i];
647 RTPrintf("Searching for hard disk '%ls'...\n", src.raw());
648 rc = virtualBox->FindHardDisk(src, hd.asOutParam());
649 if (SUCCEEDED(rc))
650 {
651 Guid id;
652 Bstr location;
653 CHECK_ERROR_BREAK(hd, COMGETTER(Id)(id.asOutParam()));
654 CHECK_ERROR_BREAK(hd, COMGETTER(Location)(location.asOutParam()));
655 RTPrintf("Found, UUID={%RTuuid}, location='%ls'.\n",
656 id.raw(), location.raw());
657
658 com::SafeArray<BSTR> names;
659 com::SafeArray<BSTR> values;
660
661 CHECK_ERROR_BREAK(hd, GetProperties(NULL,
662 ComSafeArrayAsOutParam(names),
663 ComSafeArrayAsOutParam(values)));
664
665 RTPrintf("Properties:\n");
666 for (size_t i = 0; i < names.size(); ++ i)
667 RTPrintf(" %ls = %ls\n", names[i], values[i]);
668
669 if (names.size() == 0)
670 RTPrintf(" <none>\n");
671
672#if 0
673 Bstr name("TargetAddress");
674 Bstr value = Utf8StrFmt("lalala (%llu)", RTTimeMilliTS());
675
676 RTPrintf("Settings property %ls to %ls...\n", name.raw(), value.raw());
677 CHECK_ERROR(hd, SetProperty(name, value));
678#endif
679 }
680 else
681 {
682 com::ErrorInfo info(virtualBox);
683 PRINT_ERROR_INFO(info);
684 }
685 RTPrintf("\n");
686 }
687 }
688 while (FALSE);
689 RTPrintf("\n");
690#endif
691
692#if 0
693 // access the machine in read-only mode
694 ///////////////////////////////////////////////////////////////////////////
695 do
696 {
697 ComPtr<IMachine> machine;
698 Bstr name = argc > 1 ? argv[1] : "dos";
699 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
700 CHECK_ERROR_BREAK(virtualBox, FindMachine(name, machine.asOutParam()));
701 RTPrintf("Accessing the machine in read-only mode:\n");
702 readAndChangeMachineSettings(machine);
703#if 0
704 if (argc != 2)
705 {
706 RTPrintf("Error: a string has to be supplied!\n");
707 }
708 else
709 {
710 Bstr secureLabel = argv[1];
711 machine->COMSETTER(ExtraData)(L"VBoxSDL/SecureLabel", secureLabel);
712 }
713#endif
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
1136#if 0
1137 Bstr extraDataKey = "VBoxSDL/SecureLabel";
1138 Bstr extraData = "Das kommt jetzt noch viel krasser vom total konkreten API!";
1139 CHECK_RC(sessionMachine->SetExtraData(extraDataKey, extraData));
1140#endif
1141#if 0
1142 ComPtr<IConsole> console;
1143 RTPrintf("Getting console object...\n");
1144 CHECK_RC_BREAK(session->COMGETTER(Console)(console.asOutParam()));
1145 RTPrintf("Press enter to pause the VM execution in the remote session...");
1146 getchar();
1147 CHECK_RC(console->Pause());
1148 RTPrintf("Press enter to close this session...");
1149 getchar();
1150#endif
1151 session->Close();
1152 }
1153 while (FALSE);
1154 RTPrintf("\n");
1155#endif
1156
1157#if 1
1158 do {
1159 // Get host
1160 ComPtr<IHost> host;
1161 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1162
1163 ULONG uMemSize, uMemAvail;
1164 CHECK_ERROR_BREAK(host, COMGETTER(MemorySize)(&uMemSize));
1165 RTPrintf("Total memory (MB): %u\n", uMemSize);
1166 CHECK_ERROR_BREAK(host, COMGETTER(MemoryAvailable)(&uMemAvail));
1167 RTPrintf("Free memory (MB): %u\n", uMemAvail);
1168 } while (0);
1169#endif
1170
1171#if 0
1172 do {
1173 // Get host
1174 ComPtr<IHost> host;
1175 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1176
1177 com::SafeIfaceArray<IHostNetworkInterface> hostNetworkInterfaces;
1178 CHECK_ERROR_BREAK(host,
1179 COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(hostNetworkInterfaces)));
1180 if (hostNetworkInterfaces.size() > 0)
1181 {
1182 ComPtr<IHostNetworkInterface> networkInterface = hostNetworkInterfaces[0];
1183 Bstr interfaceName;
1184 networkInterface->COMGETTER(Name)(interfaceName.asOutParam());
1185 RTPrintf("Found %d network interfaces, testing with %ls...\n", hostNetworkInterfaces.size(), interfaceName.raw());
1186 Bstr interfaceGuid;
1187 networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam());
1188 // Find the interface by its name
1189 networkInterface.setNull();
1190 CHECK_ERROR_BREAK(host,
1191 FindHostNetworkInterfaceByName(interfaceName.raw(), networkInterface.asOutParam()));
1192 Bstr interfaceGuid2;
1193 networkInterface->COMGETTER(Id)(interfaceGuid2.asOutParam());
1194 if (interfaceGuid2 != interfaceGuid)
1195 RTPrintf("Failed to retrieve an interface by name %ls.\n", interfaceName.raw());
1196 // Find the interface by its guid
1197 networkInterface.setNull();
1198 CHECK_ERROR_BREAK(host,
1199 FindHostNetworkInterfaceById(interfaceGuid.raw(), networkInterface.asOutParam()));
1200 Bstr interfaceName2;
1201 networkInterface->COMGETTER(Name)(interfaceName2.asOutParam());
1202 if (interfaceName != interfaceName2)
1203 RTPrintf("Failed to retrieve an interface by GUID %ls.\n", interfaceGuid.raw());
1204 }
1205 else
1206 {
1207 RTPrintf("No network interfaces found!\n");
1208 }
1209 } while (0);
1210#endif
1211
1212#if 0
1213 // DNS & Co.
1214 ///////////////////////////////////////////////////////////////////////////
1215 /* XXX: Note it's endless loop */
1216 do
1217 {
1218 ComPtr<IHost> host;
1219 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1220
1221 {
1222 Bstr domainName;
1223 CHECK_ERROR_BREAK(host,COMGETTER(DomainName)(domainName.asOutParam()));
1224 RTPrintf("Domain name: %ls\n", domainName.raw());
1225 }
1226
1227 com::SafeArray<BSTR> strs;
1228 CHECK_ERROR_BREAK(host, COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs)));
1229
1230 unsigned int i;
1231 for (i = 0; i < strs.size(); ++i)
1232 RTPrintf("Name server[%d]:%s\n", i, com::Utf8Str(strs[i]).c_str());
1233
1234 RTThreadSleep(1000);
1235 }
1236 while (1);
1237 RTPrintf("\n");
1238#endif
1239
1240
1241#if 0 && defined(VBOX_WITH_RESOURCE_USAGE_API)
1242 do {
1243 // Get collector
1244 ComPtr<IPerformanceCollector> collector;
1245 CHECK_ERROR_BREAK(virtualBox,
1246 COMGETTER(PerformanceCollector)(collector.asOutParam()));
1247
1248
1249 // Fill base metrics array
1250 Bstr baseMetricNames[] = { L"Net/eth0/Load" };
1251 com::SafeArray<BSTR> baseMetrics(1);
1252 baseMetricNames[0].cloneTo(&baseMetrics[0]);
1253
1254 // Get host
1255 ComPtr<IHost> host;
1256 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1257
1258 // Get host network interfaces
1259 // com::SafeIfaceArray<IHostNetworkInterface> hostNetworkInterfaces;
1260 // CHECK_ERROR_BREAK(host,
1261 // COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(hostNetworkInterfaces)));
1262
1263 // Setup base metrics
1264 // Note that one needs to set up metrics after a session is open for a machine.
1265 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
1266 com::SafeIfaceArray<IUnknown> objects(1);
1267 host.queryInterfaceTo(&objects[0]);
1268 CHECK_ERROR_BREAK(collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
1269 ComSafeArrayAsInParam(objects), 1u, 10u,
1270 ComSafeArrayAsOutParam(affectedMetrics)));
1271 listAffectedMetrics(virtualBox,
1272 ComSafeArrayAsInParam(affectedMetrics));
1273 affectedMetrics.setNull();
1274
1275 RTPrintf("Sleeping for 5 seconds...\n");
1276 RTThreadSleep(5000); // Sleep for 5 seconds
1277
1278 RTPrintf("\nMetrics collected: --------------------\n");
1279 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1280 } while (false);
1281#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1282#if 0 && defined(VBOX_WITH_RESOURCE_USAGE_API)
1283 do {
1284 // Get collector
1285 ComPtr<IPerformanceCollector> collector;
1286 CHECK_ERROR_BREAK(virtualBox,
1287 COMGETTER(PerformanceCollector)(collector.asOutParam()));
1288
1289
1290 // Fill base metrics array
1291 //Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" };
1292 Bstr baseMetricNames[] = { L"RAM/VMM" };
1293 com::SafeArray<BSTR> baseMetrics(1);
1294 baseMetricNames[0].cloneTo(&baseMetrics[0]);
1295
1296 // Get host
1297 ComPtr<IHost> host;
1298 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
1299
1300 // Get machine
1301 ComPtr<IMachine> machine;
1302 Bstr name = argc > 1 ? argv[1] : "dsl";
1303 Bstr sessionType = argc > 2 ? argv[2] : "headless";
1304 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1305 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
1306
1307 // Open session
1308 ComPtr<IProgress> progress;
1309 RTPrintf("Launching VM process...\n");
1310 CHECK_ERROR_BREAK(machine, LaunchVMProcess(session, sessionType.raw(),
1311 NULL, progress.asOutParam()));
1312 RTPrintf("Waiting for the VM to power on...\n");
1313 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
1314
1315 // ComPtr<IMachine> sessionMachine;
1316 // RTPrintf("Getting machine session object...\n");
1317 // CHECK_ERROR_BREAK(session, COMGETTER(Machine)(sessionMachine.asOutParam()));
1318
1319 // Setup base metrics
1320 // Note that one needs to set up metrics after a session is open for a machine.
1321 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
1322 com::SafeIfaceArray<IUnknown> objects(1);
1323 host.queryInterfaceTo(&objects[0]);
1324 //machine.queryInterfaceTo(&objects[1]);
1325 CHECK_ERROR_BREAK(collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
1326 ComSafeArrayAsInParam(objects), 1u, 10u,
1327 ComSafeArrayAsOutParam(affectedMetrics)));
1328 listAffectedMetrics(virtualBox,
1329 ComSafeArrayAsInParam(affectedMetrics));
1330 affectedMetrics.setNull();
1331
1332 // Get console
1333 ComPtr<IConsole> console;
1334 RTPrintf("Getting console object...\n");
1335 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
1336
1337 RTThreadSleep(5000); // Sleep for 5 seconds
1338
1339 RTPrintf("\nMetrics collected with VM running: --------------------\n");
1340 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1341
1342 // Pause
1343 //RTPrintf("Press enter to pause the VM execution in the remote session...");
1344 //getchar();
1345 CHECK_ERROR_BREAK(console, Pause());
1346
1347 RTThreadSleep(5000); // Sleep for 5 seconds
1348
1349 RTPrintf("\nMetrics collected with VM paused: ---------------------\n");
1350 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1351
1352 RTPrintf("\nDrop collected metrics: ----------------------------------------\n");
1353 CHECK_ERROR_BREAK(collector,
1354 SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
1355 ComSafeArrayAsInParam(objects),
1356 1u, 5u, ComSafeArrayAsOutParam(affectedMetrics)));
1357 listAffectedMetrics(virtualBox,
1358 ComSafeArrayAsInParam(affectedMetrics));
1359 affectedMetrics.setNull();
1360 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1361
1362 com::SafeIfaceArray<IUnknown> vmObject(1);
1363 machine.queryInterfaceTo(&vmObject[0]);
1364
1365 RTPrintf("\nDisable collection of VM metrics: ------------------------------\n");
1366 CHECK_ERROR_BREAK(collector,
1367 DisableMetrics(ComSafeArrayAsInParam(baseMetrics),
1368 ComSafeArrayAsInParam(vmObject),
1369 ComSafeArrayAsOutParam(affectedMetrics)));
1370 listAffectedMetrics(virtualBox,
1371 ComSafeArrayAsInParam(affectedMetrics));
1372 affectedMetrics.setNull();
1373 RTThreadSleep(5000); // Sleep for 5 seconds
1374 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1375
1376 RTPrintf("\nRe-enable collection of all metrics: ---------------------------\n");
1377 CHECK_ERROR_BREAK(collector,
1378 EnableMetrics(ComSafeArrayAsInParam(baseMetrics),
1379 ComSafeArrayAsInParam(objects),
1380 ComSafeArrayAsOutParam(affectedMetrics)));
1381 listAffectedMetrics(virtualBox,
1382 ComSafeArrayAsInParam(affectedMetrics));
1383 affectedMetrics.setNull();
1384 RTThreadSleep(5000); // Sleep for 5 seconds
1385 queryMetrics(virtualBox, collector, ComSafeArrayAsInParam(objects));
1386
1387 // Power off
1388 RTPrintf("Press enter to power off VM...");
1389 getchar();
1390 CHECK_ERROR_BREAK(console, PowerDown(progress.asOutParam()));
1391 RTPrintf("Waiting for the VM to power down...\n");
1392 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1));
1393 RTPrintf("Press enter to close this session...");
1394 getchar();
1395 session->UnlockMachine();
1396 } while (false);
1397#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1398#if 0
1399 // check of OVF appliance handling
1400 ///////////////////////////////////////////////////////////////////////////
1401 do
1402 {
1403 Bstr ovf = argc > 1 ? argv[1] : "someOVF.ovf";
1404 RTPrintf("Try to open %ls ...\n", ovf.raw());
1405
1406 ComPtr<IAppliance> appliance;
1407 CHECK_ERROR_BREAK(virtualBox,
1408 CreateAppliance(appliance.asOutParam()));
1409 CHECK_ERROR_BREAK(appliance, Read(ovf));
1410 Bstr path;
1411 CHECK_ERROR_BREAK(appliance, COMGETTER(Path)(path.asOutParam()));
1412 RTPrintf("Successfully opened %ls.\n", path.raw());
1413 CHECK_ERROR_BREAK(appliance, Interpret());
1414 RTPrintf("Successfully interpreted %ls.\n", path.raw());
1415 RTPrintf("Appliance:\n");
1416 // Fetch all disks
1417 com::SafeArray<BSTR> retDisks;
1418 CHECK_ERROR_BREAK(appliance,
1419 COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks)));
1420 if (retDisks.size() > 0)
1421 {
1422 RTPrintf("Disks:");
1423 for (unsigned i = 0; i < retDisks.size(); i++)
1424 RTPrintf(" %ls", Bstr(retDisks[i]).raw());
1425 RTPrintf("\n");
1426 }
1427 /* Fetch all virtual system descriptions */
1428 com::SafeIfaceArray<IVirtualSystemDescription> retVSD;
1429 CHECK_ERROR_BREAK(appliance,
1430 COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(retVSD)));
1431 if (retVSD.size() > 0)
1432 {
1433 for (unsigned i = 0; i < retVSD.size(); ++i)
1434 {
1435 com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
1436 com::SafeArray<BSTR> retRefValues;
1437 com::SafeArray<BSTR> retOrigValues;
1438 com::SafeArray<BSTR> retAutoValues;
1439 com::SafeArray<BSTR> retConfiguration;
1440 CHECK_ERROR_BREAK(retVSD[i],
1441 GetDescription(ComSafeArrayAsOutParam(retTypes),
1442 ComSafeArrayAsOutParam(retRefValues),
1443 ComSafeArrayAsOutParam(retOrigValues),
1444 ComSafeArrayAsOutParam(retAutoValues),
1445 ComSafeArrayAsOutParam(retConfiguration)));
1446
1447 RTPrintf("VirtualSystemDescription:\n");
1448 for (unsigned a = 0; a < retTypes.size(); ++a)
1449 {
1450 RTPrintf(" %d %ls %ls %ls\n",
1451 retTypes[a],
1452 Bstr(retOrigValues[a]).raw(),
1453 Bstr(retAutoValues[a]).raw(),
1454 Bstr(retConfiguration[a]).raw());
1455 }
1456 /* Show warnings from interpret */
1457 com::SafeArray<BSTR> retWarnings;
1458 CHECK_ERROR_BREAK(retVSD[i],
1459 GetWarnings(ComSafeArrayAsOutParam(retWarnings)));
1460 if (retWarnings.size() > 0)
1461 {
1462 RTPrintf("The following warnings occurs on interpret:\n");
1463 for (unsigned r = 0; r < retWarnings.size(); ++r)
1464 RTPrintf("%ls\n", Bstr(retWarnings[r]).raw());
1465 RTPrintf("\n");
1466 }
1467 }
1468 RTPrintf("\n");
1469 }
1470 RTPrintf("Try to import the appliance ...\n");
1471 ComPtr<IProgress> progress;
1472 CHECK_ERROR_BREAK(appliance,
1473 ImportMachines(progress.asOutParam()));
1474 CHECK_ERROR(progress, WaitForCompletion(-1));
1475 if (SUCCEEDED(rc))
1476 {
1477 /* Check if the import was successfully */
1478 progress->COMGETTER(ResultCode)(&rc);
1479 if (FAILED(rc))
1480 {
1481 com::ProgressErrorInfo info(progress);
1482 if (info.isBasicAvailable())
1483 RTPrintf("Error: failed to import appliance. Error message: %ls\n", info.getText().raw());
1484 else
1485 RTPrintf("Error: failed to import appliance. No error message available!\n");
1486 }
1487 else
1488 RTPrintf("Successfully imported the appliance.\n");
1489 }
1490
1491 }
1492 while (FALSE);
1493 RTPrintf("\n");
1494#endif
1495#if 0
1496 // check of network bandwidth control
1497 ///////////////////////////////////////////////////////////////////////////
1498 do
1499 {
1500 Bstr name = argc > 1 ? argv[1] : "ubuntu";
1501 Bstr sessionType = argc > 2 ? argv[2] : "headless";
1502 Bstr grpName = "tstAPI";
1503 {
1504 // Get machine
1505 ComPtr<IMachine> machine;
1506 ComPtr<IBandwidthControl> bwCtrl;
1507 ComPtr<IBandwidthGroup> bwGroup;
1508 ComPtr<INetworkAdapter> nic;
1509 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1510 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
1511 /* open a session for the VM (new or shared) */
1512 CHECK_ERROR_BREAK(machine, LockMachine(session, LockType_Shared));
1513 SessionType_T st;
1514 CHECK_ERROR_BREAK(session, COMGETTER(Type)(&st));
1515 bool fRunTime = (st == SessionType_Shared);
1516 if (fRunTime)
1517 {
1518 RTPrintf("Machine %ls must not be running!\n");
1519 break;
1520 }
1521 /* get the mutable session machine */
1522 session->COMGETTER(Machine)(machine.asOutParam());
1523 CHECK_ERROR_BREAK(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
1524
1525 RTPrintf("Creating bandwidth group named '%ls'...\n", grpName.raw());
1526 CHECK_ERROR_BREAK(bwCtrl, CreateBandwidthGroup(grpName.raw(), BandwidthGroupType_Network, 123));
1527
1528
1529 CHECK_ERROR_BREAK(bwCtrl, GetBandwidthGroup(grpName.raw(), bwGroup.asOutParam()));
1530 CHECK_ERROR_BREAK(machine, GetNetworkAdapter(0, nic.asOutParam()));
1531 RTPrintf("Assigning the group to the first network adapter...\n");
1532 CHECK_ERROR_BREAK(nic, COMSETTER(BandwidthGroup)(bwGroup));
1533 CHECK_ERROR_BREAK(machine, SaveSettings());
1534 RTPrintf("Press enter to close this session...");
1535 getchar();
1536 session->UnlockMachine();
1537 }
1538 {
1539 // Get machine
1540 ComPtr<IMachine> machine;
1541 ComPtr<IBandwidthControl> bwCtrl;
1542 ComPtr<IBandwidthGroup> bwGroup;
1543 Bstr grpNameReadFromNic;
1544 ComPtr<INetworkAdapter> nic;
1545 RTPrintf("Getting a machine object named '%ls'...\n", name.raw());
1546 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam()));
1547 /* open a session for the VM (new or shared) */
1548 CHECK_ERROR_BREAK(machine, LockMachine(session, LockType_Shared));
1549 /* get the mutable session machine */
1550 session->COMGETTER(Machine)(machine.asOutParam());
1551 CHECK_ERROR_BREAK(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
1552 CHECK_ERROR_BREAK(machine, GetNetworkAdapter(0, nic.asOutParam()));
1553
1554 RTPrintf("Reading the group back from the first network adapter...\n");
1555 CHECK_ERROR_BREAK(nic, COMGETTER(BandwidthGroup)(bwGroup.asOutParam()));
1556 if (bwGroup.isNull())
1557 RTPrintf("Error: Bandwidth group is null at the first network adapter!\n");
1558 else
1559 {
1560 CHECK_ERROR_BREAK(bwGroup, COMGETTER(Name)(grpNameReadFromNic.asOutParam()));
1561 if (grpName != grpNameReadFromNic)
1562 RTPrintf("Error: Bandwidth group names do not match (%ls != %ls)!\n", grpName.raw(), grpNameReadFromNic.raw());
1563 else
1564 RTPrintf("Successfully retrieved bandwidth group attribute from NIC (name=%ls)\n", grpNameReadFromNic.raw());
1565 ComPtr<IBandwidthGroup> bwGroupEmpty;
1566 RTPrintf("Assigning an empty group to the first network adapter...\n");
1567 CHECK_ERROR_BREAK(nic, COMSETTER(BandwidthGroup)(bwGroupEmpty));
1568 }
1569 RTPrintf("Removing bandwidth group named '%ls'...\n", grpName.raw());
1570 CHECK_ERROR_BREAK(bwCtrl, DeleteBandwidthGroup(grpName.raw()));
1571 CHECK_ERROR_BREAK(machine, SaveSettings());
1572 RTPrintf("Press enter to close this session...");
1573 getchar();
1574 session->UnlockMachine();
1575 }
1576 } while (FALSE);
1577 RTPrintf("\n");
1578#endif
1579
1580 RTPrintf("Press enter to release Session and VirtualBox instances...");
1581 getchar();
1582
1583 // end "all-stuff" scope
1584 ////////////////////////////////////////////////////////////////////////////
1585 }
1586 while (0);
1587
1588 RTPrintf("Press enter to shutdown COM...");
1589 getchar();
1590
1591 com::Shutdown();
1592
1593 RTPrintf("tstAPI FINISHED.\n");
1594
1595 return rc;
1596}
1597
1598#ifdef VBOX_WITH_RESOURCE_USAGE_API
1599
1600static void queryMetrics(ComPtr<IVirtualBox> aVirtualBox,
1601 ComPtr<IPerformanceCollector> collector,
1602 ComSafeArrayIn(IUnknown *, objects))
1603{
1604 HRESULT rc;
1605
1606 //Bstr metricNames[] = { L"CPU/Load/User:avg,CPU/Load/System:avg,CPU/Load/Idle:avg,RAM/Usage/Total,RAM/Usage/Used:avg" };
1607 Bstr metricNames[] = { L"*" };
1608 com::SafeArray<BSTR> metrics(1);
1609 metricNames[0].cloneTo(&metrics[0]);
1610 com::SafeArray<BSTR> retNames;
1611 com::SafeIfaceArray<IUnknown> retObjects;
1612 com::SafeArray<BSTR> retUnits;
1613 com::SafeArray<ULONG> retScales;
1614 com::SafeArray<ULONG> retSequenceNumbers;
1615 com::SafeArray<ULONG> retIndices;
1616 com::SafeArray<ULONG> retLengths;
1617 com::SafeArray<LONG> retData;
1618 CHECK_ERROR(collector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
1619 ComSafeArrayInArg(objects),
1620 ComSafeArrayAsOutParam(retNames),
1621 ComSafeArrayAsOutParam(retObjects),
1622 ComSafeArrayAsOutParam(retUnits),
1623 ComSafeArrayAsOutParam(retScales),
1624 ComSafeArrayAsOutParam(retSequenceNumbers),
1625 ComSafeArrayAsOutParam(retIndices),
1626 ComSafeArrayAsOutParam(retLengths),
1627 ComSafeArrayAsOutParam(retData)));
1628 RTPrintf("Object Metric Values\n"
1629 "---------- -------------------- --------------------------------------------\n");
1630 for (unsigned i = 0; i < retNames.size(); i++)
1631 {
1632 Bstr metricUnit(retUnits[i]);
1633 Bstr metricName(retNames[i]);
1634 RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
1635 const char *separator = "";
1636 for (unsigned j = 0; j < retLengths[i]; j++)
1637 {
1638 if (retScales[i] == 1)
1639 RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
1640 else
1641 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
1642 (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
1643 separator = ", ";
1644 }
1645 RTPrintf("\n");
1646 }
1647}
1648
1649static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox,
1650 ComPtr<IUnknown> aObject)
1651{
1652 HRESULT rc;
1653
1654 ComPtr<IHost> host = aObject;
1655 if (!host.isNull())
1656 return Bstr("host");
1657
1658 ComPtr<IMachine> machine = aObject;
1659 if (!machine.isNull())
1660 {
1661 Bstr name;
1662 CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
1663 if (SUCCEEDED(rc))
1664 return name;
1665 }
1666 return Bstr("unknown");
1667}
1668
1669static void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
1670 ComSafeArrayIn(IPerformanceMetric*, aMetrics))
1671{
1672 HRESULT rc;
1673 com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
1674 if (metrics.size())
1675 {
1676 ComPtr<IUnknown> object;
1677 Bstr metricName;
1678 RTPrintf("The following metrics were modified:\n\n"
1679 "Object Metric\n"
1680 "---------- --------------------\n");
1681 for (size_t i = 0; i < metrics.size(); i++)
1682 {
1683 CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
1684 CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
1685 RTPrintf("%-10ls %-20ls\n",
1686 getObjectName(aVirtualBox, object).raw(), metricName.raw());
1687 }
1688 RTPrintf("\n");
1689 }
1690 else
1691 {
1692 RTPrintf("No metrics match the specified filter!\n");
1693 }
1694}
1695
1696#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1697/* 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