vbox_mscom_impl.cpp 100 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2010-2012 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.

18
#ifdef _VIRTUALBOX_IMPORT_FUNCTIONS_
Rom Walton's avatar
Rom Walton committed
19

20
#include "boinc_win.h"
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "win_util.h"
#include "diagnostics.h"
#include "filesys.h"
#include "parse.h"
#include "str_util.h"
#include "str_replace.h"
#include "util.h"
#include "error_numbers.h"
#include "procinfo.h"
#include "network.h"
#include "boinc_api.h"
#include "floppyio.h"
#include "vboxwrapper.h"

35
36
37
#if defined(_MSC_VER) || defined(__MINGW32__)
#define stricmp     _stricmp
#endif
38

39
using std::string;
40
41


42
43
44
45
46
47
48
// Helper function to print MSCOM exception information set on the current
// thread after a failed MSCOM method call. This function will also print
// extended VirtualBox error info if it is available.
//
void virtualbox_dump_error() {
    HRESULT rc;
    char buf[256];
49
50
51
    IErrorInfo* pErrorInfo = NULL;
    BSTR strSource;
    BSTR strDescription;
52
53
54
55
56
57
58
59
60
61

    rc = GetErrorInfo(0, &pErrorInfo);
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error: getting error info! rc = 0x%x\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
            rc
        );
    } else {
62
        rc = pErrorInfo->GetSource(&strSource);
63
        if (SUCCEEDED(rc) && strSource) {
64
65
            fprintf(
                stderr,
66
                "%s Error source: %S\n",
67
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
68
                strSource
69
            );
70
            SysFreeString(strSource);
71
        }
72
        rc = pErrorInfo->GetDescription(&strDescription);
73
        if (SUCCEEDED(rc) && strDescription) {
74
75
            fprintf(
                stderr,
76
                "%s Error description: %S\n",
77
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
78
                strDescription
79
            );
80
            SysFreeString(strDescription);
81
        }
82
        pErrorInfo->Release();
83
84
85
86
    }
}


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const char *MachineStateToName(MachineState State) 
{ 
    switch (State) 
    { 
        case MachineState_PoweredOff: 
            return "poweroff"; 
        case MachineState_Saved: 
            return "saved"; 
        case MachineState_Aborted: 
            return "aborted"; 
        case MachineState_Teleported: 
            return "teleported"; 
        case MachineState_Running: 
            return "running"; 
        case MachineState_Paused: 
            return "paused"; 
        case MachineState_Stuck: 
            return "gurumeditation"; 
        case MachineState_LiveSnapshotting: 
            return "livesnapshotting"; 
        case MachineState_Teleporting: 
            return "teleporting"; 
        case MachineState_Starting: 
            return "starting"; 
        case MachineState_Stopping: 
            return "stopping"; 
        case MachineState_Saving: 
            return "saving"; 
        case MachineState_Restoring: 
            return "restoring"; 
        case MachineState_TeleportingPausedVM: 
            return "teleportingpausedvm"; 
        case MachineState_TeleportingIn: 
            return "teleportingin"; 
        case MachineState_RestoringSnapshot: 
            return "restoringsnapshot"; 
        case MachineState_DeletingSnapshot: 
            return "deletingsnapshot"; 
        case MachineState_DeletingSnapshotOnline: 
            return "deletingsnapshotlive"; 
        case MachineState_DeletingSnapshotPaused: 
            return "deletingsnapshotlivepaused"; 
        case MachineState_SettingUp: 
            return "settingup"; 
        default: 
            break; 
    } 
    return "unknown"; 
} 


138
VBOX_VM::VBOX_VM() {
139
140
141
    VBOX_BASE::VBOX_BASE();
}

142
VBOX_VM::~VBOX_VM() {
143
144
145
146
    VBOX_BASE::~VBOX_BASE();
}


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
int VBOX_VM::initialize() {
    int rc = BOINC_SUCCESS;
    string old_path;
    string new_path;
    string command;
    string output;
    APP_INIT_DATA aid;
    bool force_sandbox = false;
    char buf[256];

    boinc_get_init_data_p(&aid);
    get_install_directory(virtualbox_install_directory);

    // Prep the environment so we can execute the vboxmanage application
    //
    // TODO: Fix for non-Windows environments if we ever find another platform
    // where vboxmanage is not already in the search path
    if (!virtualbox_install_directory.empty())
    {
        old_path = getenv("PATH");
        new_path = virtualbox_install_directory + ";" + old_path;

        if (!SetEnvironmentVariable("PATH", const_cast<char*>(new_path.c_str()))) {
            fprintf(
                stderr,
                "%s Failed to modify the search path.\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf))
            );
        }
    }

    // Determine the VirtualBox home directory.  Overwrite as needed.
    //
    if (getenv("VBOX_USER_HOME")) {
        virtualbox_home_directory = getenv("VBOX_USER_HOME");
    } else {
        // If the override environment variable isn't specified then
        // it is based of the current users HOME directory.
        virtualbox_home_directory = getenv("USERPROFILE");
        virtualbox_home_directory += "/.VirtualBox";
    }

    // Set the location in which the VirtualBox Configuration files can be
    // stored for this instance.
    if (aid.using_sandbox || force_sandbox) {
        virtualbox_home_directory = aid.project_dir;
        virtualbox_home_directory += "/../virtualbox";

        if (!boinc_file_exists(virtualbox_home_directory.c_str())) {
            boinc_mkdir(virtualbox_home_directory.c_str());
        }

        if (!SetEnvironmentVariable("VBOX_USER_HOME", const_cast<char*>(virtualbox_home_directory.c_str()))) {
            fprintf(
                stderr,
                "%s Failed to modify the search path.\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf))
            );
        }
    }

    // Initialize the COM subsystem.
    CoInitialize(NULL);

    // Instantiate the VirtualBox root object.
212
    rc = m_pVirtualBox.CoCreateInstance(CLSID_VirtualBox);
213
    if (FAILED(rc))
214
215
216
217
    {
        fprintf(
            stderr,
            "%s Error creating VirtualBox instance! rc = 0x%x\n",
218
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
219
220
221
222
223
224
            rc
        );
        return rc;
    }

    // Create the session object.
225
    rc = m_pSession.CoCreateInstance(CLSID_Session);
226
    if (FAILED(rc))
227
228
229
230
    {
        fprintf(
            stderr,
            "%s Error creating Session instance! rc = 0x%x\n",
231
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
232
233
234
235
236
237
238
239
            rc
        );
        return rc;
    }

    rc = get_version_information(virtualbox_version);
    if (rc) return rc;

240
    get_guest_additions(virtualbox_guest_additions);
241
242
243
244
245

    return rc;
}

