VirtualBox

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

Last change on this file since 98302 was 98302, checked in by vboxsync, 16 months ago

FE/SDL. bugref:9449. Removing secure label related code.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use