VirtualBox

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

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

tstXPCOMCCall.c: adjustments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.6 KB
Line 
1/* $Revision: 18806 $ */
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
33static char *nsIDToString(nsID *guid);
34static void listVMs(IVirtualBox *virtualBox, ISession *session);
35static void startVM(IVirtualBox *virtualBox, ISession *session, nsID *id);
36
37int volatile g_refcount = 0;
38
39/**
40 * Helper function to convert an nsID into a human readable string.
41 *
42 * @returns result string, allocated. Has to be freed using free()
43 * @param guid Pointer to nsID that will be converted.
44 */
45static char *nsIDToString(nsID *guid)
46{
47 /* Avoid magic number 39. Yes, sizeof "literal" includes the NUL byte. */
48 char *res = malloc(sizeof "{12345678-1234-1234-1234-123456789012}");
49
50 if (res != NULL)
51 {
52 sprintf(res, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
53 (unsigned)guid->m0, (unsigned)guid->m1, (unsigned)guid->m2,
54 (unsigned)guid->m3[0], (unsigned)guid->m3[1],
55 (unsigned)guid->m3[2], (unsigned)guid->m3[3],
56 (unsigned)guid->m3[4], (unsigned)guid->m3[5],
57 (unsigned)guid->m3[6], (unsigned)guid->m3[7]);
58 }
59 return res;
60}
61
62static const char *GetStateName(PRUint32 machineState)
63{
64 switch (machineState)
65 {
66 case MachineState_Null: return "<null>";
67 case MachineState_PoweredOff: return "PoweredOff";
68 case MachineState_Saved: return "Saved";
69 case MachineState_Aborted: return "Aborted";
70 case MachineState_Running: return "Running";
71 case MachineState_Paused: return "Paused";
72 case MachineState_Stuck: return "Stuck";
73 case MachineState_Starting: return "Starting";
74 case MachineState_Stopping: return "Stopping";
75 case MachineState_Saving: return "Saving";
76 case MachineState_Restoring: return "Restoring";
77 case MachineState_Discarding: return "Discarding";
78 case MachineState_SettingUp: return "SettingUp";
79 default: return "no idea";
80 }
81}
82
83static nsresult OnMousePointerShapeChange(
84 IConsoleCallback *this_,
85 PRBool visible,
86 PRBool alpha,
87 PRUint32 xHot,
88 PRUint32 yHot,
89 PRUint32 width,
90 PRUint32 height,
91 PRUint8 * shape
92) {
93 printf("%d here\n",__LINE__);
94 return 0;
95}
96
97static nsresult OnMouseCapabilityChange(
98 IConsoleCallback *this_,
99 PRBool supportsAbsolute,
100 PRBool needsHostCursor
101) {
102 printf("%d here\n",__LINE__);
103 return 0;
104}
105
106static nsresult OnKeyboardLedsChange(
107 IConsoleCallback *this_,
108 PRBool numLock,
109 PRBool capsLock,
110 PRBool scrollLock
111) {
112 printf("%d here\n",__LINE__);
113 return 0;
114}
115
116static nsresult OnStateChange(
117 IConsoleCallback *this_,
118 PRUint32 state
119) {
120 printf("%d here\n",__LINE__);
121 printf("OnStateChange: %s\n", GetStateName(state));
122 fflush(stdout);
123 return 0;
124}
125
126static nsresult OnAdditionsStateChange(IConsoleCallback *this_ )
127{
128 printf("%d here\n",__LINE__);
129 return 0;
130}
131
132static nsresult OnDVDDriveChange(IConsoleCallback *this_ )
133{
134 printf("%d here\n",__LINE__);
135 return 0;
136}
137
138static nsresult OnFloppyDriveChange(IConsoleCallback *this_ )
139{
140 printf("%d here\n",__LINE__);
141 return 0;
142}
143
144static nsresult OnNetworkAdapterChange(
145 IConsoleCallback *this_,
146 INetworkAdapter * networkAdapter
147) {
148 printf("%d here\n",__LINE__);
149 return 0;
150}
151
152static nsresult OnSerialPortChange(
153 IConsoleCallback *this_,
154 ISerialPort * serialPort
155) {
156 printf("%d here\n",__LINE__);
157 return 0;
158}
159
160static nsresult OnParallelPortChange(
161 IConsoleCallback *this_,
162 IParallelPort * parallelPort
163) {
164 printf("%d here\n",__LINE__);
165 return 0;
166}
167
168static nsresult OnStorageControllerChange(IConsoleCallback *this_ )
169{
170 printf("%d here\n",__LINE__);
171 return 0;
172}
173
174static nsresult OnVRDPServerChange(IConsoleCallback *this_ )
175{
176 printf("%d here\n",__LINE__);
177 return 0;
178}
179
180static nsresult OnUSBControllerChange(IConsoleCallback *this_ )
181{
182 printf("%d here\n",__LINE__);
183 return 0;
184}
185
186static nsresult OnUSBDeviceStateChange(
187 IConsoleCallback *this_,
188 IUSBDevice * device,
189 PRBool attached,
190 IVirtualBoxErrorInfo * error
191) {
192 printf("%d here\n",__LINE__);
193 return 0;
194}
195
196static nsresult OnSharedFolderChange(
197 IConsoleCallback *this_,
198 PRUint32 scope
199) {
200 printf("%d here\n",__LINE__);
201 return 0;
202}
203
204static nsresult OnRuntimeError(
205 IConsoleCallback *this_,
206 PRBool fatal,
207 PRUnichar * id,
208 PRUnichar * message
209) {
210 printf("%d here\n",__LINE__);
211 return 0;
212}
213
214static nsresult OnCanShowWindow(
215 IConsoleCallback *this_,
216 PRBool * canShow
217) {
218 printf("%d here\n",__LINE__);
219 return 0;
220}
221
222static nsresult OnShowWindow(
223 IConsoleCallback *this_,
224 PRUint64 * winId
225) {
226 printf("%d here\n",__LINE__);
227 return 0;
228}
229
230
231static nsresult AddRef(nsISupports *this_)
232{
233 nsresult c;
234
235 printf("AddRef\n");
236 c = g_refcount++;
237 return c;
238}
239
240static nsresult Release(nsISupports *this_)
241{
242 nsresult c;
243 printf("Release\n");
244
245 c = g_refcount--;
246 if (c == 0)
247 {
248 /* delete object */
249#if 0 /* test */
250 free(this_->vtbl);
251 free(this_);
252#endif
253 }
254 return c;
255}
256
257static nsresult QueryInterface(nsISupports *this_, const nsID *iid, void **resultp)
258{
259 IConsoleCallback *that = (IConsoleCallback *)this_;
260
261 printf("QueryInterface\n");
262 /* match iid */
263 g_refcount++;
264 *resultp = that;
265 return 0;
266}
267
268static void registerCallBack(IVirtualBox *virtualBox, ISession *session, nsID *machineId)
269{
270 IConsole *console = NULL;
271 nsresult rc;
272
273 rc = virtualBox->vtbl->OpenExistingSession(virtualBox, session, machineId);
274 session->vtbl->GetConsole(session, &console);
275 if (console) {
276 IConsoleCallback *consoleCallback = NULL;
277
278 consoleCallback = calloc(1, sizeof(IConsoleCallback));
279 consoleCallback->vtbl = calloc(1, sizeof(struct IConsoleCallback_vtbl));
280
281 if (consoleCallback && consoleCallback->vtbl) {
282
283 consoleCallback->vtbl->nsisupports.AddRef = &AddRef;
284 consoleCallback->vtbl->nsisupports.Release = &Release;
285 consoleCallback->vtbl->nsisupports.QueryInterface = &QueryInterface;
286 consoleCallback->vtbl->OnMousePointerShapeChange = &OnMousePointerShapeChange;
287 consoleCallback->vtbl->OnMouseCapabilityChange = &OnMouseCapabilityChange;
288 consoleCallback->vtbl->OnKeyboardLedsChange =&OnKeyboardLedsChange;
289 consoleCallback->vtbl->OnStateChange = &OnStateChange;
290 consoleCallback->vtbl->OnAdditionsStateChange = &OnAdditionsStateChange;
291 consoleCallback->vtbl->OnDVDDriveChange = &OnDVDDriveChange;
292 consoleCallback->vtbl->OnFloppyDriveChange = &OnFloppyDriveChange;
293 consoleCallback->vtbl->OnNetworkAdapterChange = &OnNetworkAdapterChange;
294 consoleCallback->vtbl->OnSerialPortChange = &OnSerialPortChange;
295 consoleCallback->vtbl->OnParallelPortChange = &OnParallelPortChange;
296 consoleCallback->vtbl->OnStorageControllerChange = &OnStorageControllerChange;
297 consoleCallback->vtbl->OnVRDPServerChange = &OnVRDPServerChange;
298 consoleCallback->vtbl->OnUSBControllerChange = &OnUSBControllerChange;
299 consoleCallback->vtbl->OnUSBDeviceStateChange = &OnUSBDeviceStateChange;
300 consoleCallback->vtbl->OnSharedFolderChange = &OnSharedFolderChange;
301 consoleCallback->vtbl->OnRuntimeError = &OnRuntimeError;
302 consoleCallback->vtbl->OnCanShowWindow = &OnCanShowWindow;
303 consoleCallback->vtbl->OnShowWindow = &OnShowWindow;
304 g_refcount = 1;
305
306 printf("%d here\n",__LINE__);
307 console->vtbl->RegisterCallback(console, consoleCallback);
308 printf("%d here\n",__LINE__);
309
310 {
311 int run = 10;
312 while (run-- > 0) {
313 sleep(1);
314 printf("waiting here:%d\n",run);
315 fflush(stdout);
316 }
317 }
318 console->vtbl->UnregisterCallback(console, consoleCallback);
319 }
320 /*consoleCallback->vtbl->Release(consoleCallback);*/
321 }
322 session->vtbl->Close((void *)session);
323}
324
325/**
326 * List the registered VMs.
327 *
328 * @param virtualBox ptr to IVirtualBox object
329 * @param session ptr to ISession object
330 */
331static void listVMs(IVirtualBox *virtualBox, ISession *session)
332{
333 nsresult rc;
334 IMachine **machines = NULL;
335 PRUint32 machineCnt = 0;
336 PRUint32 i;
337 unsigned start_id;
338
339 /*
340 * Get the list of all registered VMs.
341 */
342
343 rc = virtualBox->vtbl->GetMachines(virtualBox, &machineCnt, &machines);
344 if (NS_FAILED(rc))
345 {
346 fprintf(stderr, "could not get list of machines, rc=%08x\n",
347 (unsigned)rc);
348 return;
349 }
350
351 if (machineCnt == 0)
352 {
353 printf("\tNo VMs\n");
354 return;
355 }
356
357 printf("VM List:\n\n");
358
359 /*
360 * Iterate through the collection.
361 */
362
363 for (i = 0; i < machineCnt; ++i)
364 {
365 IMachine *machine = machines[i];
366 PRBool isAccessible = PR_FALSE;
367
368 printf("\tMachine #%u\n", (unsigned)i);
369
370 if (!machine)
371 {
372 printf("\t(skipped, NULL)\n");
373 continue;
374 }
375
376 machine->vtbl->GetAccessible(machine, &isAccessible);
377
378 if (isAccessible)
379 {
380 PRUnichar *machineNameUtf16;
381 char *machineName;
382
383 machine->vtbl->GetName(machine, &machineNameUtf16);
384 g_pVBoxFuncs->pfnUtf16ToUtf8(machineNameUtf16,&machineName);
385 printf("\tName: %s\n", machineName);
386
387 g_pVBoxFuncs->pfnUtf8Free(machineName);
388 g_pVBoxFuncs->pfnComUnallocMem(machineNameUtf16);
389 }
390 else
391 {
392 printf("\tName: <inaccessible>\n");
393 }
394
395
396 {
397 nsID *iid = NULL;
398 char *uuidString;
399
400 machine->vtbl->GetId(machine, &iid);
401 uuidString = nsIDToString(iid);
402 printf("\tUUID: %s\n", uuidString);
403
404 free(uuidString);
405 g_pVBoxFuncs->pfnComUnallocMem(iid);
406 }
407
408 if (isAccessible)
409 {
410 {
411 PRUnichar *configFile;
412 char *configFile1 = calloc((size_t)64, (size_t)1);
413
414 machine->vtbl->GetSettingsFilePath(machine, &configFile);
415 g_pVBoxFuncs->pfnUtf16ToUtf8(configFile, &configFile1);
416 printf("\tConfig file: %s\n", configFile1);
417
418 free(configFile1);
419 g_pVBoxFuncs->pfnComUnallocMem(configFile);
420 }
421
422 {
423 PRUint32 memorySize;
424
425 machine->vtbl->GetMemorySize(machine, &memorySize);
426 printf("\tMemory size: %uMB\n", memorySize);
427 }
428
429 {
430 PRUnichar *typeId;
431 PRUnichar *osNameUtf16;
432 char *osName;
433 IGuestOSType *osType = NULL;
434
435 machine->vtbl->GetOSTypeId(machine, &typeId);
436 virtualBox->vtbl->GetGuestOSType(virtualBox, typeId, &osType);
437 osType->vtbl->GetDescription(osType, &osNameUtf16);
438 g_pVBoxFuncs->pfnUtf16ToUtf8(osNameUtf16,&osName);
439 printf("\tGuest OS: %s\n\n", osName);
440
441 osType->vtbl->nsisupports.Release((void *)osType);
442 g_pVBoxFuncs->pfnUtf8Free(osName);
443 g_pVBoxFuncs->pfnComUnallocMem(osNameUtf16);
444 g_pVBoxFuncs->pfnComUnallocMem(typeId);
445 }
446 }
447 }
448
449 /*
450 * Let the user chose a machine to start.
451 */
452
453 printf("Type Machine# to start (0 - %u) or 'quit' to do nothing: ",
454 (unsigned)(machineCnt - 1));
455 fflush(stdout);
456
457 if (scanf("%u", &start_id) == 1 && start_id < machineCnt)
458 {
459 IMachine *machine = machines[start_id];
460
461 if (machine)
462 {
463 nsID *iid = NULL;
464
465 machine->vtbl->GetId(machine, &iid);
466 /*startVM(virtualBox, session, iid);*/
467 registerCallBack(virtualBox, session, iid);
468
469 g_pVBoxFuncs->pfnComUnallocMem(iid);
470 }
471 }
472
473 /*
474 * Don't forget to release the objects in the array.
475 */
476
477 for (i = 0; i < machineCnt; ++i)
478 {
479 IMachine *machine = machines[i];
480
481 if (machine)
482 {
483 machine->vtbl->nsisupports.Release((nsISupports *)machine);
484 }
485 }
486}
487
488/**
489 * Start a VM.
490 *
491 * @param virtualBox ptr to IVirtualBox object
492 * @param session ptr to ISession object
493 * @param id identifies the machine to start
494 */
495#if 0
496static void startVM(IVirtualBox *virtualBox, ISession *session, nsID *id)
497{
498 nsresult rc;
499 IMachine *machine = NULL;
500 IProgress *progress = NULL;
501 PRUnichar *env = NULL;
502 PRUnichar *sessionType;
503
504 rc = virtualBox->vtbl->GetMachine(virtualBox, id, &machine);
505
506 if (NS_FAILED(rc) || !machine)
507 {
508 fprintf(stderr, "Error: Couldn't get the machine handle.\n");
509 return;
510 }
511
512 g_pVBoxFuncs->pfnUtf8ToUtf16("gui", &sessionType);
513
514 rc = virtualBox->vtbl->OpenRemoteSession(
515 virtualBox,
516 session,
517 id,
518 sessionType,
519 env,
520 &progress
521 );
522
523 g_pVBoxFuncs->pfnUtf16Free(sessionType);
524
525 if (NS_FAILED(rc))
526 {
527 fprintf(stderr, "Error: OpenRemoteSession failed.\n");
528 }
529 else
530 {
531 PRBool completed;
532 nsresult resultCode;
533
534 printf("Waiting for the remote session to open...\n");
535 progress->vtbl->WaitForCompletion(progress, -1);
536
537 rc = progress->vtbl->GetCompleted(progress, &completed);
538 if (NS_FAILED(rc))
539 {
540 fprintf (stderr, "Error: GetCompleted status failed.\n");
541 }
542
543 progress->vtbl->GetResultCode(progress, &resultCode);
544 if (NS_FAILED(resultCode))
545 {
546 IVirtualBoxErrorInfo *errorInfo;
547 PRUnichar *textUtf16;
548 char *text;
549
550 progress->vtbl->GetErrorInfo(progress, &errorInfo);
551 errorInfo->vtbl->GetText(errorInfo, &textUtf16);
552 g_pVBoxFuncs->pfnUtf16ToUtf8(textUtf16, &text);
553 printf("Error: %s\n", text);
554
555 g_pVBoxFuncs->pfnComUnallocMem(textUtf16);
556 g_pVBoxFuncs->pfnUtf8Free(text);
557 }
558 else
559 {
560 fprintf(stderr, "Remote session has been successfully opened.\n");
561 }
562 progress->vtbl->nsisupports.Release((void *)progress);
563 }
564
565 /* It's important to always release resources. */
566 machine->vtbl->nsisupports.Release((void *)machine);
567}
568#endif
569
570/* Main - Start the ball rolling. */
571
572int main(int argc, char **argv)
573{
574 IVirtualBox *vbox = NULL;
575 ISession *session = NULL;
576 PRUint32 revision = 0;
577 PRUnichar *versionUtf16 = NULL;
578 PRUnichar *homefolderUtf16 = NULL;
579 nsresult rc; /* Result code of various function (method) calls. */
580
581 printf("Starting Main\n");
582
583 /*
584 * VBoxComInitialize does all the necessary startup action and
585 * provides us with pointers to vbox and session handles.
586 * It should be matched by a call to VBoxComUninitialize(vbox)
587 * when done.
588 */
589
590 if (VBoxCGlueInit() != 0)
591 {
592 fprintf(stderr, "%s: FATAL: VBoxCGlueInit failed: %s\n",
593 argv[0], g_szVBoxErrMsg);
594 return EXIT_FAILURE;
595 }
596
597 g_pVBoxFuncs->pfnComInitialize(&vbox, &session);
598 if (vbox == NULL)
599 {
600 fprintf(stderr, "%s: FATAL: could not get vbox handle\n", argv[0]);
601 return EXIT_FAILURE;
602 }
603 if (session == NULL)
604 {
605 fprintf(stderr, "%s: FATAL: could not get session handle\n", argv[0]);
606 return EXIT_FAILURE;
607 }
608
609 /*
610 * Now ask for revision, version and home folder information of
611 * this vbox. Were not using fancy macros here so it
612 * remains easy to see how we access C++'s vtable.
613 */
614
615 printf("----------------------------------------------------\n");
616
617 /* 1. Revision */
618
619 rc = vbox->vtbl->GetRevision(vbox, &revision);
620 if (NS_SUCCEEDED(rc))
621 {
622 printf("\tRevision: %u\n", revision);
623 }
624 else
625 {
626 fprintf(stderr, "%s: GetRevision() returned %08x\n",
627 argv[0], (unsigned)rc);
628 }
629
630 /* 2. Version */
631
632 rc = vbox->vtbl->GetVersion(vbox, &versionUtf16);
633 if (NS_SUCCEEDED(rc))
634 {
635 char *version = NULL;
636 g_pVBoxFuncs->pfnUtf16ToUtf8(versionUtf16, &version);
637 printf("\tVersion: %s\n", version);
638 g_pVBoxFuncs->pfnUtf8Free(version);
639 g_pVBoxFuncs->pfnComUnallocMem(versionUtf16);
640 }
641 else
642 {
643 fprintf(stderr, "%s: GetVersion() returned %08x\n",
644 argv[0], (unsigned)rc);
645 }
646
647 /* 3. Home Folder */
648
649 rc = vbox->vtbl->GetHomeFolder(vbox, &homefolderUtf16);
650 if (NS_SUCCEEDED(rc))
651 {
652 char *homefolder = NULL;
653 g_pVBoxFuncs->pfnUtf16ToUtf8(homefolderUtf16, &homefolder);
654 printf("\tHomeFolder: %s\n", homefolder);
655 g_pVBoxFuncs->pfnUtf8Free(homefolder);
656 g_pVBoxFuncs->pfnComUnallocMem(homefolderUtf16);
657 }
658 else
659 {
660 fprintf(stderr, "%s: GetHomeFolder() returned %08x\n",
661 argv[0], (unsigned)rc);
662 }
663
664 listVMs(vbox, session);
665 session->vtbl->Close(session);
666
667 printf("----------------------------------------------------\n");
668
669 /*
670 * Do as mom told us: always clean up after yourself.
671 */
672
673 g_pVBoxFuncs->pfnComUninitialize();
674 VBoxCGlueTerm();
675 printf("Finished Main\n");
676
677 return 0;
678}
679/* 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