int VBOX_VM::create_vm() {
Rom Walton's avatar
Rom Walton committed
246
247
248
    int retval = ERR_EXEC;
    HRESULT rc;
    char buf[256];
249
    APP_INIT_DATA aid;
Rom Walton's avatar
Rom Walton committed
250
    CComBSTR vm_machine_uuid;
251
    CComPtr<IMachine> pMachineRO;
252
253
    CComPtr<IMachine> pMachine;
    CComPtr<ISession> pSession;
Rom Walton's avatar
Rom Walton committed
254
255
256
    CComPtr<IBIOSSettings> pBIOSSettings;
    CComPtr<INetworkAdapter> pNetworkAdapter;
    CComPtr<INATEngine> pNATEngine;
257
    CComPtr<IUSBController> pUSBContoller;
258
259
260
261
    CComPtr<ISerialPort> pSerialPort1;
    CComPtr<ISerialPort> pSerialPort2;
    CComPtr<IParallelPort> pParallelPort1;
    CComPtr<IParallelPort> pParallelPort2;
Rom Walton's avatar
Rom Walton committed
262
263
264
265
266
267
    CComPtr<IAudioAdapter> pAudioAdapter;
    CComPtr<IStorageController> pDiskController;
    CComPtr<IStorageController> pFloppyController;
    CComPtr<IBandwidthControl> pBandwidthControl;
    CComPtr<IVRDEServer> pVRDEServer;
    ULONG lOHCICtrls = 0;
268
    bool disable_acceleration = false;
Rom Walton's avatar
Rom Walton committed
269
270
    string virtual_machine_slot_directory;
    string default_interface;
271
272
273
274
275

    boinc_get_init_data_p(&aid);
    get_slot_directory(virtual_machine_slot_directory);


276
277
278
279
280
281
282
283
284
285
286
287
288
    rc = pSession.CoCreateInstance(CLSID_Session);
    if (!SUCCEEDED(rc))
    {
        fprintf(
            stderr,
            "%s Error creating Session instance! rc = 0x%x\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
            rc
        );
        return rc;
    }


289
290
291
292
    // Reset VM name in case it was changed while deregistering a stale VM
    //
    vm_name = vm_master_name;

293
294
295
296
297
298
299
300
    fprintf(
        stderr,
        "%s Create VM. (%s, slot#%d) \n",
        vboxwrapper_msg_prefix(buf, sizeof(buf)),
        vm_name.c_str(),
        aid.slot
    );

301
302
303
304
305
306
307
308
309
310
311
312
313
314
    // Fixup chipset and drive controller information for known configurations
    //
    if (enable_isocontextualization) {
        if ("PIIX4" == vm_disk_controller_model) {
            fprintf(
                stderr,
                "%s Updating drive controller type and model for desired configuration.\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf))
            );
            vm_disk_controller_type = "sata";
            vm_disk_controller_model = "IntelAHCI";
        }
    }

Rom Walton's avatar
Rom Walton committed
315
    // Start the VM creation process
316
    //
Rom Walton's avatar
Rom Walton committed
317
    rc = m_pVirtualBox->CreateMachine(
318
        CComBSTR(string(virtual_machine_slot_directory + "\\" + vm_name + "\\" + vm_name + ".vbox").c_str()),
Rom Walton's avatar
Rom Walton committed
319
320
321
322
        CComBSTR(vm_name.c_str()),
        NULL,
        CComBSTR(os_name.c_str()),
        CComBSTR(""),
323
        &pMachineRO
Rom Walton's avatar
Rom Walton committed
324
325
326
327
328
    );
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error creating virtual machine instance! rc = 0x%x\n",
329
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
330
331
332
333
334
335
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
336

Rom Walton's avatar
Rom Walton committed
337
338
339
340
341
342
    // Register the VM. Note that this call also saves the VM config
    // to disk. It is also possible to save the VM settings but not
    // register the VM.
    //
    // Also note that due to current VirtualBox limitations, the machine
    // must be registered *before* we can attach hard disks to it.
343
    //
344
    rc = m_pVirtualBox->RegisterMachine(pMachineRO);
Rom Walton's avatar
Rom Walton committed
345
346
347
348
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error registering virtual machine! rc = 0x%x\n",
349
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
350
351
352
353
354
355
356
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
    
357
    rc = pMachineRO->LockMachine(pSession, LockType_Write);
Rom Walton's avatar
Rom Walton committed
358
359
360
361
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error locking virtual machine! rc = 0x%x\n",
362
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
363
364
365
366
367
368
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
369

370
    rc = pSession->get_Machine(&pMachine);
Rom Walton's avatar
Rom Walton committed
371
372
373
374
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving mutable virtual machine object! rc = 0x%x\n",
375
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
376
377
378
379
380
381
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
382

Rom Walton's avatar
Rom Walton committed
383

384
    rc = pMachine->get_BIOSSettings(&pBIOSSettings);
Rom Walton's avatar
Rom Walton committed
385
386
387
388
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving the BIOS settings for the virtual machine! rc = 0x%x\n",
389
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
390
391
392
393
394
395
396
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }

397
    rc = pMachine->get_BandwidthControl(&pBandwidthControl);
Rom Walton's avatar
Rom Walton committed
398
399
400
401
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving the Bandwidth Control settings for the virtual machine! rc = 0x%x\n",
402
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
403
404
405
406
407
408
409
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }

410
    rc = pMachine->get_VRDEServer(&pVRDEServer);
Rom Walton's avatar
Rom Walton committed
411
412
413
414
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving the Remote Desktop settings for the virtual machine! rc = 0x%x\n",
415
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
416
417
418
419
420
421
422
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }

423
    rc = pMachine->GetNetworkAdapter(0, &pNetworkAdapter);
Rom Walton's avatar
Rom Walton committed
424
425
426
427
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving the Network Adapter for the virtual machine! rc = 0x%x\n",
428
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
429
430
431
432
433
434
435
436
437
438
439
440
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }

    rc = pNetworkAdapter->get_NATEngine(&pNATEngine);
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving the NAT Engine for the virtual machine! rc = 0x%x\n",
441
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
442
443
444
445
446
447
448
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }

449
    rc = pMachine->get_AudioAdapter(&pAudioAdapter);
Rom Walton's avatar
Rom Walton committed
450
451
452
453
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error retrieving the Audio Adapter for the virtual machine! rc = 0x%x\n",
454
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
455
456
457
458
459
460
461
462
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }

    // Set some properties
463
    pMachine->put_Description(CComBSTR(vm_master_description.c_str()));
Rom Walton's avatar
Rom Walton committed
464
465

    // Tweak the VM's Memory Size
466
467
468
    //
    fprintf(
        stderr,
Rom Walton's avatar
Rom Walton committed
469
        "%s Setting Memory Size for VM. (%dMB)\n",
470
        vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
471
        (int)memory_size_mb
472
    );
473
    rc = pMachine->put_MemorySize((int)(memory_size_mb));
Rom Walton's avatar
Rom Walton committed
474
475
476
477
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error memory size for the virtual machine! rc = 0x%x\n",
478
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
479
480
481
482
483
484
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
485

Rom Walton's avatar
Rom Walton committed
486
    // Tweak the VM's CPU Count
487
488
489
    //
    fprintf(
        stderr,
Rom Walton's avatar
Rom Walton committed
490
        "%s Setting CPU Count for VM. (%s)\n",
491
        vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
492
        vm_cpu_count.c_str()
493
    );
494
    rc = pMachine->put_CPUCount((int)atoi(vm_cpu_count.c_str()));
