VirtualBox

source: vbox/trunk/src/VBox/Main/cbinding/tstXPCOMCCall.c@ 23585

Last change on this file since 23585 was 23330, checked in by vboxsync, 15 years ago

tstXPCOMCCall: change for recent IConsoleCallback change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1/* $Revision: 23330 $ */
2/** @file tstXPCOMCGlue.c
3 * Demonstrator program to illustrate use of C bindings of Main API.
4 *
5 * Linux only at the moment due to shared library magic in the Makefile.
6 */
7
8/*
9 * Copyright (C) 2009 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include "VBoxXPCOMCGlue.h"
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <signal.h>
33#include <sys/poll.h>
34
35/*******************************************************************************
36* Internal Functions *
37*******************************************************************************/
38static void listVMs(IVirtualBox *virtualBox, ISession *session, nsIEventQueue *queue);
39static void registerCallBack(IVirtualBox *virtualBox, ISession *session, PRUnichar *machineId, nsIEventQueue *queue);
40static void startVM(IVirtualBox *virtualBox, ISession *session, PRUnichar *id, nsIEventQueue *queue);
41
42/*******************************************************************************
43* Global Variables *
44*******************************************************************************/
45/** Set by signal handler. */
46static volatile int g_fStop = 0;
47
48int volatile g_refcount = 0;
49
50/* #define for printing nsID type UUID's */
51
52#define printUUID(iid) \
53{\
54 printf(#iid ": {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",\
55 (unsigned)(iid)->m0,\
56 (unsigned)(iid)->m1,\
57 (unsigned)(iid)->m2,\
58 (unsigned)(iid)->m3[0],\
59 (unsigned)(iid)->m3[1],\
60 (unsigned)(iid)->m3[2],\
61 (unsigned)(iid)->m3[3],\
62 (unsigned)(iid)->m3[4],\
63 (unsigned)(iid)->m3[5],\
64 (unsigned)(iid)->m3[6],\
65 (unsigned)(iid)->m3[7]);\
66}\
67
68/**
69 * Callback functions
70 */
71static const char *GetStateName(PRUint32 machineState)
72{
73 switch (machineState)
74 {
75 case MachineState_Null: return "<null>";
76 case MachineState_PoweredOff: return "PoweredOff";
77 case MachineState_Saved: return "Saved";
78 case MachineState_Aborted: return "Aborted";
79 case MachineState_Running: return "Running";
80 case MachineState_Paused: return "Paused";
81 case MachineState_Stuck: return "Stuck";
82 case MachineState_Starting: return "Starting";
83 case MachineState_Stopping: return "Stopping";
84 case MachineState_Saving: return "Saving";
85 case MachineState_Restoring: return "Restoring";
86 case MachineState_Discarding: return "Discarding";
87 case MachineState_SettingUp: return "SettingUp";
88 default: return "no idea";
89 }
90}
91
92static nsresult OnMousePointerShapeChange(
93 IConsoleCallback *pThis,
94 PRBool visible,
95 PRBool alpha,
96 PRUint32 xHot,
97 PRUint32 yHot,
98 PRUint32 width,
99 PRUint32 height,
100 PRUint8 * shape
101) {
102 printf("OnMousePointerShapeChange\n");
103 return 0;
104}
105
106static nsresult OnMouseCapabilityChange(
107 IConsoleCallback *pThis,
108 PRBool supportsAbsolute,
109 PRBool needsHostCursor
110) {
111 printf("OnMouseCapabilityChange\n");
112 return 0;
113}
114
115static nsresult OnKeyboardLedsChange(
116 IConsoleCallback *pThis,
117 PRBool numLock,
118 PRBool capsLock,
119 PRBool scrollLock
120) {
121 printf("OnMouseCapabilityChange\n");
122 return 0;
123}
124
125static nsresult OnStateChange(
126 IConsoleCallback *pThis,
127 PRUint32 state
128) {
129 printf("OnStateChange: %s\n", GetStateName(state));
130 fflush(stdout);
131 if (state == MachineState_PoweredOff)
132 g_fStop = 1;
133 return 0;
134}
135
136static nsresult OnAdditionsStateChange(IConsoleCallback *pThis )
137{
138 printf("OnAdditionsStateChange\n");
139 return 0;
140}
141
142static nsresult OnNetworkAdapterChange(
143 IConsoleCallback *pThis,
144 INetworkAdapter * networkAdapter
145) {
146 printf("OnNetworkAdapterChange\n");
147 return 0;
148}
149
150static nsresult OnSerialPortChange(
151 IConsoleCallback *pThis,
152 ISerialPort * serialPort
153) {
154 printf("OnSerialPortChange\n");
155 return 0;
156}
157
158static nsresult OnParallelPortChange(
159 IConsoleCallback *pThis,
160 IParallelPort * parallelPort
161) {
162 printf("OnParallelPortChange\n");
163 return 0;
164}
165
166static nsresult OnStorageControllerChange(IConsoleCallback *pThis)
167{
168 printf("OnStorageControllerChange\n");
169 return 0;
170}
171
172static nsresult OnMediumChange(IConsoleCallback *pThis,
173 IMediumAttachment *mediumAttachment)
174{
175 printf("OnMediumChange\n");
176 return 0;
177}
178
179static nsresult OnVRDPServerChange(IConsoleCallback *pThis )
180{
181 printf("OnVRDPServerChange\n");
182 return 0;
183}
184
185static nsresult OnUSBControllerChange(IConsoleCallback *pThis )
186{
187 printf("OnUSBControllerChange\n");
188 return 0;
189}
190
191static nsresult OnUSBDeviceStateChange(
192 IConsoleCallback *pThis,
193 IUSBDevice * device,
194 PRBool attached,
195 IVirtualBoxErrorInfo * error
196) {
197 printf("OnUSBDeviceStateChange\n");
198 return 0;
199}
200
201static nsresult OnSharedFolderChange(
202 IConsoleCallback *pThis,
203 PRUint32 scope
204) {
205 printf("OnSharedFolderChange\n");
206 return 0;
207}
208
209static nsresult OnRuntimeError(
210 IConsoleCallback *pThis,
211 PRBool fatal,
212 PRUnichar * id,
213 PRUnichar * message
214) {
215 printf("OnRuntimeError\n");
216 return 0;
217}
218
219static nsresult OnCanShowWindow(
220 IConsoleCallback *pThis,
221 PRBool * canShow
222) {
223 printf("OnCanShowWindow\n");
224 return 0;
225}
226
227static nsresult OnShowWindow(
228 IConsoleCallback *pThis,
229 PRUint64 * winId
230) {
231 printf("OnShowWindow\n");
232 return 0;
233}
234
235
236static nsresult AddRef(nsISupports *pThis)
237{
238 nsresult c;
239
240 c = ++g_refcount;
241 printf("AddRef: %d\n", c);
242 return c;
243}
244
245static nsresult Release(nsISupports *pThis)
246{
247 nsresult c;
248
249 c = --g_refcount;
250 printf("Release: %d\n", c);
251 if (c == 0)
252 {
253 /* delete object */
254 free(pThis->vtbl);
255 free(pThis);
256 }
257 return c;
258}
259
260static nsresult QueryInterface(nsISupports *pThis, const nsID *iid, void **resultp)
261{
262 static const nsID ivirtualboxCallbackUUID = IVIRTUALBOXCALLBACK_IID;
263 static const nsID isupportIID = NS_ISUPPORTS_IID;
264
265 /* match iid */
266 if ( memcmp(iid, &ivirtualboxCallbackUUID, sizeof(nsID)) == 0
267 || memcmp(iid, &isupportIID, sizeof(nsID)) == 0)
268 {
269 ++g_refcount;
270 printf("QueryInterface: %d\n", g_refcount);
271 *resultp = pThis;
272 return NS_OK;
273 }
274
275 /* printf("vboxCallback QueryInterface didn't find a matching interface\n"); */
276 printUUID(iid);
277 printUUID(&ivirtualboxCallbackUUID);
278 return NS_NOINTERFACE;
279}
280
281/**
282 * Signal callback.
283 *
284 * @param iSig The signal number (ignored).
285 */
286static void sigIntHandler(int iSig)
287{
288 printf("sigIntHandler\n");
289 (void)iSig;
290 g_fStop = 1;
291}
292
293/**
294 * Register callback functions for the selected VM.
295 *
296 * @param virtualBox ptr to IVirtualBox object
297 * @param session ptr to ISession object
298 * @param id identifies the machine to start
299 * @param queue handle to the event queue
300 */
301static void registerCallBack(IVirtualBox *virtualBox, ISession *session, PRUnichar *machineId, nsIEventQueue *queue)
302{
303 IConsole *console = NULL;
304 nsresult rc;
305
306 rc = session->vtbl->GetConsole(session, &console);
307 if ((NS_SUCCEEDED(rc)) && console)
308 {
309 IConsoleCallback *consoleCallback = NULL;
310
311 consoleCallback = calloc(1, sizeof(IConsoleCallback));
312 consoleCallback->vtbl = calloc(1, sizeof(struct IConsoleCallback_vtbl));
313
314 if (consoleCallback && consoleCallback->vtbl)
315 {
316 consoleCallback->vtbl->nsisupports.AddRef = &AddRef;
317 consoleCallback->vtbl->nsisupports.Release = &Release;
318 consoleCallback->vtbl->nsisupports.QueryInterface = &QueryInterface;
319 consoleCallback->vtbl->OnMousePointerShapeChange = &OnMousePointerShapeChange;
320 consoleCallback->vtbl->OnMouseCapabilityChange = &OnMouseCapabilityChange;
321 consoleCallback->vtbl->OnKeyboardLedsChange =&OnKeyboardLedsChange;
322 consoleCallback->vtbl->OnStateChange = &OnStateChange;
323 consoleCallback->vtbl->OnAdditionsStateChange = &OnAdditionsStateChange;
324 consoleCallback->vtbl->OnNetworkAdapterChange = &OnNetworkAdapterChange;
325 consoleCallback->vtbl->OnSerialPortChange = &OnSerialPortChange;
326 consoleCallback->vtbl->OnParallelPortChange = &OnParallelPortChange;
327 consoleCallback->vtbl->OnStorageControllerChange = &OnStorageControllerChange;
328 consoleCallback->vtbl->OnMediumChange = &OnMediumChange;
329 consoleCallback->vtbl->OnVRDPServerChange = &OnVRDPServerChange;
330 consoleCallback->vtbl->OnUSBControllerChange = &OnUSBControllerChange;
331 consoleCallback->vtbl->OnUSBDeviceStateChange = &OnUSBDeviceStateChange;
332 consoleCallback->vtbl->OnSharedFolderChange = &OnSharedFolderChange;
333 consoleCallback->vtbl->OnRuntimeError = &OnRuntimeError;
334 consoleCallback->vtbl->OnCanShowWindow = &OnCanShowWindow;
335 consoleCallback->vtbl->OnShowWindow = &OnShowWindow;
336 g_refcount = 1;
337
338 rc = console->vtbl->RegisterCallback(console, consoleCallback);
339 if (NS_SUCCEEDED(rc))
340 {
341 /* crude way to show how it works, but any
342 * great ideas anyone?
343 */
344 PRInt32 fd;
345 int ret;
346
347 printf("Entering event loop, PowerOff the machine to exit or press Ctrl-C to terminate\n");
348 fflush(stdout);
349 signal(SIGINT, sigIntHandler);
350
351 fd = queue->vtbl->GetEventQueueSelectFD(queue);
352 if (fd >= 0)
353 {
354 while (!g_fStop)
355 {
356 struct pollfd pfd;
357
358 pfd.fd = fd;
359 pfd.events = POLLIN | POLLERR | POLLHUP;
360 pfd.revents = 0;
361
362 ret = poll(&pfd, 1, 250);
363
364 if (ret <= 0)
365 continue;
366
367 if (pfd.revents & POLLHUP)
368 g_fStop = 1;
369
370 queue->vtbl->ProcessPendingEvents(queue);
371 }
372 }
373 else
374 {
375 while (!g_fStop)
376 {
377 PLEvent *pEvent = NULL;
378 rc = queue->vtbl->WaitForEvent(queue, &pEvent);
379 /*printf("event: %p rc=%x\n", (void *)pEvent, rc);*/
380 if (NS_SUCCEEDED(rc))
381 queue->vtbl->HandleEvent(queue, pEvent);
382 }
383 }
384 signal(SIGINT, SIG_DFL);
385 }
386 console->vtbl->UnregisterCallback(console, consoleCallback);
387 consoleCallback->vtbl->nsisupports.Release((nsISupports *)consoleCallback);
388 }
389 else
390 {
391 printf("Failed while allocating memory for console Callback.\n");
392 }
393 }
394}
395
396/**
397 * List the registered VMs.
398 *
399 * @param virtualBox ptr to IVirtualBox object
400 * @param session ptr to ISession object
401 * @param queue handle to the event queue
402 */
403static void listVMs(IVirtualBox *virtualBox, ISession *session, nsIEventQueue *queue)
404{
405 nsresult rc;
406 IMachine **machines = NULL;
407 PRUint32 machineCnt = 0;
408 PRUint32 i;
409 unsigned start_id;
410
411 /*
412 * Get the list of all registered VMs.
413 */
414
415 rc = virtualBox->vtbl->GetMachines(virtualBox, &machineCnt, &machines);
416 if (NS_FAILED(rc))
417 {
418 fprintf(stderr, "could not get list of machines, rc=%08x\n",
419 (unsigned)rc);
420 return;
421 }
422
423 if (machineCnt == 0)
424 {
425 printf("\tNo VMs\n");
426 return;
427 }
428
429 printf("VM List:\n\n");
430
431 /*
432 * Iterate through the collection.
433 */
434
435 for (i = 0; i < machineCnt; ++i)
436 {
437 IMachine *machine = machines[i];
438 PRBool isAccessible = PR_FALSE;
439
440 printf("\tMachine #%u\n", (unsigned)i);
441
442 if (!machine)
443 {
444 printf("\t(skipped, NULL)\n");
445 continue;
446 }
447
448 machine->vtbl->GetAccessible(machine, &isAccessible);
449
450 if (isAccessible)
451 {
452 PRUnichar *machineNameUtf16;
453 char *machineName;
454
455 machine->vtbl->GetName(machine, &machineNameUtf16);
456 g_pVBoxFuncs->pfnUtf16ToUtf8(machineNameUtf16,&machineName);
457 printf("\tName: %s\n", machineName);
458
459 g_pVBoxFuncs->pfnUtf8Free(machineName);
460 g_pVBoxFuncs->pfnComUnallocMem(machineNameUtf16);
461 }
462 else
463 {
464 printf("\tName: <inaccessible>\n");
465 }
466
467 {
468 PRUnichar *uuidUtf16 = NULL;
469 char *uuidUtf8 = NULL;
470
471 machine->vtbl->GetId(machine, &uuidUtf16);
472 g_pVBoxFuncs->pfnUtf16ToUtf8(uuidUtf16, &uuidUtf8);
473 printf("\tUUID: %s\n", uuidUtf8);
474
475 g_pVBoxFuncs->pfnUtf8Free(uuidUtf8);
476 g_pVBoxFuncs->pfnUtf16Free(uuidUtf16);
477 }
478
479 if (isAccessible)
480 {
481 {
482 PRUnichar *configFile;
483 char *configFile1 = calloc((size_t)64, (size_t)1);
484
485 machine->vtbl->GetSettingsFilePath(machine, &configFile);
486 g_pVBoxFuncs->pfnUtf16ToUtf8(configFile, &configFile1);
487 printf("\tConfig file: %s\n", configFile1);
488
489 free(configFile1);
490 g_pVBoxFuncs->pfnComUnallocMem(configFile);
491 }
492
493 {
494 PRUint32 memorySize;
495
496 machine->vtbl->GetMemorySize(machine, &memorySize);
497 printf("\tMemory size: %uMB\n", memorySize);
498 }
499
500 {
501 PRUnichar *typeId;
502 PRUnichar *osNameUtf16;
503 char *osName;
504 IGuestOSType *osType = NULL;
505
506 machine->vtbl->GetOSTypeId(machine, &typeId);
507 virtualBox->vtbl->GetGuestOSType(virtualBox, typeId, &osType);
508 osType->vtbl->GetDescription(osType, &osNameUtf16);
509 g_pVBoxFuncs->pfnUtf16ToUtf8(osNameUtf16,&osName);
510 printf("\tGuest OS: %s\n\n", osName);
511
512 osType->vtbl->nsisupports.Release((void *)osType);
513 g_pVBoxFuncs->pfnUtf8Free(osName);
514 g_pVBoxFuncs->pfnComUnallocMem(osNameUtf16);
515 g_pVBoxFuncs->pfnComUnallocMem(typeId);
516 }
517 }
518 }
519
520 /*
521 * Let the user chose a machine to start.
522 */
523
524 printf("Type Machine# to start (0 - %u) or 'quit' to do nothing: ",
525 (unsigned)(machineCnt - 1));
526 fflush(stdout);
527
528 if (scanf("%u", &start_id) == 1 && start_id < machineCnt)
529 {
530 IMachine *machine = machines[start_id];
531
532 if (machine)
533 {
534 PRUnichar *uuidUtf16 = NULL;
535
536 machine->vtbl->GetId(machine, &uuidUtf16);
537 startVM(virtualBox, session, uuidUtf16, queue);
538
539 g_pVBoxFuncs->pfnUtf16Free(uuidUtf16);
540 }
541 }
542
543 /*
544 * Don't forget to release the objects in the array.
545 */
546
547 for (i = 0; i < machineCnt; ++i)
548 {
549 IMachine *machine = machines[i];
550
551 if (machine)
552 {
553 machine->vtbl->nsisupports.Release((nsISupports *)machine);
554 }
555 }
556}
557
558/**
559 * Start a VM.
560 *
561 * @param virtualBox ptr to IVirtualBox object
562 * @param session ptr to ISession object
563 * @param id identifies the machine to start
564 * @param queue handle to the event queue
565 */
566
567static void startVM(IVirtualBox *virtualBox, ISession *session, PRUnichar *id, nsIEventQueue *queue)
568{
569 nsresult rc;
570 IMachine *machine = NULL;
571 IProgress *progress = NULL;
572 PRUnichar *env = NULL;
573 PRUnichar *sessionType;
574
575 rc = virtualBox->vtbl->GetMachine(virtualBox, id, &machine);
576
577 if (NS_FAILED(rc) || !machine)
578 {
579 fprintf(stderr, "Error: Couldn't get the machine handle.\n");
580 return;
581 }
582
583 g_pVBoxFuncs->pfnUtf8ToUtf16("gui", &sessionType);
584
585 rc = virtualBox->vtbl->OpenRemoteSession(
586 virtualBox,
587 session,
588 id,
589 sessionType,
590 env,
591 &progress
592 );
593
594 g_pVBoxFuncs->pfnUtf16Free(sessionType);
595
596 if (NS_FAILED(rc))
597 {
598 fprintf(stderr, "Error: OpenRemoteSession failed.\n");
599 }
600 else
601 {
602 PRBool completed;
603 PRInt32 resultCode;
604
605 printf("Waiting for the remote session to open...\n");
606 progress->vtbl->WaitForCompletion(progress, -1);
607
608 rc = progress->vtbl->GetCompleted(progress, &completed);
609 if (NS_FAILED(rc))
610 {
611 fprintf (stderr, "Error: GetCompleted status failed.\n");
612 }
613
614 progress->vtbl->GetResultCode(progress, &resultCode);
615 if (NS_FAILED(resultCode))
616 {
617 IVirtualBoxErrorInfo *errorInfo;
618 PRUnichar *textUtf16;
619 char *text;
620
621 progress->vtbl->GetErrorInfo(progress, &errorInfo);
622 errorInfo->vtbl->GetText(errorInfo, &textUtf16);
623 g_pVBoxFuncs->pfnUtf16ToUtf8(textUtf16, &text);
624 printf("Error: %s\n", text);
625
626 g_pVBoxFuncs->pfnComUnallocMem(textUtf16);
627 g_pVBoxFuncs->pfnUtf8Free(text);
628 }
629 else
630 {
631 fprintf(stderr, "Remote session has been successfully opened.\n");
632 registerCallBack(virtualBox, session, id, queue);
633 }
634 progress->vtbl->nsisupports.Release((void *)progress);
635 }
636
637 /* It's important to always release resources. */
638 machine->vtbl->nsisupports.Release((void *)machine);
639}
640
641/* Main - Start the ball rolling. */
642
643int main(int argc, char **argv)
644{
645 IVirtualBox *vbox = NULL;
646 ISession *session = NULL;
647 nsIEventQueue *queue = NULL;
648 PRUint32 revision = 0;
649 PRUnichar *versionUtf16 = NULL;
650 PRUnichar *homefolderUtf16 = NULL;
651 nsresult rc; /* Result code of various function (method) calls. */
652
653 printf("Starting Main\n");
654
655 /*
656 * VBoxComInitialize does all the necessary startup action and
657 * provides us with pointers to vbox and session handles.
658 * It should be matched by a call to VBoxComUninitialize(vbox)
659 * when done.
660 */
661
662 if (VBoxCGlueInit() != 0)
663 {
664 fprintf(stderr, "%s: FATAL: VBoxCGlueInit failed: %s\n",
665 argv[0], g_szVBoxErrMsg);
666 return EXIT_FAILURE;
667 }
668
669 g_pVBoxFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &vbox,
670 ISESSION_IID_STR, &session);
671 if (vbox == NULL)
672 {
673 fprintf(stderr, "%s: FATAL: could not get vbox handle\n", argv[0]);
674 return EXIT_FAILURE;
675 }
676 if (session == NULL)
677 {
678 fprintf(stderr, "%s: FATAL: could not get session handle\n", argv[0]);
679 return EXIT_FAILURE;
680 }
681 g_pVBoxFuncs->pfnGetEventQueue(&queue);
682 printf("Got the event queue: %p\n", (void *)queue);
683
684 /*
685 * Now ask for revision, version and home folder information of
686 * this vbox. Were not using fancy macros here so it
687 * remains easy to see how we access C++'s vtable.
688 */
689
690 printf("----------------------------------------------------\n");
691
692 /* 1. Revision */
693
694 rc = vbox->vtbl->GetRevision(vbox, &revision);
695 if (NS_SUCCEEDED(rc))
696 {
697 printf("\tRevision: %u\n", revision);
698 }
699 else
700 {
701 fprintf(stderr, "%s: GetRevision() returned %08x\n",
702 argv[0], (unsigned)rc);
703 }
704
705 /* 2. Version */
706
707 rc = vbox->vtbl->GetVersion(vbox, &versionUtf16);
708 if (NS_SUCCEEDED(rc))
709 {
710 char *version = NULL;
711 g_pVBoxFuncs->pfnUtf16ToUtf8(versionUtf16, &version);
712 printf("\tVersion: %s\n", version);
713 g_pVBoxFuncs->pfnUtf8Free(version);
714 g_pVBoxFuncs->pfnComUnallocMem(versionUtf16);
715 }
716 else
717 {
718 fprintf(stderr, "%s: GetVersion() returned %08x\n",
719 argv[0], (unsigned)rc);
720 }
721
722 /* 3. Home Folder */
723
724 rc = vbox->vtbl->GetHomeFolder(vbox, &homefolderUtf16);
725 if (NS_SUCCEEDED(rc))
726 {
727 char *homefolder = NULL;
728 g_pVBoxFuncs->pfnUtf16ToUtf8(homefolderUtf16, &homefolder);
729 printf("\tHomeFolder: %s\n", homefolder);
730 g_pVBoxFuncs->pfnUtf8Free(homefolder);
731 g_pVBoxFuncs->pfnComUnallocMem(homefolderUtf16);
732 }
733 else
734 {
735 fprintf(stderr, "%s: GetHomeFolder() returned %08x\n",
736 argv[0], (unsigned)rc);
737 }
738
739 listVMs(vbox, session, queue);
740 session->vtbl->Close(session);
741
742 printf("----------------------------------------------------\n");
743
744 /*
745 * Do as mom told us: always clean up after yourself.
746 */
747
748 g_pVBoxFuncs->pfnComUninitialize();
749 VBoxCGlueTerm();
750 printf("Finished Main\n");
751
752 return 0;
753}
754/* vim: set ts=4 sw=4 et: */
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