~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/VBox/Main/testcase/tstVBoxAPILinux.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 *
 
3
 * tstVBoxAPILinux - sample program to illustrate the VirtualBox
 
4
 *                   XPCOM API for machine management on Linux.
 
5
 *                   It only uses standard C/C++ and XPCOM semantics,
 
6
 *                   no additional VBox classes/macros/helpers.
 
7
 *
 
8
 */
 
9
 
 
10
/*
 
11
 * Copyright (C) 2006-2007 innotek GmbH
 
12
 *
 
13
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
14
 * available from http://www.virtualbox.org. This file is free software;
 
15
 * you can redistribute it and/or modify it under the terms of the GNU
 
16
 * General Public License as published by the Free Software Foundation,
 
17
 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
 
18
 * distribution. VirtualBox OSE is distributed in the hope that it will
 
19
 * be useful, but WITHOUT ANY WARRANTY of any kind.
 
20
 */
 
21
 
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <iconv.h>
 
25
#include <errno.h>
 
26
 
 
27
 
 
28
/*
 
29
 * Include the XPCOM headers
 
30
 */
 
31
#include <nsXPCOMGlue.h>
 
32
#include <nsMemory.h>
 
33
#include <nsString.h>
 
34
#include <nsIServiceManager.h>
 
35
#include <nsEventQueueUtils.h>
 
36
 
 
37
#include <nsIExceptionService.h>
 
38
 
 
39
/*
 
40
 * VirtualBox XPCOM interface. This header is generated
 
41
 * from IDL which in turn is generated from a custom XML format.
 
42
 */
 
43
#include "VirtualBox_XPCOM.h"
 
44
 
 
45
/*
 
46
 * Prototypes
 
47
 */
 
48
char *nsIDToString(nsID *guid);
 
49
void printErrorInfo();
 
50
 
 
51
 
 
52
/**
 
53
 * Display all registered VMs on the screen with some information about each
 
54
 *
 
55
 * @param virtualBox VirtualBox instance object.
 
56
 */
 
57
void listVMs(IVirtualBox *virtualBox)
 
58
{
 
59
    nsresult rc;
 
60
 
 
61
    printf("----------------------------------------------------\n");
 
62
    printf("VM List:\n\n");
 
63
 
 
64
    /*
 
65
     * Get the list of all registered VMs
 
66
     */
 
67
    IMachineCollection *collection = nsnull;
 
68
    IMachineEnumerator *enumerator = nsnull;
 
69
    rc = virtualBox->GetMachines(&collection);
 
70
    if (NS_SUCCEEDED(rc))
 
71
        rc = collection->Enumerate(&enumerator);
 
72
    if (NS_SUCCEEDED(rc))
 
73
    {
 
74
        /*
 
75
         * Iterate through the collection
 
76
         */
 
77
        PRBool hasMore = false;
 
78
        while (enumerator->HasMore(&hasMore), hasMore)
 
79
        {
 
80
            IMachine *machine = nsnull;
 
81
            rc = enumerator->GetNext(&machine);
 
82
            if ((NS_SUCCEEDED(rc)) && machine)
 
83
            {
 
84
                nsXPIDLString machineName;
 
85
                machine->GetName(getter_Copies(machineName));
 
86
                char *machineNameAscii = ToNewCString(machineName);
 
87
                printf("\tName:        %s\n", machineNameAscii);
 
88
                free(machineNameAscii);
 
89
 
 
90
                nsID *iid = nsnull;
 
91
                machine->GetId(&iid);
 
92
                const char *uuidString = nsIDToString(iid);
 
93
                printf("\tUUID:        %s\n", uuidString);
 
94
                free((void*)uuidString);
 
95
                nsMemory::Free(iid);
 
96
 
 
97
                nsXPIDLString configFile;
 
98
                machine->GetSettingsFilePath(getter_Copies(configFile));
 
99
                char *configFileAscii = ToNewCString(configFile);
 
100
                printf("\tConfig file: %s\n", configFileAscii);
 
101
                free(configFileAscii);
 
102
 
 
103
                PRUint32 memorySize;
 
104
                machine->GetMemorySize(&memorySize);
 
105
                printf("\tMemory size: %uMB\n", memorySize);
 
106
 
 
107
                nsXPIDLString typeId;
 
108
                machine->GetOSTypeId(getter_Copies(typeId));
 
109
                IGuestOSType *osType = nsnull;
 
110
                virtualBox->GetGuestOSType (typeId.get(), &osType);
 
111
                nsXPIDLString osName;
 
112
                osType->GetDescription(getter_Copies(osName));
 
113
                char *osNameAscii = ToNewCString(osName);
 
114
                printf("\tGuest OS:    %s\n\n", osNameAscii);
 
115
                free(osNameAscii);
 
116
                osType->Release();
 
117
 
 
118
                machine->Release();
 
119
            }
 
120
        }
 
121
    }
 
122
    printf("----------------------------------------------------\n\n");
 
123
    /* don't forget to release the objects... */
 
124
    if (enumerator)
 
125
        enumerator->Release();
 
126
    if (collection)
 
127
        collection->Release();
 
128
}
 
