VirtualBox

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

Last change on this file since 16597 was 16548, checked in by vboxsync, 16 years ago

Return early when the machine count is zero.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette