VirtualBox

source: vbox/trunk/src/VBox/Main/cbinding/tstXPCOMCGlue.c@ 19106

Last change on this file since 19106 was 19081, checked in by vboxsync, 16 years ago

Main/cbindings: VBOXXPCOMC::pfnComInitialize needs to know which interface versions to return, outlined the change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Revision: 19081 $ */
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
32static char *nsIDToString(nsID *guid);
33static void listVMs(IVirtualBox *virtualBox, ISession *session);
34static void startVM(IVirtualBox *virtualBox, ISession *session, nsID *id);
35
36/**
37 * Helper function to convert an nsID into a human readable string.
38 *
39 * @returns result string, allocated. Has to be freed using free()
40 * @param guid Pointer to nsID that will be converted.
41 */
42static char *nsIDToString(nsID *guid)
43{
44 /* Avoid magic number 39. Yes, sizeof "literal" includes the NUL byte. */
45 char *res = malloc(sizeof "{12345678-1234-1234-1234-123456789012}");
46
47 if (res != NULL)
48 {
49 sprintf(res, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
50 (unsigned)guid->m0, (unsigned)guid->m1, (unsigned)guid->m2,
51 (unsigned)guid->m3[0], (unsigned)guid->m3[1],
52 (unsigned)guid->m3[2], (unsigned)guid->m3[3],
53 (unsigned)guid->m3[4], (unsigned)guid->m3[5],
54 (unsigned)guid->m3[6], (unsigned)guid->m3[7]);
55 }
56 return res;
57}
58
59/**
60 * List the registered VMs.
61 *
62 * @param virtualBox ptr to IVirtualBox object
63 * @param session ptr to ISession object
64 */
65static void listVMs(IVirtualBox *virtualBox, ISession *session)
66{
67 nsresult rc;
68 IMachine **machines = NULL;
69 PRUint32 machineCnt = 0;
70 PRUint32 i;
71 unsigned start_id;
72
73 /*
74 * Get the list of all registered VMs.
75 */
76
77 rc = virtualBox->vtbl->GetMachines(virtualBox, &machineCnt, &machines);
78 if (NS_FAILED(rc))
79 {
80 fprintf(stderr, "could not get list of machines, rc=%08x\n",
81 (unsigned)rc);
82 return;
83 }
84
85 if (machineCnt == 0)
86 {
87 printf("\tNo VMs\n");
88 return;
89 }
90
91 printf("VM List:\n\n");
92
93 /*
94 * Iterate through the collection.
95 */
96
97 for (i = 0; i < machineCnt; ++i)
98 {
99 IMachine *machine = machines[i];
100 PRBool isAccessible = PR_FALSE;
101
102 printf("\tMachine #%u\n", (unsigned)i);
103
104 if (!machine)
105 {
106 printf("\t(skipped, NULL)\n");
107 continue;
108 }
109
110 machine->vtbl->GetAccessible(machine, &isAccessible);
111
112 if (isAccessible)
113 {
114 PRUnichar *machineNameUtf16;
115 char *machineName;
116
117 machine->vtbl->GetName(machine, &machineNameUtf16);
118 g_pVBoxFuncs->pfnUtf16ToUtf8(machineNameUtf16,&machineName);
119 printf("\tName: %s\n", machineName);
120
121 g_pVBoxFuncs->pfnUtf8Free(machineName);
122 g_pVBoxFuncs->pfnComUnallocMem(machineNameUtf16);
123 }
124 else
125 {
126 printf("\tName: <inaccessible>\n");
127 }
128
129
130 {
131 nsID *iid = NULL;
132 char *uuidString;
133
134 machine->vtbl->GetId(machine, &iid);
135 uuidString = nsIDToString(iid);
136 printf("\tUUID: %s\n", uuidString);
137
138 free(uuidString);
139 g_pVBoxFuncs->pfnComUnallocMem(iid);
140 }
141
142 if (isAccessible)
143 {
144 {
145 PRUnichar *configFile;
146 char *configFile1 = calloc((size_t)64, (size_t)1);
147
148 machine->vtbl->GetSettingsFilePath(machine, &configFile);
149 g_pVBoxFuncs->pfnUtf16ToUtf8(configFile, &configFile1);
150 printf("\tConfig file: %s\n", configFile1);
151
152 free(configFile1);
153 g_pVBoxFuncs->pfnComUnallocMem(configFile);
154 }
155
156 {
157 PRUint32 memorySize;
158
159 machine->vtbl->GetMemorySize(machine, &memorySize);
160 printf("\tMemory size: %uMB\n", memorySize);
161 }
162
163 {
164 PRUnichar *typeId;
165 PRUnichar *osNameUtf16;
166 char *osName;
167 IGuestOSType *osType = NULL;
168
169 machine->vtbl->GetOSTypeId(machine, &typeId);
170 virtualBox->vtbl->GetGuestOSType(virtualBox, typeId, &osType);
171 osType->vtbl->GetDescription(osType, &osNameUtf16);
172 g_pVBoxFuncs->pfnUtf16ToUtf8(osNameUtf16,&osName);
173 printf("\tGuest OS: %s\n\n", osName);
174
175 osType->vtbl->nsisupports.Release((void *)osType);
176 g_pVBoxFuncs->pfnUtf8Free(osName);
177 g_pVBoxFuncs->pfnComUnallocMem(osNameUtf16);
178 g_pVBoxFuncs->pfnComUnallocMem(typeId);
179 }
180 }
181 }
182
183 /*
184 * Let the user chose a machine to start.
185 */
186
187 printf("Type Machine# to start (0 - %u) or 'quit' to do nothing: ",
188 (unsigned)(machineCnt - 1));
189 fflush(stdout);
190
191 if (scanf("%u", &start_id) == 1 && start_id < machineCnt)
192 {
193 IMachine *machine = machines[start_id];
194
195 if (machine)
196 {
197 nsID *iid = NULL;
198
199 machine->vtbl->GetId(machine, &iid);
200 startVM(virtualBox, session, iid);
201
202 g_pVBoxFuncs->pfnComUnallocMem(iid);
203 }
204 }
205
206 /*
207 * Don't forget to release the objects in the array.
208 */
209
210 for (i = 0; i < machineCnt; ++i)
211 {
212 IMachine *machine = machines[i];
213
214 if (machine)
215 {
216 machine->vtbl->nsisupports.Release((void *)machine);
217 }
218 }
219}
220
221/**
222 * Start a VM.
223 *
224 * @param virtualBox ptr to IVirtualBox object
225 * @param session ptr to ISession object
226 * @param id identifies the machine to start
227 */
228static void startVM(IVirtualBox *virtualBox, ISession *session, nsID *id)
229{
230 nsresult rc;
231 IMachine *machine = NULL;
232 IProgress *progress = NULL;
233 PRUnichar *env = NULL;
234 PRUnichar *sessionType;
235
236 rc = virtualBox->vtbl->GetMachine(virtualBox, id, &machine);
237
238 if (NS_FAILED(rc) || !machine)
239 {
240 fprintf(stderr, "Error: Couldn't get the machine handle.\n");
241 return;
242 }
243
244 g_pVBoxFuncs->pfnUtf8ToUtf16("gui", &sessionType);
245
246 rc = virtualBox->vtbl->OpenRemoteSession(
247 virtualBox,
248 session,
249 id,
250 sessionType,
251 env,
252 &progress
253 );
254
255 g_pVBoxFuncs->pfnUtf16Free(sessionType);
256
257 if (NS_FAILED(rc))
258 {
259 fprintf(stderr, "Error: OpenRemoteSession failed.\n");
260 }
261 else
262 {
263 PRBool completed;
264 nsresult resultCode;
265
266 printf("Waiting for the remote session to open...\n");
267 progress->vtbl->WaitForCompletion(progress, -1);
268
269 rc = progress->vtbl->GetCompleted(progress, &completed);
270 if (NS_FAILED(rc))
271 {
272 fprintf (stderr, "Error: GetCompleted status failed.\n");
273 }
274
275 progress->vtbl->GetResultCode(progress, &resultCode);
276 if (NS_FAILED(resultCode))
277 {
278 IVirtualBoxErrorInfo *errorInfo;
279 PRUnichar *textUtf16;
280 char *text;
281
282 progress->vtbl->GetErrorInfo(progress, &errorInfo);
283 errorInfo->vtbl->GetText(errorInfo, &textUtf16);
284 g_pVBoxFuncs->pfnUtf16ToUtf8(textUtf16, &text);
285 printf("Error: %s\n", text);
286
287 g_pVBoxFuncs->pfnComUnallocMem(textUtf16);
288 g_pVBoxFuncs->pfnUtf8Free(text);
289 }
290 else
291 {
292 fprintf(stderr, "Remote session has been successfully opened.\n");
293 }
294 progress->vtbl->nsisupports.Release((void *)progress);
295 }
296
297 /* It's important to always release resources. */
298 machine->vtbl->nsisupports.Release((void *)machine);
299}
300
301/* Main - Start the ball rolling. */
302
303int main(int argc, char **argv)
304{
305 IVirtualBox *vbox = NULL;
306 ISession *session = NULL;
307 PRUint32 revision = 0;
308 PRUnichar *versionUtf16 = NULL;
309 PRUnichar *homefolderUtf16 = NULL;
310 nsresult rc; /* Result code of various function (method) calls. */
311
312 printf("Starting Main\n");
313
314 /*
315 * VBoxComInitialize does all the necessary startup action and
316 * provides us with pointers to vbox and session handles.
317 * It should be matched by a call to VBoxComUninitialize(vbox)
318 * when done.
319 */
320
321 if (VBoxCGlueInit() != 0)
322 {
323 fprintf(stderr, "%s: FATAL: VBoxCGlueInit failed: %s\n",
324 argv[0], g_szVBoxErrMsg);
325 return EXIT_FAILURE;
326 }
327
328 g_pVBoxFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &vbox,
329 ISESSION_IID_STR, &session);
330 if (vbox == NULL)
331 {
332 fprintf(stderr, "%s: FATAL: could not get vbox handle\n", argv[0]);
333 return EXIT_FAILURE;
334 }
335 if (session == NULL)
336 {
337 fprintf(stderr, "%s: FATAL: could not get session handle\n", argv[0]);
338 return EXIT_FAILURE;
339 }
340
341 /*
342 * Now ask for revision, version and home folder information of
343 * this vbox. Were not using fancy macros here so it
344 * remains easy to see how we access C++'s vtable.
345 */
346
347 printf("----------------------------------------------------\n");
348
349 /* 1. Revision */
350
351 rc = vbox->vtbl->GetRevision(vbox, &revision);
352 if (NS_SUCCEEDED(rc))
353 {
354 printf("\tRevision: %u\n", revision);
355 }
356 else
357 {
358 fprintf(stderr, "%s: GetRevision() returned %08x\n",
359 argv[0], (unsigned)rc);
360 }
361
362 /* 2. Version */
363
364 rc = vbox->vtbl->GetVersion(vbox, &versionUtf16);
365 if (NS_SUCCEEDED(rc))
366 {
367 char *version = NULL;
368 g_pVBoxFuncs->pfnUtf16ToUtf8(versionUtf16, &version);
369 printf("\tVersion: %s\n", version);
370 g_pVBoxFuncs->pfnUtf8Free(version);
371 g_pVBoxFuncs->pfnComUnallocMem(versionUtf16);
372 }
373 else
374 {
375 fprintf(stderr, "%s: GetVersion() returned %08x\n",
376 argv[0], (unsigned)rc);
377 }
378
379 /* 3. Home Folder */
380
381 rc = vbox->vtbl->GetHomeFolder(vbox, &homefolderUtf16);
382 if (NS_SUCCEEDED(rc))
383 {
384 char *homefolder = NULL;
385 g_pVBoxFuncs->pfnUtf16ToUtf8(homefolderUtf16, &homefolder);
386 printf("\tHomeFolder: %s\n", homefolder);
387 g_pVBoxFuncs->pfnUtf8Free(homefolder);
388 g_pVBoxFuncs->pfnComUnallocMem(homefolderUtf16);
389 }
390 else
391 {
392 fprintf(stderr, "%s: GetHomeFolder() returned %08x\n",
393 argv[0], (unsigned)rc);
394 }
395
396 listVMs(vbox, session);
397 session->vtbl->Close(session);
398
399 printf("----------------------------------------------------\n");
400
401 /*
402 * Do as mom told us: always clean up after yourself.
403 */
404
405 g_pVBoxFuncs->pfnComUninitialize();
406 VBoxCGlueTerm();
407 printf("Finished Main\n");
408
409 return 0;
410}
411/* 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