129
 
 
130
/**
 
131
 * Create a sample VM
 
132
 *
 
133
 * @param virtualBox VirtualBox instance object.
 
134
 */
 
135
void createVM(IVirtualBox *virtualBox)
 
136
{
 
137
    nsresult rc;
 
138
    /*
 
139
     * First create a unnamed new VM. It will be unconfigured and not be saved
 
140
     * in the configuration until we explicitely choose to do so.
 
141
     */
 
142
    nsCOMPtr <IMachine> machine;
 
143
    rc = virtualBox->CreateMachine(nsnull, NS_LITERAL_STRING("A brand new name").get(),
 
144
                                   getter_AddRefs(machine));
 
145
    if (NS_FAILED(rc))
 
146
    {
 
147
        printf("Error: could not create machine! rc=%08X\n", rc);
 
148
        return;
 
149
    }
 
150
 
 
151
    /*
 
152
     * Set some properties
 
153
     */
 
154
    /* alternative to illustrate the use of string classes */
 
155
    rc = machine->SetName(NS_ConvertUTF8toUTF16("A new name").get());
 
156
    rc = machine->SetMemorySize(128);
 
157
 
 
158
    /*
 
159
     * Now a more advanced property -- the guest OS type. This is
 
160
     * an object by itself which has to be found first. Note that we
 
161
     * use the ID of the guest OS type here which is an internal
 
162
     * representation (you can find that by configuring the OS type of
 
163
     * a machine in the GUI and then looking at the <Guest ostype=""/>
 
164
     * setting in the XML file. It is also possible to get the OS type from
 
165
     * its description (win2k would be "Windows 2000") by getting the
 
166
     * guest OS type collection and enumerating it.
 
167
     */
 
168
    nsCOMPtr <IGuestOSType> osType;
 
169
    rc = virtualBox->GetGuestOSType(NS_LITERAL_STRING("win2k").get(),
 
170
                                    getter_AddRefs(osType));
 
171
    if (NS_FAILED(rc))
 
172
    {
 
173
        printf("Error: could not find guest OS type! rc=%08X\n", rc);
 
174
    }
 
175
    else
 
176
    {
 
177
        machine->SetOSTypeId (NS_LITERAL_STRING("win2k").get());
 
178
    }
 
179
 
 
180
    /*
 
181
     * Register the VM. Note that this call also saves the VM config
 
182
     * to disk. It is also possible to save the VM settings but not
 
183
     * register the VM.
 
184
     *
 
185
     * Also note that due to current VirtualBox limitations, the machine
 
186
     * must be registered *before* we can attach hard disks to it.
 
187
     */
 
188
    rc = virtualBox->RegisterMachine(machine);
 
189
    if (NS_FAILED(rc))
 
190
    {
 
191
        printf("Error: could not register machine! rc=%08X\n", rc);
 
192
        printErrorInfo();
 
193
        return;
 
194
    }
 
195
 
 
196
    /*
 
197
     * In order to manipulate the registered machine, we must open a session
 
198
     * for that machine. Do it now.
 
199
     */
 
200
    nsCOMPtr<ISession> session;
 
201
    {
 
202
        nsCOMPtr<nsIComponentManager> manager;
 
203
        rc = NS_GetComponentManager (getter_AddRefs (manager));
 
204
        if (NS_FAILED(rc))
 
205
        {
 
206
            printf("Error: could not get component manager! rc=%08X\n", rc);
 
207
            return;
 
208
        }
 
209
        rc = manager->CreateInstanceByContractID (NS_SESSION_CONTRACTID,
 
210
                                                  nsnull,
 
211
                                                  NS_GET_IID(ISession),
 
212
                                                  getter_AddRefs(session));
 
213
        if (NS_FAILED(rc))
 
214
        {
 
215
            printf("Error, could not instantiate Session object! rc=0x%x\n", rc);
 
216
            return;
 
217
        }
 
218
 
 
219
        nsID *machineUUID = nsnull;
 
220
        machine->GetId(&machineUUID);
 
221
        rc = virtualBox->OpenSession(session, *machineUUID);
 
222
        nsMemory::Free(machineUUID);
 
223
        if (NS_FAILED(rc))
 
224
        {
 
225
            printf("Error, could not open session! rc=0x%x\n", rc);
 
226
            return;
 
227
        }
 
228
 
 
229
        /*
 
230
         * After the machine is registered, the initial machine object becomes
 
231
         * immutable. In order to get a mutable machine object, we must query
 
232
         * it from the opened session object.
 
233
         */
 
234
        rc = session->GetMachine(getter_AddRefs(machine));
 
235
        if (NS_FAILED(rc))
 
236
        {
 
237
            printf("Error, could not get sessioned machine! rc=0x%x\n", rc);
 
238
            return;
 
239
        }
 
240
    }
 
241
 
 
242
    /*
 
243
     * Create a virtual harddisk
 
244
     */
 
245
    nsCOMPtr<IHardDisk> hardDisk = 0;
 
246
    nsCOMPtr<IVirtualDiskImage> vdi = 0;
 
247
    rc = virtualBox->CreateHardDisk(HardDiskStorageType::VirtualDiskImage,
 
248
                                    getter_AddRefs(hardDisk));
 
249
    if (NS_SUCCEEDED (rc))
 
250
    {
 
251
        rc = hardDisk->QueryInterface(NS_GET_IID(IVirtualDiskImage),
 
252
                                      (void **)(getter_AddRefs(vdi)));
 
253
        if (NS_SUCCEEDED (rc))
 
254
            rc = vdi->SetFilePath(NS_LITERAL_STRING("TestHardDisk.vdi").get());
 
255
    }
 
256
 
 
257
    if (NS_FAILED(rc))
 
258
    {
 
259
        printf("Failed creating a hard disk object! rc=%08X\n", rc);
 
260
    }
 
261
    else
 
262
    {
 
263
        /*
 
264
         * We have only created an object so far. No on disk representation exists
 
265
         * because none of its properties has been set so far. Let's continue creating
 
266
         * a dynamically expanding image.
 
267
         */
 
268
        nsCOMPtr <IProgress> progress;
 
269
        rc = vdi->CreateDynamicImage(100,                                             // size in megabytes
 
270
                                     getter_AddRefs(progress));                       // optional progress object
 
271
        if (NS_FAILED(rc))
 
272
        {
 
273
            printf("Failed creating hard disk image! rc=%08X\n", rc);
 
274
        }
 
275
        else
 
276
        {
 
277
            /*
 
278
             * Creating the image is done in the background because it can take quite
 
279
             * some time (at least fixed size images). We have to wait for its completion.
 
280
             * Here we wait forever (timeout -1)  which is potentially dangerous.
 
281
             */
 
282
            rc = progress->WaitForCompletion(-1);
 
283
            nsresult resultCode;
 
284
            progress->GetResultCode(&resultCode);
 
285
            if (NS_FAILED(rc) || NS_FAILED(resultCode))
 
286
            {
 
287
                printf("Error: could not create hard disk! rc=%08X\n",
 
288
                       NS_FAILED(rc) ? rc : resultCode);
 
289
            }
 
290
            else
 
291
            {
 
292
                /*
 
293
                 * Now we have to register the new hard disk with VirtualBox.
 
294
                 */
 
295
                rc = virtualBox->RegisterHardDisk(hardDisk);
 
296
                if (NS_FAILED(rc))
 
297
                {
 
298
                    printf("Error: could not register hard disk! rc=%08X\n", rc);
 
299
                }
 
300
                else
 
301
                {
 
302
                    /*
 
303
                     * Now that it's registered, we can assign it to the VM. This is done
 
304
                     * by UUID, so query that one fist. The UUID has been assigned automatically
 
305
                     * when we've created the image.
 
306
                     */
 
307
                    nsID *vdiUUID = nsnull;
 
308
                    hardDisk->GetId(&vdiUUID);
 
309
                    rc = machine->AttachHardDisk(*vdiUUID,
 
310
                                                DiskControllerType::IDE0Controller, // controler identifier
 
311
                                                0);                                 // device number on the controller
 
312
                    nsMemory::Free(vdiUUID);
 
313
                    if (NS_FAILED(rc))
 
314
                    {
 
315
                        printf("Error: could not attach hard disk! rc=%08X\n", rc);
 
316
                    }
 
317
                }
 
318
            }
 
319
        }
 
320
    }
 
321
 
 
322
    /*
 
323
     * It's got a hard disk but that one is new and thus not bootable. Make it
 
324
     * boot from an ISO file. This requires some processing. First the ISO file
 
325
     * has to be registered and then mounted to the VM's DVD drive and selected
 
326
     * as the boot device.
 
327
     */
 
328
    nsID uuid = {0};
 
329
    nsCOMPtr<IDVDImage> dvdImage;
 
330
 
 
331
    rc = virtualBox->OpenDVDImage(NS_LITERAL_STRING("/home/achimha/isoimages/winnt4ger.iso").get(),
 
332
                                  uuid, /* NULL UUID, i.e. a new one will be created */
 
333
                                  getter_AddRefs(dvdImage));
 
334
    if (NS_FAILED(rc))
 
335
    {
 
336
        printf("Error: could not open CD image! rc=%08X\n", rc);
 
337
    }
 
338
    else
 
339
    {
 
340
        /*
 
341
         * Register it with VBox
 
342
         */
 
343
        rc = virtualBox->RegisterDVDImage(dvdImage);
 
344
        if (NS_FAILED(rc))
 
345
        {
 
346
            printf("Error: could not register CD image! rc=%08X\n", rc);
 
347
        }
 
348
        else
 
349
        {
 
350
            /*
 
351
             * Now assign it to our VM
 
352
             */
 
353
            nsID *isoUUID = nsnull;
 
354
            dvdImage->GetId(&isoUUID);
 
355
            nsCOMPtr<IDVDDrive> dvdDrive;
 
356
            machine->GetDVDDrive(getter_AddRefs(dvdDrive));
 
357
            rc = dvdDrive->MountImage(*isoUUID);
 
358
            nsMemory::Free(isoUUID);
 
359
            if (NS_FAILED(rc))
 
360
            {
 
361
                printf("Error: could not mount ISO image! rc=%08X\n", rc);
 
362
            }
 
363
            else
 
364
            {
 
365
                /*
 
366
                 * Last step: tell the VM to boot from the CD.
 
367
                 */
 
368
                rc = machine->SetBootOrder (1, DeviceType::DVDDevice);
 
369
                if (NS_FAILED(rc))
 
370
                {
 
371
                    printf("Could not set boot device! rc=%08X\n", rc);
 
372
                }
 
373
            }
 
374
        }
 
375
    }
 
376
 
 
377
    /*
 
378
     * Save all changes we've just made.
 
379
     */
 
380
    rc = machine->SaveSettings();
 
381
    if (NS_FAILED(rc))
 
382
    {
 
383
        printf("Could not save machine settings! rc=%08X\n", rc);
 
384
    }
 
385
 
 
386
    /*
 
387
     * It is always important to close the open session when it becomes not
 
388
     * necessary any more.
 
389
     */
 
390
    session->Close();
 
391
}
 