Rom Walton's avatar
Rom Walton committed
495
496
497
498
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error CPU count for the virtual machine! rc = 0x%x\n",
499
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
500
501
502
503
504
505
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
506
507
508
509
510
511
512
513

    // Tweak the VM's Chipset Options
    //
    fprintf(
        stderr,
        "%s Setting Chipset Options for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
Rom Walton's avatar
Rom Walton committed
514
515
516
517
518
    rc = pBIOSSettings->put_ACPIEnabled(TRUE);
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error setting ACPI enabled for the virtual machine! rc = 0x%x\n",
519
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
520
521
522
523
524
525
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
526

Rom Walton's avatar
Rom Walton committed
527
528
529
530
531
    rc = pBIOSSettings->put_IOAPICEnabled(TRUE);
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error setting IOAPIC enabled for the virtual machine! rc = 0x%x\n",
532
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
533
534
535
536
537
538
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
539
540
541
542
543
544
545
546

    // Tweak the VM's Boot Options
    //
    fprintf(
        stderr,
        "%s Setting Boot Options for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
547
    rc = pMachine->SetBootOrder(1, DeviceType_HardDisk);
Rom Walton's avatar
Rom Walton committed
548
549
550
551
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error setting hard disk boot order for the virtual machine! rc = 0x%x\n",
552
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
553
554
555
556
557
558
559
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
    
560
    rc = pMachine->SetBootOrder(2, DeviceType_DVD);
Rom Walton's avatar
Rom Walton committed
561
562
563
564
    if (FAILED(rc)) {
        fprintf(
            stderr,
            "%s Error setting DVD boot order for the virtual machine! rc = 0x%x\n",
565
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
566
567
568
569
570
571
            rc
        );
        virtualbox_dump_error();
        retval = rc;
        goto CLEANUP;
    }
572

573
574
    pMachine->SetBootOrder(3, DeviceType_Null);
    pMachine->SetBootOrder(4, DeviceType_Null);
575
576
577

    // Tweak the VM's Network Configuration
    //
578
579
    if (enable_network) {

Rom Walton's avatar
Rom Walton committed
580
581
        fprintf(
            stderr,
582
583
            "%s Enabling VM Network Access.\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf))
Rom Walton's avatar
Rom Walton committed
584
        );
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
        rc = pNetworkAdapter->put_Enabled(TRUE);
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error enabling network access for the virtual machine! rc = 0x%x\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }

    } else {

        fprintf(
            stderr,
            "%s Disabling VM Network Access.\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf))
        );
        rc = pNetworkAdapter->put_Enabled(FALSE);
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error disabling network access for the virtual machine! rc = 0x%x\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }

Rom Walton's avatar
Rom Walton committed
618
619
    }

620
    if (network_bridged_mode) {
Rom Walton's avatar
Rom Walton committed
621

622
623
624
625
626
        fprintf(
            stderr,
            "%s Setting Network Configuration for Bridged Mode.\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf))
        );
Rom Walton's avatar
Rom Walton committed
627
628
629
630
631
        rc = pNetworkAdapter->put_AttachmentType(NetworkAttachmentType_Bridged);
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error setting network configuration for the virtual machine! rc = 0x%x\n",
632
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
633
634
635
636
637
638
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
639
640
641
642
643
644
645
646

        get_default_network_interface(default_interface);
        fprintf(
            stderr,
            "%s Setting Bridged Interface. (%s)\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
            default_interface.c_str()
        );
Rom Walton's avatar
Rom Walton committed
647
648
649
650
651
        rc = pNetworkAdapter->put_BridgedInterface(CComBSTR(CA2W(default_interface.c_str())));
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error setting network configuration (brigded interface) for the virtual machine! rc = 0x%x\n",
652
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
653
654
655
656
657
658
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
659
660

    } else {
Rom Walton's avatar
Rom Walton committed
661

662
663
664
665
666
        fprintf(
            stderr,
            "%s Setting Network Configuration for NAT.\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf))
        );
Rom Walton's avatar
Rom Walton committed
667
668
669
670
671
        rc = pNetworkAdapter->put_AttachmentType(NetworkAttachmentType_NAT);
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error setting network configuration for the virtual machine! rc = 0x%x\n",
672
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
673
674
675
676
677
678
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
679

Rom Walton's avatar
Rom Walton committed
680
681
682
683
684
        rc = pNATEngine->put_DNSProxy(TRUE);
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error setting network configuration (DNS Proxy) for the virtual machine! rc = 0x%x\n",
685
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
686
687
688
689
690
691
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
692
693
694
695
696
697
698
699
700
    }

    // Tweak the VM's USB Configuration
    //
    fprintf(
        stderr,
        "%s Disabling USB Support for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
701
#ifdef _VIRTUALBOX43_
702
    rc = pMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &lOHCICtrls);
Rom Walton's avatar
Rom Walton committed
703
    if (SUCCEEDED(rc) && lOHCICtrls) {
704
        pMachine->RemoveUSBController(CComBSTR("OHCI"));
Rom Walton's avatar
Rom Walton committed
705
    }
