VirtualBox

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

Last change on this file since 21835 was 20220, checked in by vboxsync, 16 years ago

Main: back out the IProgess::GetResultCode() parameter change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 KB
Line 
1/* $Revision: 20220 $ */
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 OnDVDDriveChange(IConsoleCallback *pThis )
143{
144 printf("OnDVDDriveChange \n");
145 return 0;
146}
147
148static nsresult OnFloppyDriveChange(IConsoleCallback *pThis )
149{
150 printf("OnFloppyDriveChange \n");
151 return 0;
152}
153
154static nsresult OnNetworkAdapterChange(
155 IConsoleCallback *pThis,
156 INetworkAdapter * networkAdapter
157) {
158 printf("OnNetworkAdapterChange\n");
159 return 0;
160}
161
162static nsresult OnSerialPortChange(
163 IConsoleCallback *pThis,
164 ISerialPort * serialPort
165) {
166 printf("OnSerialPortChange\n");
167 return 0;
168}
169
170static nsresult OnParallelPortChange(
171 IConsoleCallback *pThis,
172 IParallelPort * parallelPort
173) {
174 printf("OnParallelPortChange\n");
175 return 0;
176}
177
178static nsresult OnStorageControllerChange(IConsoleCallback *pThis )
179{
180 printf("OnStorageControllerChange\n");
181 return 0;
182}
183
184static nsresult OnVRDPServerChange(IConsoleCallback *pThis )
185{
186 printf("OnVRDPServerChange\n");
187 return 0;
188}
189
190static nsresult OnUSBControllerChange(IConsoleCallback *pThis )
191{
192 printf("OnUSBControllerChange\n");
193 return 0;
194}
195
196static nsresult OnUSBDeviceStateChange(
197 IConsoleCallback *pThis,
198 IUSBDevice * device,
199 PRBool attached,
200 IVirtualBoxErrorInfo * error
201) {
202 printf("OnUSBDeviceStateChange\n");
203 return 0;
204}
205
206static nsresult OnSharedFolderChange(
207 IConsoleCallback *pThis,
208 PRUint32 scope
209) {
210 printf("OnSharedFolderChange\n");
211 return 0;
212}
213
214static nsresult OnRuntimeError(
215 IConsoleCallback *pThis,
216 PRBool fatal,
217 PRUnichar * id,
218 PRUnichar * message
219) {
220 printf("OnRuntimeError\n");
221 return 0;
222}
223
224static nsresult OnCanShowWindow(
225 IConsoleCallback *pThis,
226 PRBool * canShow
227) {
228 printf("OnCanShowWindow\n");
229 return 0;
230}
231
232static nsresult OnShowWindow(
233 IConsoleCallback *pThis,
234 PRUint64 * winId
235) {
236 printf("OnShowWindow\n");
237 return 0;
238}
239
240
241static nsresult AddRef(nsISupports *pThis)
242{
243 nsresult c;
244
245 c = ++g_refcount;
246 printf("AddRef: %d\n", c);
247 return c;
248}
249
250static nsresult Release(nsISupports *pThis)
251{
252 nsresult c;
253
254 c = --g_refcount;
255 printf("Release: %d\n", c);
256 if (c == 0)
257 {
258 /* delete object */
259 free(pThis->vtbl);
260 free(pThis);
261 }
262 return c;
263}
264
265static nsresult QueryInterface(nsISupports *pThis, const nsID *iid, void **resultp)
266{
267 static const nsID ivirtualboxCallbackUUID = IVIRTUALBOXCALLBACK_IID;
268 static const nsID isupportIID = NS_ISUPPORTS_IID;
269
270 /* match iid */
271 if ( memcmp(iid, &ivirtualboxCallbackUUID, sizeof(nsID)) == 0
272 || memcmp(iid, &isupportIID, sizeof(nsID)) == 0)
273 {
274 ++g_refcount;
275 printf("QueryInterface: %d\n", g_refcount);
276 *resultp = pThis;
277 return NS_OK;
278 }
279
280 /* printf("vboxCallback QueryInterface didn't find a matching interface\n"); */
281 printUUID(iid);
282 printUUID(&ivirtualboxCallbackUUID);
283 return NS_NOINTERFACE;
284}
285
286/**
287 * Signal callback.
288 *
289 * @param iSig The signal number (ignored).
290 */
291static void sigIntHandler(int iSig)
292{
293 printf("sigIntHandler\n");
294 (void)iSig;
295 g_fStop = 1;
296}
297
298/**
299 * Register callback functions for the selected VM.
300 *
301 * @param virtualBox ptr to IVirtualBox object
302 * @param session ptr to ISession object
303 * @param id identifies the machine to start
304 * @param queue handle to the event queue
305 */
306static void registerCallBack(IVirtualBox *virtualBox, ISession *session, PRUnichar *machineId, nsIEventQueue *queue)
307{
308 IConsole *console = NULL;
309 nsresult rc;
310
311 rc = session->vtbl->GetConsole(session, &console);
312 if ((NS_SUCCEEDED(rc)) && console)
313 {
314 IConsoleCallback *consoleCallback = NULL;
315
316 consoleCallback = calloc(1, sizeof(IConsoleCallback));
317 consoleCallback->vtbl = calloc(1, sizeof(struct IConsoleCallback_vtbl));
318
319 if (consoleCallback && consoleCallback->vtbl)
320 {
321 consoleCallback->vtbl->nsisupports.AddRef = &AddRef;
322 consoleCallback->vtbl->nsisupports.Release = &Release;
323 consoleCallback->vtbl->nsisupports.QueryInterface = &QueryInterface;
324 consoleCallback->vtbl->OnMousePointerShapeChange = &OnMousePointerShapeChange;
325 consoleCallback->vtbl->OnMouseCapabilityChange = &OnMouseCapabilityChange;
326 consoleCallback->vtbl->OnKeyboardLedsChange =&OnKeyboardLedsChange;
327 consoleCallback->vtbl->OnStateChange = &OnStateChange;
328 consoleCallback->vtbl->OnAdditionsStateChange = &OnAdditionsStateChange;
329 consoleCallback->vtbl->OnDVDDriveChange = &OnDVDDriveChange;
330 consoleCallback->vtbl->OnFloppyDriveChange = &OnFloppyDriveChange;
331 consoleCallback->vtbl->OnNetworkAdapterChange = &OnNetworkAdapterChange;
332 consoleCallback->vtbl->OnSerialPortChange = &OnSerialPortChange;
333 consoleCallback->vtbl->OnParallelPortChange = &OnParallelPortChange;
334 consoleCallback->vtbl->OnStorageControllerChange = &OnStorageControllerChange;
335 consoleCallback->vtbl->OnVRDPServerChange = &OnVRDPServerChange;
336 consoleCallback->vtbl->OnUSBControllerChange = &OnUSBControllerChange;
337 consoleCallback->vtbl->OnUSBDeviceStateChange = &OnUSBDeviceStateChange;
338 consoleCallback->vtbl->OnSharedFolderChange = &OnSharedFolderChange;
339 consoleCallback->vtbl->OnRuntimeError = &OnRuntimeError;
340 consoleCallback->vtbl->OnCanShowWindow = &OnCanShowWindow;
341 consoleCallback->vtbl->OnShowWindow = &OnShowWindow;
342 g_refcount = 1;
343
344 rc = console->vtbl->RegisterCallback(console, consoleCallback);
345 if (NS_SUCCEEDED(rc))
346 {
347 /* crude way to show how it works, but any
348 * great ideas anyone?
349 */
350 PRInt32 fd;
351 int ret;
352
353 printf("Entering event loop, PowerOff the machine to exit or press Ctrl-C to terminate\n");
354 fflush(stdout);
355 signal(SIGINT, sigIntHandler);
356
357 fd = queue->vtbl->GetEventQueueSelectFD(queue);
358 if (fd >= 0)
359 {
360 while (!g_fStop)
361 {
362 struct pollfd pfd;
363
364 pfd.fd = fd;
365 pfd.events = POLLIN | POLLERR | POLLHUP;
366 pfd.revents = 0;
367
368 ret = poll(&pfd, 1, 250);
369
370 if (ret <= 0)
371 continue;
372
373 if (pfd.revents & POLLHUP)
374 g_fStop = 1;
375
376 queue->vtbl->ProcessPendingEvents(queue);
377 }
378 }
379 else
380 {
381 while (!g_fStop)
382 {
383 PLEvent *pEvent = NULL;
384 rc = queue->vtbl->WaitForEvent(queue, &pEvent);
385 /*printf("event: %p rc=%x\n", (void *)pEvent, rc);*/
386 if (NS_SUCCEEDED(rc))
387 queue->vtbl->HandleEvent(queue, pEvent);
388 }
389 }
390 signal(SIGINT, SIG_DFL);
391 }
392 console->vtbl->UnregisterCallback(console, consoleCallback);
393 consoleCallback->vtbl->nsisupports.Release((nsISupports *)consoleCallback);
394 }
395 else
396 {
397 printf("Failed while allocating memory for console Callback.\n");
398 }
399 }
400}
401
402/**
403 * List the registered VMs.
404 *
405 * @param virtualBox ptr to IVirtualBox object
406 * @param session ptr to ISession object
407 * @param queue handle to the event queue
408 */
409static void listVMs(IVirtualBox *virtualBox, ISession *session, nsIEventQueue *queue)
410{
411 nsresult rc;
412 IMachine **machines = NULL;
413 PRUint32 machineCnt = 0;
414 PRUint32 i;
415 unsigned start_id;
416
417 /*
418 * Get the list of all registered VMs.
419 */
420
421 rc = virtualBox->vtbl->GetMachines(virtualBox, &machineCnt, &machines);
422 if (NS_FAILED(rc))
423 {
424 fprintf(stderr, "could not get list of machines, rc=%08x\n",
425 (unsigned)rc);
426 return;
427 }
428
429 if (machineCnt == 0)
430 {
431 printf("\tNo VMs\n");
432 return;
433 }
434
435 printf("VM List:\n\n");
436
437 /*
438 * Iterate through the collection.
439 */
440
441 for (i = 0; i < machineCnt; ++i)
442 {
443 IMachine *machine = machines[i];
444 PRBool isAccessible = PR_FALSE;
445
446 printf("\tMachine #%u\n", (unsigned)i);
447
448 if (!machine)
449 {
450 printf("\t(skipped, NULL)\n");
451 continue;
452 }
453
454 machine->vtbl->GetAccessible(machine, &isAccessible);
455
456 if (isAccessible)
457 {
458 PRUnichar *machineNameUtf16;
459 char *machineName;
460
461 machine->vtbl->GetName(machine, &machineNameUtf16);
462 g_pVBoxFuncs->pfnUtf16ToUtf8(machineNameUtf16,&machineName);
463 printf("\tName: %s\n", machineName);
464
465 g_pVBoxFuncs->pfnUtf8Free(machineName);
466 g_pVBoxFuncs->pfnComUnallocMem(machineNameUtf16);
467 }
468 else
469 {
470 printf("\tName: <inaccessible>\n");
471 }
472
473 {
474 PRUnichar *uuidUtf16 = NULL;
475 char *uuidUtf8 = NULL;
476
477 machine->vtbl->GetId(machine, &uuidUtf16);
478 g_pVBoxFuncs->pfnUtf16ToUtf8(uuidUtf16, &uuidUtf8);
479 printf("\tUUID: %s\n", uuidUtf8);
480
481 g_pVBoxFuncs->pfnUtf8Free(uuidUtf8);
482 g_pVBoxFuncs->pfnUtf16Free(uuidUtf16);
483 }
484
485 if (isAccessible)
486 {
487 {
488 PRUnichar *configFile;
489 char *configFile1 = calloc((size_t)64, (size_t)1);
490
491 machine->vtbl->GetSettingsFilePath(machine, &configFile);
492 g_pVBoxFuncs->pfnUtf16ToUtf8(configFile, &configFile1);
493 printf("\tConfig file: %s\n", configFile1);
494
495 free(configFile1);
496 g_pVBoxFuncs->pfnComUnallocMem(configFile);
497 }
498
499 {
500 PRUint32 memorySize;
501
502 machine->vtbl->GetMemorySize(machine, &memorySize);
503 printf("\tMemory size: %uMB\n", memorySize);
504 }
505
506 {
507 PRUnichar *typeId;
508 PRUnichar *osNameUtf16;
509 char *osName;
510 IGuestOSType *osType = NULL;
511
512 machine->vtbl->GetOSTypeId(machine, &typeId);
513 virtualBox->vtbl->GetGuestOSType(virtualBox, typeId, &osType);
514 osType->vtbl->GetDescription(osType, &osNameUtf16);
515 g_pVBoxFuncs->pfnUtf16ToUtf8(osNameUtf16,&osName);
516 printf("\tGuest OS: %s\n\n", osName);
517
518 osType->vtbl->nsisupports.Release((void *)osType);
519 g_pVBoxFuncs->pfnUtf8Free(osName);
520 g_pVBoxFuncs->pfnComUnallocMem(osNameUtf16);
521 g_pVBoxFuncs->pfnComUnallocMem(typeId);
522 }
523 }
524 }
525
526 /*
527 * Let the user chose a machine to start.
528 */
529
530 printf("Type Machine# to start (0 - %u) or 'quit' to do nothing: ",
531 (unsigned)(machineCnt - 1));
532 fflush(stdout);
533
534 if (scanf("%u", &start_id) == 1 && start_id < machineCnt)
535 {
536 IMachine *machine = machines[start_id];
537
538 if (machine)
539 {
540 PRUnichar *uuidUtf16 = NULL;
541
542 machine->vtbl->GetId(machine, &uuidUtf16);
543 startVM(virtualBox, session, uuidUtf16, queue);
544
545 g_pVBoxFuncs->pfnUtf16Free(uuidUtf16);
546 }
547 }
548
549 /*
550 * Don't forget to release the objects in the array.
551 */
552
553 for (i = 0; i < machineCnt; ++i)
554 {
555 IMachine *machine = machines[i];
556
557 if (machine)
558 {
559 machine->vtbl->nsisupports.Release((nsISupports *)machine);
560 }
561 }
562}
563
564/**
565 * Start a VM.
566 *
567 * @param virtualBox ptr to IVirtualBox object
568 * @param session ptr to ISession object
569 * @param id identifies the machine to start
570 * @param queue handle to the event queue
571 */
572
573static void startVM(IVirtualBox *virtualBox, ISession *session, PRUnichar *id, nsIEventQueue *queue)
574{
575 nsresult rc;
576 IMachine *machine = NULL;
577 IProgress *progress = NULL;
578 PRUnichar *env = NULL;
579 PRUnichar *sessionType;
580
581 rc = virtualBox->vtbl->GetMachine(virtualBox, id, &machine);
582
583 if (NS_FAILED(rc) || !machine)
584 {
585 fprintf(stderr, "Error: Couldn't get the machine handle.\n");
586 return;
587 }
588
589 g_pVBoxFuncs->pfnUtf8ToUtf16("gui", &sessionType);
590
591 rc = virtualBox->vtbl->OpenRemoteSession(
592 virtualBox,
593 session,
594 id,
595 sessionType,
596 env,
597 &progress
598 );
599
600 g_pVBoxFuncs->pfnUtf16Free(sessionType);
601
602 if (NS_FAILED(rc))
603 {
604 fprintf(stderr, "Error: OpenRemoteSession failed.\n");
605 }
606 else
607 {
608 PRBool completed;
609 PRInt32 resultCode;
610
611 printf("Waiting for the remote session to open...\n");
612 progress->vtbl->WaitForCompletion(progress, -1);
613
614 rc = progress->vtbl->GetCompleted(progress, &completed);
615 if (NS_FAILED(rc))
616 {
617 fprintf (stderr, "Error: GetCompleted status failed.\n");
618 }
619
620 progress->vtbl->GetResultCode(progress, &resultCode);
621 if (NS_FAILED(resultCode))
622 {
623 IVirtualBoxErrorInfo *errorInfo;
624 PRUnichar *textUtf16;
625 char *text;
626
627 progress->vtbl->GetErrorInfo(progress, &errorInfo);
628 errorInfo->vtbl->GetText(errorInfo, &textUtf16);
629 g_pVBoxFuncs->pfnUtf16ToUtf8(textUtf16, &text);
630 printf("Error: %s\n", text);
631
632 g_pVBoxFuncs->pfnComUnallocMem(textUtf16);
633 g_pVBoxFuncs->pfnUtf8Free(text);
634 }
635 else
636 {
637 fprintf(stderr, "Remote session has been successfully opened.\n");
638 registerCallBack(virtualBox, session, id, queue);
639 }
640 progress->vtbl->nsisupports.Release((void *)progress);
641 }
642
643 /* It's important to always release resources. */
644 machine->vtbl->nsisupports.Release((void *)machine);
645}
646
647/* Main - Start the ball rolling. */
648
649int main(int argc, char **argv)
650{
651 IVirtualBox *vbox = NULL;
652 ISession *session = NULL;
653 nsIEventQueue *queue = NULL;
654 PRUint32 revision = 0;
655 PRUnichar *versionUtf16 = NULL;
656 PRUnichar *homefolderUtf16 = NULL;
657 nsresult rc; /* Result code of various function (method) calls. */
658
659 printf("Starting Main\n");
660
661 /*
662 * VBoxComInitialize does all the necessary startup action and
663 * provides us with pointers to vbox and session handles.
664 * It should be matched by a call to VBoxComUninitialize(vbox)
665 * when done.
666 */
667
668 if (VBoxCGlueInit() != 0)
669 {
670 fprintf(stderr, "%s: FATAL: VBoxCGlueInit failed: %s\n",
671 argv[0], g_szVBoxErrMsg);
672 return EXIT_FAILURE;
673 }
674
675 g_pVBoxFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &vbox,
676 ISESSION_IID_STR, &session);
677 if (vbox == NULL)
678 {
679 fprintf(stderr, "%s: FATAL: could not get vbox handle\n", argv[0]);
680 return EXIT_FAILURE;
681 }
682 if (session == NULL)
683 {
684 fprintf(stderr, "%s: FATAL: could not get session handle\n", argv[0]);
685 return EXIT_FAILURE;
686 }
687 g_pVBoxFuncs->pfnGetEventQueue(&queue);
688 printf("Got the event queue: %p\n", (void *)queue);
689
690 /*
691 * Now ask for revision, version and home folder information of
692 * this vbox. Were not using fancy macros here so it
693 * remains easy to see how we access C++'s vtable.
694 */
695
696 printf("----------------------------------------------------\n");
697
698 /* 1. Revision */
699
700 rc = vbox->vtbl->GetRevision(vbox, &revision);
701 if (NS_SUCCEEDED(rc))
702 {
703 printf("\tRevision: %u\n", revision);
704 }
705 else
706 {
707 fprintf(stderr, "%s: GetRevision() returned %08x\n",
708 argv[0], (unsigned)rc);
709 }
710
711 /* 2. Version */
712
713 rc = vbox->vtbl->GetVersion(vbox, &versionUtf16);
714 if (NS_SUCCEEDED(rc))
715 {
716 char *version = NULL;
717 g_pVBoxFuncs->pfnUtf16ToUtf8(versionUtf16, &version);
718 printf("\tVersion: %s\n", version);
719 g_pVBoxFuncs->pfnUtf8Free(version);
720 g_pVBoxFuncs->pfnComUnallocMem(versionUtf16);
721 }
722 else
723 {
724 fprintf(stderr, "%s: GetVersion() returned %08x\n",
725 argv[0], (unsigned)rc);
726 }
727
728 /* 3. Home Folder */
729
730 rc = vbox->vtbl->GetHomeFolder(vbox, &homefolderUtf16);
731 if (NS_SUCCEEDED(rc))
732 {
733 char *homefolder = NULL;
734 g_pVBoxFuncs->pfnUtf16ToUtf8(homefolderUtf16, &homefolder);
735 printf("\tHomeFolder: %s\n", homefolder);
736 g_pVBoxFuncs->pfnUtf8Free(homefolder);
737 g_pVBoxFuncs->pfnComUnallocMem(homefolderUtf16);
738 }
739 else
740 {
741 fprintf(stderr, "%s: GetHomeFolder() returned %08x\n",
742 argv[0], (unsigned)rc);
743 }
744
745 listVMs(vbox, session, queue);
746 session->vtbl->Close(session);
747
748 printf("----------------------------------------------------\n");
749
750 /*
751 * Do as mom told us: always clean up after yourself.
752 */
753
754 g_pVBoxFuncs->pfnComUninitialize();
755 VBoxCGlueTerm();
756 printf("Finished Main\n");
757
758 return 0;
759}
760/* 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