392
 
 
393
// main
 
394
///////////////////////////////////////////////////////////////////////////////
 
395
 
 
396
int main(int argc, char *argv[])
 
397
{
 
398
    /*
 
399
     * Check that PRUnichar is equal in size to what compiler composes L""
 
400
     * strings from; otherwise NS_LITERAL_STRING macros won't work correctly
 
401
     * and we will get a meaningless SIGSEGV. This, of course, must be checked
 
402
     * at compile time in xpcom/string/nsTDependentString.h, but XPCOM lacks
 
403
     * compile-time assert macros and I'm not going to add them now.
 
404
     */
 
405
    if (sizeof(PRUnichar) != sizeof(wchar_t))
 
406
    {
 
407
        printf("Error: sizeof(PRUnichar) {%d} != sizeof(wchar_t) {%d}!\n"
 
408
               "Probably, you forgot the -fshort-wchar compiler option.\n",
 
409
               sizeof(PRUnichar), sizeof(wchar_t));
 
410
        return -1;
 
411
    }
 
412
 
 
413
    nsresult rc;
 
414
 
 
415
    /*
 
416
     * This is the standard XPCOM init procedure.
 
417
     * What we do is just follow the required steps to get an instance
 
418
     * of our main interface, which is IVirtualBox.
 
419
     */
 
420
    XPCOMGlueStartup(nsnull);
 
421
 
 
422
    /*
 
423
     * Note that we scope all nsCOMPtr variables in order to have all XPCOM
 
424
     * objects automatically released before we call NS_ShutdownXPCOM at the
 
425
     * end. This is an XPCOM requirement.
 
426
     */
 
427
    {
 
428
        nsCOMPtr<nsIServiceManager> serviceManager;
 
429
        rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsnull, nsnull);
 
430
        if (NS_FAILED(rc))
 
431
        {
 
432
            printf("Error: XPCOM could not be initialized! rc=0x%x\n", rc);
 
433
            return -1;
 
434
        }
 
435
 
 
436
#if 0
 
437
        /*
 
438
         * Register our components. This step is only necessary if this executable
 
439
         * implements XPCOM components itself which is not the case for this
 
440
         * simple example.
 
441
         */
 
442
        nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(serviceManager);
 
443
        if (!registrar)
 
444
        {
 
445
            printf("Error: could not query nsIComponentRegistrar interface!\n");
 
446
            return -1;
 
447
        }
 
448
        registrar->AutoRegister(nsnull);
 
449
#endif
 
450
 
 
451
        /*
 
452
         * Make sure the main event queue is created. This event queue is
 
453
         * responsible for dispatching incoming XPCOM IPC messages. The main
 
454
         * thread should run this event queue's loop during lengthy non-XPCOM
 
455
         * operations to ensure messages from the VirtualBox server and other
 
456
         * XPCOM IPC clients are processed. This use case doesn't perform such
 
457
         * operations so it doesn't run the event loop.
 
458
         */
 
459
        nsCOMPtr<nsIEventQueue> eventQ;
 
460
        rc = NS_GetMainEventQ(getter_AddRefs (eventQ));
 
461
        if (NS_FAILED(rc))
 
462
        {
 
463
            printf("Error: could not get main event queue! rc=%08X\n", rc);
 
464
            return -1;
 
465
        }
 
466
 
 
467
        /*
 
468
         * Now XPCOM is ready and we can start to do real work.
 
469
         * IVirtualBox is the root interface of VirtualBox and will be
 
470
         * retrieved from the XPCOM component manager. We use the
 
471
         * XPCOM provided smart pointer nsCOMPtr for all objects because
 
472
         * that's very convenient and removes the need deal with reference
 
473
         * counting and freeing.
 
474
         */
 
475
        nsCOMPtr<nsIComponentManager> manager;
 
476
        rc = NS_GetComponentManager (getter_AddRefs (manager));
 
477
        if (NS_FAILED(rc))
 
478
        {
 
479
            printf("Error: could not get component manager! rc=%08X\n", rc);
 
480
            return -1;
 
481
        }
 
482
 
 
483
        nsCOMPtr<IVirtualBox> virtualBox;
 
484
        rc = manager->CreateInstanceByContractID (NS_VIRTUALBOX_CONTRACTID,
 
485
                                                  nsnull,
 
486
                                                  NS_GET_IID(IVirtualBox),
 
487
                                                  getter_AddRefs(virtualBox));
 
488
        if (NS_FAILED(rc))
 
489
        {
 
490
            printf("Error, could not instantiate VirtualBox object! rc=0x%x\n", rc);
 
491
            return -1;
 
492
        }
 
493
        printf("VirtualBox object created\n");
 
494
 
 
495
        ////////////////////////////////////////////////////////////////////////////////
 
496
        ////////////////////////////////////////////////////////////////////////////////
 
497
        ////////////////////////////////////////////////////////////////////////////////
 
498
 
 
499
 
 
500
        listVMs(virtualBox);
 
501
 
 
502
        createVM(virtualBox);
 
503
 
 
504
 
 
505
        ////////////////////////////////////////////////////////////////////////////////
 
506
        ////////////////////////////////////////////////////////////////////////////////
 
507
        ////////////////////////////////////////////////////////////////////////////////
 
508
 
 
509
        /* this is enough to free the IVirtualBox instance -- smart pointers rule! */
 
510
        virtualBox = nsnull;
 
511
 
 
512
        /*
 
513
         * Process events that might have queued up in the XPCOM event
 
514
         * queue. If we don't process them, the server might hang.
 
515
         */
 
516
        eventQ->ProcessPendingEvents();
 
517
    }
 