706
707
708
709
710
711
712
#endif
#ifdef _VIRTUALBOX42_
    rc = pMachine->get_USBController(&pUSBContoller);
    if (SUCCEEDED(rc)) {
        pUSBContoller->put_Enabled(FALSE);
    }
#endif
713
714
715
716
717
718
719
720

    // Tweak the VM's COM Port Support
    //
    fprintf(
        stderr,
        "%s Disabling COM Port Support for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
721
    rc = pMachine->GetSerialPort(0, &pSerialPort1);
Rom Walton's avatar
Rom Walton committed
722
    if (SUCCEEDED(rc)) {
723
        pSerialPort1->put_Enabled(FALSE);
Rom Walton's avatar
Rom Walton committed
724
    }
725
    rc = pMachine->GetSerialPort(1, &pSerialPort2);
Rom Walton's avatar
Rom Walton committed
726
    if (SUCCEEDED(rc)) {
727
        pSerialPort2->put_Enabled(FALSE);
Rom Walton's avatar
Rom Walton committed
728
    }
729
730
731
732
733
734
735
736

    // Tweak the VM's LPT Port Support
    //
    fprintf(
        stderr,
        "%s Disabling LPT Port Support for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
737
    rc = pMachine->GetParallelPort(0, &pParallelPort1);
Rom Walton's avatar
Rom Walton committed
738
    if (SUCCEEDED(rc)) {
739
        pParallelPort1->put_Enabled(FALSE);
Rom Walton's avatar
Rom Walton committed
740
    }
741
    rc = pMachine->GetParallelPort(1, &pParallelPort2);
Rom Walton's avatar
Rom Walton committed
742
    if (SUCCEEDED(rc)) {
743
        pParallelPort2->put_Enabled(FALSE);
Rom Walton's avatar
Rom Walton committed
744
    }
745
746
747
748
749
750
751
752

    // Tweak the VM's Audio Support
    //
    fprintf(
        stderr,
        "%s Disabling Audio Support for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
Rom Walton's avatar
Rom Walton committed
753
    pAudioAdapter->put_Enabled(FALSE);
754
755
756
757
758
759
760
761

    // Tweak the VM's Clipboard Support
    //
    fprintf(
        stderr,
        "%s Disabling Clipboard Support for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
762
    pMachine->put_ClipboardMode(ClipboardMode_Disabled);
763
764
765
766
767
768
769
770

    // Tweak the VM's Drag & Drop Support
    //
    fprintf(
        stderr,
        "%s Disabling Drag and Drop Support for VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
771
    pMachine->put_DragAndDropMode(DragAndDropMode_Disabled);
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

    // Check to see if the processor supports hardware acceleration for virtualization
    // If it doesn't, disable the use of it in VirtualBox. Multi-core jobs require hardware
    // acceleration and actually override this setting.
    //
    if (!strstr(aid.host_info.p_features, "vmx") && !strstr(aid.host_info.p_features, "svm")) {
        fprintf(
            stderr,
            "%s Hardware acceleration CPU extensions not detected. Disabling VirtualBox hardware acceleration support.\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf))
        );
        disable_acceleration = true;
    }
    if (strstr(aid.host_info.p_features, "hypervisor")) {
        fprintf(
            stderr,
            "%s Running under Hypervisor. Disabling VirtualBox hardware acceleration support.\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf))
        );
        disable_acceleration = true;
    }
    if (is_boinc_client_version_newer(aid, 7, 2, 16)) {
        if (aid.vm_extensions_disabled) {
            fprintf(
                stderr,
                "%s Hardware acceleration failed with previous execution. Disabling VirtualBox hardware acceleration support.\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf))
            );
            disable_acceleration = true;
        }
    } else {
        if (vm_cpu_count == "1") {
            // Keep this around for older clients.  Removing this for older clients might
            // lead to a machine that will only return crashed VM reports.
            vboxwrapper_msg_prefix(buf, sizeof(buf));
            fprintf(
                stderr,
                "%s Legacy fallback configuration detected. Disabling VirtualBox hardware acceleration support.\n"
                "%s NOTE: Upgrading to BOINC 7.2.16 or better may re-enable hardware acceleration.\n",
                buf,
                buf
            );
            disable_acceleration = true;
        }
    }
Rom Walton's avatar
Rom Walton committed
817
818
819
820
821
822
823
824
825
826

    // Only allow disabling of hardware acceleration on 32-bit VM types, 64-bit VM types require it.
    //
    if (os_name.find("_64") == std::string::npos) {
        if (disable_acceleration) {
            fprintf(
                stderr,
                "%s Disabling hardware acceleration support for virtualization.\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf))
            );
827
            rc = pMachine->SetHWVirtExProperty(HWVirtExPropertyType_Enabled, FALSE);
Rom Walton's avatar
Rom Walton committed
828
829
830
831
            if (FAILED(rc)) {
                fprintf(
                    stderr,
                    "%s Error disabling hardware acceleration support for the virtual machine! rc = 0x%x\n",
832
                    vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
833
834
835
836
837
838
839
840
841
842
843
844
845
846
                    rc
                );
                virtualbox_dump_error();
                retval = rc;
                goto CLEANUP;
            }
        }
    } else if (os_name.find("_64") != std::string::npos) {
        if (disable_acceleration) {
            fprintf(
                stderr,
                "%s ERROR: Invalid configuration.  VM type requires acceleration but the current configuration cannot support it.\n",
                vboxwrapper_msg_prefix(buf, sizeof(buf))
            );
847
848
            retval = ERR_INVALID_PARAM;
            goto CLEANUP;
Rom Walton's avatar
Rom Walton committed
849
850
851
852
853
854
855
856
857
858
859
860
861
        }
    }

    // Add storage controller to VM
    // See: http://www.virtualbox.org/manual/ch08.html#vboxmanage-storagectl
    // See: http://www.virtualbox.org/manual/ch05.html#iocaching
    //
    fprintf(
        stderr,
        "%s Adding storage controller(s) to VM.\n",
        vboxwrapper_msg_prefix(buf, sizeof(buf))
    );
    if (0 == stricmp(vm_disk_controller_type.c_str(), "ide")) {
862
        rc = pMachine->AddStorageController(CComBSTR("Hard Disk Controller"), StorageBus_IDE, &pDiskController);
Rom Walton's avatar
Rom Walton committed
863
864
865
866
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error adding storage controller (IDE) to the virtual machine! rc = 0x%x\n",
867
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
868
869
870
871
872
873
874
875
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
    }
    if (0 == stricmp(vm_disk_controller_type.c_str(), "sata")) {
876
        rc = pMachine->AddStorageController(CComBSTR("Hard Disk Controller"), StorageBus_SATA, &pDiskController);
Rom Walton's avatar
Rom Walton committed
877
878
879
880
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error adding storage controller (SATA) to the virtual machine! rc = 0x%x\n",
881
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
882
883
884
885
886
887
888
889
890
891
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
        pDiskController->put_UseHostIOCache(FALSE);
        pDiskController->put_PortCount(3);
    }
    if (0 == stricmp(vm_disk_controller_type.c_str(), "sas")) {
892
        rc = pMachine->AddStorageController(CComBSTR("Hard Disk Controller"), StorageBus_SAS, &pDiskController);
Rom Walton's avatar
Rom Walton committed
893
        if (FAILED(rc)) {
894
895
            fprintf(
                stderr,
Rom Walton's avatar
Rom Walton committed
896
                "%s Error adding storage controller (SAS) to the virtual machine! rc = 0x%x\n",
897
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
898
                rc
899
            );
Rom Walton's avatar
Rom Walton committed
900
901
902
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
903
        }
Rom Walton's avatar
Rom Walton committed
904
905
906
        pDiskController->put_UseHostIOCache(FALSE);
    }
    if (0 == stricmp(vm_disk_controller_type.c_str(), "scsi")) {
907
        rc = pMachine->AddStorageController(CComBSTR("Hard Disk Controller"), StorageBus_SCSI, &pDiskController);
Rom Walton's avatar
Rom Walton committed
908
        if (FAILED(rc)) {
909
910
            fprintf(
                stderr,
Rom Walton's avatar
Rom Walton committed
911
                "%s Error adding storage controller (SCSI) to the virtual machine! rc = 0x%x\n",
912
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
913
                rc
914
            );
Rom Walton's avatar
Rom Walton committed
915
916
917
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
918
        }
Rom Walton's avatar
Rom Walton committed
919
        pDiskController->put_UseHostIOCache(FALSE);
920
921
    }

Rom Walton's avatar
Rom Walton committed
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
    if (0 == stricmp(vm_disk_controller_model.c_str(), "lsilogic")) {
        pDiskController->put_ControllerType(StorageControllerType_LsiLogic);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "buslogic")) {
        pDiskController->put_ControllerType(StorageControllerType_BusLogic);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "intelahci")) {
        pDiskController->put_ControllerType(StorageControllerType_IntelAhci);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "piix3")) {
        pDiskController->put_ControllerType(StorageControllerType_PIIX3);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "piix4")) {
        pDiskController->put_ControllerType(StorageControllerType_PIIX4);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "ich6")) {
        pDiskController->put_ControllerType(StorageControllerType_ICH6);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "i82078")) {
        pDiskController->put_ControllerType(StorageControllerType_I82078);
    } else if (0 == stricmp(vm_disk_controller_model.c_str(), "lsilogicsas")) {
        pDiskController->put_ControllerType(StorageControllerType_LsiLogicSas);
938
939
940
941
942
    }

    // Add storage controller for a floppy device if desired
    //
    if (enable_floppyio) {
943
        rc = pMachine->AddStorageController(CComBSTR("Floppy Controller"), StorageBus_Floppy, &pFloppyController);
Rom Walton's avatar
Rom Walton committed
944
945
946
947
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error adding storage controller (Floppy) to the virtual machine! rc = 0x%x\n",
948
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
949
950
951
952
953
954
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
955
956
957
958
959
960
961
962
963
964
965
966
    }

    if (enable_isocontextualization) {

        // Add virtual ISO 9660 disk drive to VM
        //
        fprintf(
            stderr,
            "%s Adding virtual ISO 9660 disk drive to VM. (%s)\n",
            vboxwrapper_msg_prefix(buf, sizeof(buf)),
            iso_image_filename.c_str()
        );
Rom Walton's avatar
Rom Walton committed
967
968
        CComPtr<IMedium> pISOImage;
        rc = m_pVirtualBox->OpenMedium(
969
            CComBSTR(string(virtual_machine_slot_directory + "\\" + iso_image_filename).c_str()),
Rom Walton's avatar
Rom Walton committed
970
971
972
973
974
975
976
977
978
            DeviceType_DVD,
            AccessMode_ReadOnly,
            FALSE,
            &pISOImage
        );
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error adding virtual ISO 9660 disk drive to VirtualBox! rc = 0x%x\n",
979
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
980
981
982
983
984
985
                rc
            );
            virtualbox_dump_error();
            retval = rc;
            goto CLEANUP;
        }
986

987
        rc = pMachine->AttachDevice(
Rom Walton's avatar
Rom Walton committed
988
989
990
991
992
993
994
995
996
997
            CComBSTR("Hard Disk Controller"),
            0,
            0,
            DeviceType_DVD,
            pISOImage
        );
        if (FAILED(rc)) {
            fprintf(
                stderr,
                "%s Error adding virtual ISO 9660 disk drive to virtual machine! rc = 0x%x\n",
998
                vboxwrapper_msg_prefix(buf, sizeof(buf)),
Rom Walton's avatar
Rom Walton committed
999
1000
                rc
            );
For faster browsing, not all history is shown. View entire blame