VirtualBox

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

Last change on this file since 25414 was 24301, checked in by vboxsync, 15 years ago

Main,Frontends: Added two new running states: Teleporting and LiveSnapshotting. Also added TeleportingPausedVM. Renamed TeleportingFrom to TeleportingIn.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use