518
 
 
519
    /*
 
520
     * Perform the standard XPCOM shutdown procedure.
 
521
     */
 
522
    NS_ShutdownXPCOM(nsnull);
 
523
    XPCOMGlueShutdown();
 
524
    printf("Done!\n");
 
525
    return 0;
 
526
}
 
527
 
 
528
 
 
529
//////////////////////////////////////////////////////////////////////////////////////////////////////
 
530
//// Helpers
 
531
//////////////////////////////////////////////////////////////////////////////////////////////////////
 
532
 
 
533
/**
 
534
 * Helper function to convert an nsID into a human readable string
 
535
 *
 
536
 * @returns result string, allocated. Has to be freed using free()
 
537
 * @param   guid Pointer to nsID that will be converted.
 
538
 */
 
539
char *nsIDToString(nsID *guid)
 
540
{
 
541
    char *res = (char*)malloc(39);
 
542
 
 
543
    if (res != NULL)
 
544
    {
 
545
        snprintf(res, 39, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
 
546
                 guid->m0, (PRUint32)guid->m1, (PRUint32)guid->m2,
 
547
                 (PRUint32)guid->m3[0], (PRUint32)guid->m3[1], (PRUint32)guid->m3[2],
 
548
                 (PRUint32)guid->m3[3], (PRUint32)guid->m3[4], (PRUint32)guid->m3[5],
 
549
                 (PRUint32)guid->m3[6], (PRUint32)guid->m3[7]);
 
550
    }
 
551
    return res;
 
552
}
 
