VirtualBox

source: vbox/trunk/src/VBox/Main/cbinding/tstLinuxC.c@ 17467

Last change on this file since 17467 was 17304, checked in by vboxsync, 16 years ago

C API: Modified the xpcidl.xsl to create VirtualBox_CXPCOM.h
header file automatically which is the only header needed
to compile any C API apps. (VirtualBox_CXPCOM.h has no other
external dependencies what so ever during compile time,
naturally during runtime it depends on VBoxXPCOMC.so)
Modified the sample applications accordingly.

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