553
 
 
554
/**
 
555
 * Helper function to print XPCOM exception information set on the current
 
556
 * thread after a failed XPCOM method call. This function will also print
 
557
 * extended VirtualBox error info if it is available.
 
558
 */
 
559
void printErrorInfo()
 
560
{
 
561
    nsresult rc;
 
562
 
 
563
    nsCOMPtr <nsIExceptionService> es;
 
564
    es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
 
565
    if (NS_SUCCEEDED (rc))
 
566
    {
 
567
        nsCOMPtr <nsIExceptionManager> em;
 
568
        rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
 
569
        if (NS_SUCCEEDED (rc))
 
570
        {
 
571
            nsCOMPtr<nsIException> ex;
 
572
            rc = em->GetCurrentException (getter_AddRefs (ex));
 
573
            if (NS_SUCCEEDED (rc) && ex)
 
574
            {
 
575
                nsCOMPtr <IVirtualBoxErrorInfo> info;
 
576
                info = do_QueryInterface(ex, &rc);
 
577
                if (NS_SUCCEEDED(rc) && info)
 
578
                {
 
579
                    /* got extended error info */
 
580
                    printf ("Extended error info (IVirtualBoxErrorInfo):\n");
 
581
                    nsresult resultCode = NS_OK;
 
582
                    info->GetResultCode (&resultCode);
 
583
                    printf ("  resultCode=%08X\n", resultCode);
 
584
                    nsXPIDLString component;
 
585
                    info->GetComponent (getter_Copies (component));
 
586
                    printf ("  component=%s\n", NS_ConvertUTF16toUTF8(component).get());
 
587
                    nsXPIDLString text;
 
588
                    info->GetText (getter_Copies (text));
 
589
                    printf ("  text=%s\n", NS_ConvertUTF16toUTF8(text).get());
 
590
                }
 
591
                else
 
592
                {
 
593
                    /* got basic error info */
 
594
                    printf ("Basic error info (nsIException):\n");
 
595
                    nsresult resultCode = NS_OK;
 
596
                    ex->GetResult (&resultCode);
 
597
                    printf ("  resultCode=%08X\n", resultCode);
 
598
                    nsXPIDLCString message;
 
599
                    ex->GetMessage (getter_Copies (message));
 
600
                    printf ("  message=%s\n", message.get());
 
601
                }
 
602
 
 
603
                /* reset the exception to NULL to indicate we've processed it */
 
604
                em->SetCurrentException (NULL);
 
605
 
 
606
                rc = NS_OK;
 
607
            }
 
608
        }
 
609
    }
 
610
}