VirtualBox

source: vbox/trunk/src/VBox/Main/ConsoleImpl2.cpp@ 8251

Last change on this file since 8251 was 8241, checked in by vboxsync, 17 years ago

Rebrand the iSCSI initiator name. Should be harmless, as normally no iSCSI target is configured to check for a particular initiator name.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 81.4 KB
Line 
1/** $Id: ConsoleImpl2.cpp 8241 2008-04-21 15:35:36Z vboxsync $ */
2/** @file
3 * VBox Console COM Class implementation
4 *
5 * @remark We've split out the code that the 64-bit VC++ v8 compiler
6 * finds problematic to optimize so we can disable optimizations
7 * and later, perhaps, find a real solution for it.
8 */
9
10/*
11 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 (GPL) as published by the Free Software
17 * Foundation, in version 2 as it comes in the "COPYING" file of the
18 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
22 * Clara, CA 95054 USA or visit http://www.sun.com if you need
23 * additional information or have any questions.
24 */
25
26/*******************************************************************************
27* Header Files *
28*******************************************************************************/
29#include "ConsoleImpl.h"
30#include "DisplayImpl.h"
31#include "VMMDev.h"
32
33// generated header
34#include "SchemaDefs.h"
35
36#include "Logging.h"
37
38#include <iprt/string.h>
39#include <iprt/path.h>
40#include <iprt/dir.h>
41#include <iprt/param.h>
42
43#include <VBox/vmapi.h>
44#include <VBox/err.h>
45#include <VBox/version.h>
46#include <VBox/HostServices/VBoxClipboardSvc.h>
47
48
49/*
50 * VC++ 8 / amd64 has some serious trouble with this function.
51 * As a temporary measure, we'll drop global optimizations.
52 */
53#if defined(_MSC_VER) && defined(RT_ARCH_AMD64)
54# pragma optimize("g", off)
55#endif
56
57/**
58 * Construct the VM configuration tree (CFGM).
59 *
60 * This is a callback for VMR3Create() call. It is called from CFGMR3Init()
61 * in the emulation thread (EMT). Any per thread COM/XPCOM initialization
62 * is done here.
63 *
64 * @param pVM VM handle.
65 * @param pvConsole Pointer to the VMPowerUpTask object.
66 * @return VBox status code.
67 *
68 * @note Locks the Console object for writing.
69 */
70DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole)
71{
72 LogFlowFuncEnter();
73 /* Note: hardcoded assumption about number of slots; see rom bios */
74 bool afPciDeviceNo[15] = {false};
75
76#if !defined (VBOX_WITH_XPCOM)
77 {
78 /* initialize COM */
79 HRESULT hrc = CoInitializeEx(NULL,
80 COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE |
81 COINIT_SPEED_OVER_MEMORY);
82 LogFlow (("Console::configConstructor(): CoInitializeEx()=%08X\n", hrc));
83 AssertComRCReturn (hrc, VERR_GENERAL_FAILURE);
84 }
85#endif
86
87 AssertReturn (pvConsole, VERR_GENERAL_FAILURE);
88 ComObjPtr <Console> pConsole = static_cast <Console *> (pvConsole);
89
90 AutoCaller autoCaller (pConsole);
91 AssertComRCReturn (autoCaller.rc(), VERR_ACCESS_DENIED);
92
93 /* lock the console because we widely use internal fields and methods */
94 AutoWriteLock alock (pConsole);
95
96 ComPtr <IMachine> pMachine = pConsole->machine();
97
98 int rc;
99 HRESULT hrc;
100 char *psz = NULL;
101 BSTR str = NULL;
102
103#define STR_CONV() do { rc = RTUtf16ToUtf8(str, &psz); RC_CHECK(); } while (0)
104#define STR_FREE() do { if (str) { SysFreeString(str); str = NULL; } if (psz) { RTStrFree(psz); psz = NULL; } } while (0)
105#define RC_CHECK() do { if (VBOX_FAILURE(rc)) { AssertMsgFailed(("rc=%Vrc\n", rc)); STR_FREE(); return rc; } } while (0)
106#define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%#x\n", hrc)); STR_FREE(); return VERR_GENERAL_FAILURE; } } while (0)
107
108 /*
109 * Get necessary objects and frequently used parameters.
110 */
111 ComPtr<IVirtualBox> virtualBox;
112 hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); H();
113
114 ComPtr<IHost> host;
115 hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); H();
116
117 ComPtr <ISystemProperties> systemProperties;
118 hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam()); H();
119
120 ComPtr<IBIOSSettings> biosSettings;
121 hrc = pMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); H();
122
123 Guid uuid;
124 hrc = pMachine->COMGETTER(Id)(uuid.asOutParam()); H();
125 PCRTUUID pUuid = uuid.raw();
126
127 ULONG cRamMBs;
128 hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs); H();
129
130
131 /*
132 * Get root node first.
133 * This is the only node in the tree.
134 */
135 PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
136 Assert(pRoot);
137
138 /*
139 * Set the root level values.
140 */
141 hrc = pMachine->COMGETTER(Name)(&str); H();
142 STR_CONV();
143 rc = CFGMR3InsertString(pRoot, "Name", psz); RC_CHECK();
144 STR_FREE();
145 rc = CFGMR3InsertBytes(pRoot, "UUID", pUuid, sizeof(*pUuid)); RC_CHECK();
146 rc = CFGMR3InsertInteger(pRoot, "RamSize", cRamMBs * _1M); RC_CHECK();
147 rc = CFGMR3InsertInteger(pRoot, "TimerMillies", 10); RC_CHECK();
148 rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled", 1); /* boolean */ RC_CHECK();
149 rc = CFGMR3InsertInteger(pRoot, "RawR0Enabled", 1); /* boolean */ RC_CHECK();
150 /** @todo Config: RawR0, PATMEnabled and CASMEnabled needs attention later. */
151 rc = CFGMR3InsertInteger(pRoot, "PATMEnabled", 1); /* boolean */ RC_CHECK();
152 rc = CFGMR3InsertInteger(pRoot, "CSAMEnabled", 1); /* boolean */ RC_CHECK();
153
154 /* hardware virtualization extensions */
155 TSBool_T hwVirtExEnabled;
156 BOOL fHWVirtExEnabled;
157 hrc = pMachine->COMGETTER(HWVirtExEnabled)(&hwVirtExEnabled); H();
158 if (hwVirtExEnabled == TSBool_Default)
159 {
160 /* check the default value */
161 hrc = systemProperties->COMGETTER(HWVirtExEnabled)(&fHWVirtExEnabled); H();
162 }
163 else
164 fHWVirtExEnabled = (hwVirtExEnabled == TSBool_True);
165#ifndef RT_OS_DARWIN /** @todo Implement HWVirtExt on darwin. See #1865. */
166 if (fHWVirtExEnabled)
167 {
168 PCFGMNODE pHWVirtExt;
169 rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHWVirtExt); RC_CHECK();
170 rc = CFGMR3InsertInteger(pHWVirtExt, "Enabled", 1); RC_CHECK();
171 }
172#endif
173
174 /* Physical Address Extension (PAE) */
175 BOOL fEnablePAE = false;
176 hrc = pMachine->COMGETTER(PAEEnabled)(&fEnablePAE); H();
177 rc = CFGMR3InsertInteger(pRoot, "EnablePAE", fEnablePAE); RC_CHECK();
178
179 BOOL fIOAPIC;
180 hrc = biosSettings->COMGETTER(IOAPICEnabled)(&fIOAPIC); H();
181
182 BOOL fPXEDebug;
183 hrc = biosSettings->COMGETTER(PXEDebugEnabled)(&fPXEDebug); H();
184
185 /*
186 * Virtual IDE controller type.
187 */
188 IDEControllerType_T controllerType;
189 BOOL fPIIX4;
190 hrc = biosSettings->COMGETTER(IDEControllerType)(&controllerType); H();
191 switch (controllerType)
192 {
193 case IDEControllerType_PIIX3:
194 fPIIX4 = FALSE;
195 break;
196 case IDEControllerType_PIIX4:
197 fPIIX4 = TRUE;
198 break;
199 default:
200 AssertMsgFailed(("Invalid IDE controller type '%d'", controllerType));
201 return VERR_INVALID_PARAMETER;
202 }
203
204 /*
205 * PDM config.
206 * Load drivers in VBoxC.[so|dll]
207 */
208 PCFGMNODE pPDM;
209 PCFGMNODE pDrivers;
210 PCFGMNODE pMod;
211 rc = CFGMR3InsertNode(pRoot, "PDM", &pPDM); RC_CHECK();
212 rc = CFGMR3InsertNode(pPDM, "Drivers", &pDrivers); RC_CHECK();
213 rc = CFGMR3InsertNode(pDrivers, "VBoxC", &pMod); RC_CHECK();
214#ifdef VBOX_WITH_XPCOM
215 // VBoxC is located in the components subdirectory
216 char szPathVBoxC[RTPATH_MAX];
217 rc = RTPathAppPrivateArch(szPathVBoxC, RTPATH_MAX - sizeof("/components/VBoxC")); AssertRC(rc);
218 strcat(szPathVBoxC, "/components/VBoxC");
219 rc = CFGMR3InsertString(pMod, "Path", szPathVBoxC); RC_CHECK();
220#else
221 rc = CFGMR3InsertString(pMod, "Path", "VBoxC"); RC_CHECK();
222#endif
223
224 /*
225 * Devices
226 */
227 PCFGMNODE pDevices = NULL; /* /Devices */
228 PCFGMNODE pDev = NULL; /* /Devices/Dev/ */
229 PCFGMNODE pInst = NULL; /* /Devices/Dev/0/ */
230 PCFGMNODE pCfg = NULL; /* /Devices/Dev/.../Config/ */
231 PCFGMNODE pLunL0 = NULL; /* /Devices/Dev/0/LUN#0/ */
232 PCFGMNODE pLunL1 = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
233 PCFGMNODE pLunL2 = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/Config/ */
234 PCFGMNODE pIdeInst = NULL; /* /Devices/piix3ide/0/ */
235 PCFGMNODE pSataInst = NULL; /* /Devices/ahci/0/ */
236 PCFGMNODE pBiosCfg = NULL; /* /Devices/pcbios/0/Config/ */
237
238 rc = CFGMR3InsertNode(pRoot, "Devices", &pDevices); RC_CHECK();
239
240 /*
241 * PC Arch.
242 */
243 rc = CFGMR3InsertNode(pDevices, "pcarch", &pDev); RC_CHECK();
244 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
245 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
246 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
247
248 /*
249 * PC Bios.
250 */
251 rc = CFGMR3InsertNode(pDevices, "pcbios", &pDev); RC_CHECK();
252 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
253 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
254 rc = CFGMR3InsertNode(pInst, "Config", &pBiosCfg); RC_CHECK();
255 rc = CFGMR3InsertInteger(pBiosCfg, "RamSize", cRamMBs * _1M); RC_CHECK();
256 rc = CFGMR3InsertString(pBiosCfg, "HardDiskDevice", "piix3ide"); RC_CHECK();
257 rc = CFGMR3InsertString(pBiosCfg, "FloppyDevice", "i82078"); RC_CHECK();
258 rc = CFGMR3InsertInteger(pBiosCfg, "IOAPIC", fIOAPIC); RC_CHECK();
259 rc = CFGMR3InsertInteger(pBiosCfg, "PXEDebug", fPXEDebug); RC_CHECK();
260 rc = CFGMR3InsertBytes(pBiosCfg, "UUID", pUuid, sizeof(*pUuid)); RC_CHECK();
261
262 DeviceType_T bootDevice;
263 if (SchemaDefs::MaxBootPosition > 9)
264 {
265 AssertMsgFailed (("Too many boot devices %d\n",
266 SchemaDefs::MaxBootPosition));
267 return VERR_INVALID_PARAMETER;
268 }
269
270 for (ULONG pos = 1; pos <= SchemaDefs::MaxBootPosition; pos ++)
271 {
272 hrc = pMachine->GetBootOrder(pos, &bootDevice); H();
273
274 char szParamName[] = "BootDeviceX";
275 szParamName[sizeof (szParamName) - 2] = ((char (pos - 1)) + '0');
276
277 const char *pszBootDevice;
278 switch (bootDevice)
279 {
280 case DeviceType_Null:
281 pszBootDevice = "NONE";
282 break;
283 case DeviceType_HardDisk:
284 pszBootDevice = "IDE";
285 break;
286 case DeviceType_DVD:
287 pszBootDevice = "DVD";
288 break;
289 case DeviceType_Floppy:
290 pszBootDevice = "FLOPPY";
291 break;
292 case DeviceType_Network:
293 pszBootDevice = "LAN";
294 break;
295 default:
296 AssertMsgFailed(("Invalid bootDevice=%d\n", bootDevice));
297 return VERR_INVALID_PARAMETER;
298 }
299 rc = CFGMR3InsertString(pBiosCfg, szParamName, pszBootDevice); RC_CHECK();
300 }
301
302 /*
303 * The time offset
304 */
305 LONG64 timeOffset;
306 hrc = biosSettings->COMGETTER(TimeOffset)(&timeOffset); H();
307 PCFGMNODE pTMNode;
308 rc = CFGMR3InsertNode(pRoot, "TM", &pTMNode); RC_CHECK();
309 rc = CFGMR3InsertInteger(pTMNode, "UTCOffset", timeOffset * 1000000); RC_CHECK();
310
311 /*
312 * ACPI
313 */
314 BOOL fACPI;
315 hrc = biosSettings->COMGETTER(ACPIEnabled)(&fACPI); H();
316 if (fACPI)
317 {
318 rc = CFGMR3InsertNode(pDevices, "acpi", &pDev); RC_CHECK();
319 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
320 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
321 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
322 rc = CFGMR3InsertInteger(pCfg, "RamSize", cRamMBs * _1M); RC_CHECK();
323 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); RC_CHECK();
324 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 7); RC_CHECK();
325 Assert(!afPciDeviceNo[7]);
326 afPciDeviceNo[7] = true;
327 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
328
329 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
330 rc = CFGMR3InsertString(pLunL0, "Driver", "ACPIHost"); RC_CHECK();
331 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
332 }
333
334 /*
335 * DMA
336 */
337 rc = CFGMR3InsertNode(pDevices, "8237A", &pDev); RC_CHECK();
338 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
339 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
340
341 /*
342 * PCI bus.
343 */
344 rc = CFGMR3InsertNode(pDevices, "pci", &pDev); /* piix3 */ RC_CHECK();
345 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
346 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
347 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
348 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); RC_CHECK();
349
350 /*
351 * PS/2 keyboard & mouse.
352 */
353 rc = CFGMR3InsertNode(pDevices, "pckbd", &pDev); RC_CHECK();
354 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
355 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
356 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
357
358 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
359 rc = CFGMR3InsertString(pLunL0, "Driver", "KeyboardQueue"); RC_CHECK();
360 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
361 rc = CFGMR3InsertInteger(pCfg, "QueueSize", 64); RC_CHECK();
362
363 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
364 rc = CFGMR3InsertString(pLunL1, "Driver", "MainKeyboard"); RC_CHECK();
365 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
366 Keyboard *pKeyboard = pConsole->mKeyboard;
367 rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pKeyboard); RC_CHECK();
368
369 rc = CFGMR3InsertNode(pInst, "LUN#1", &pLunL0); RC_CHECK();
370 rc = CFGMR3InsertString(pLunL0, "Driver", "MouseQueue"); RC_CHECK();
371 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
372 rc = CFGMR3InsertInteger(pCfg, "QueueSize", 128); RC_CHECK();
373
374 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
375 rc = CFGMR3InsertString(pLunL1, "Driver", "MainMouse"); RC_CHECK();
376 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
377 Mouse *pMouse = pConsole->mMouse;
378 rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pMouse); RC_CHECK();
379
380 /*
381 * i82078 Floppy drive controller
382 */
383 ComPtr<IFloppyDrive> floppyDrive;
384 hrc = pMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam()); H();
385 BOOL fFloppyEnabled;
386 hrc = floppyDrive->COMGETTER(Enabled)(&fFloppyEnabled); H();
387 if (fFloppyEnabled)
388 {
389 rc = CFGMR3InsertNode(pDevices, "i82078", &pDev); RC_CHECK();
390 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
391 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); RC_CHECK();
392 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
393 rc = CFGMR3InsertInteger(pCfg, "IRQ", 6); RC_CHECK();
394 rc = CFGMR3InsertInteger(pCfg, "DMA", 2); RC_CHECK();
395 rc = CFGMR3InsertInteger(pCfg, "MemMapped", 0 ); RC_CHECK();
396 rc = CFGMR3InsertInteger(pCfg, "IOBase", 0x3f0); RC_CHECK();
397
398 /* Attach the status driver */
399 rc = CFGMR3InsertNode(pInst, "LUN#999", &pLunL0); RC_CHECK();
400 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
401 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
402 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapFDLeds[0]); RC_CHECK();
403 rc = CFGMR3InsertInteger(pCfg, "First", 0); RC_CHECK();
404 rc = CFGMR3InsertInteger(pCfg, "Last", 0); RC_CHECK();
405
406 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
407
408 ComPtr<IFloppyImage> floppyImage;
409 hrc = floppyDrive->GetImage(floppyImage.asOutParam()); H();
410 if (floppyImage)
411 {
412 pConsole->meFloppyState = DriveState_ImageMounted;
413 rc = CFGMR3InsertString(pLunL0, "Driver", "Block"); RC_CHECK();
414 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
415 rc = CFGMR3InsertString(pCfg, "Type", "Floppy 1.44"); RC_CHECK();
416 rc = CFGMR3InsertInteger(pCfg, "Mountable", 1); RC_CHECK();
417
418 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
419 rc = CFGMR3InsertString(pLunL1, "Driver", "RawImage"); RC_CHECK();
420 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
421 hrc = floppyImage->COMGETTER(FilePath)(&str); H();
422 STR_CONV();
423 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
424 STR_FREE();
425 }
426 else
427 {
428 ComPtr<IHostFloppyDrive> hostFloppyDrive;
429 hrc = floppyDrive->GetHostDrive(hostFloppyDrive.asOutParam()); H();
430 if (hostFloppyDrive)
431 {
432 pConsole->meFloppyState = DriveState_HostDriveCaptured;
433 rc = CFGMR3InsertString(pLunL0, "Driver", "HostFloppy"); RC_CHECK();
434 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
435 hrc = hostFloppyDrive->COMGETTER(Name)(&str); H();
436 STR_CONV();
437 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
438 STR_FREE();
439 }
440 else
441 {
442 pConsole->meFloppyState = DriveState_NotMounted;
443 rc = CFGMR3InsertString(pLunL0, "Driver", "Block"); RC_CHECK();
444 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
445 rc = CFGMR3InsertString(pCfg, "Type", "Floppy 1.44"); RC_CHECK();
446 rc = CFGMR3InsertInteger(pCfg, "Mountable", 1); RC_CHECK();
447 }
448 }
449 }
450
451 /*
452 * i8254 Programmable Interval Timer And Dummy Speaker
453 */
454 rc = CFGMR3InsertNode(pDevices, "i8254", &pDev); RC_CHECK();
455 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
456 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
457#ifdef DEBUG
458 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
459#endif
460
461 /*
462 * i8259 Programmable Interrupt Controller.
463 */
464 rc = CFGMR3InsertNode(pDevices, "i8259", &pDev); RC_CHECK();
465 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
466 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
467 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
468
469 /*
470 * Advanced Programmable Interrupt Controller.
471 */
472 rc = CFGMR3InsertNode(pDevices, "apic", &pDev); RC_CHECK();
473 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
474 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
475 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
476 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); RC_CHECK();
477
478 if (fIOAPIC)
479 {
480 /*
481 * I/O Advanced Programmable Interrupt Controller.
482 */
483 rc = CFGMR3InsertNode(pDevices, "ioapic", &pDev); RC_CHECK();
484 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
485 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
486 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
487 }
488
489 /*
490 * RTC MC146818.
491 */
492 rc = CFGMR3InsertNode(pDevices, "mc146818", &pDev); RC_CHECK();
493 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
494 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
495
496 /*
497 * VGA.
498 */
499 rc = CFGMR3InsertNode(pDevices, "vga", &pDev); RC_CHECK();
500 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
501 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
502 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 2); RC_CHECK();
503 Assert(!afPciDeviceNo[2]);
504 afPciDeviceNo[2] = true;
505 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
506 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
507 hrc = pMachine->COMGETTER(VRAMSize)(&cRamMBs); H();
508 rc = CFGMR3InsertInteger(pCfg, "VRamSize", cRamMBs * _1M); RC_CHECK();
509
510 /*
511 * BIOS logo
512 */
513 BOOL fFadeIn;
514 hrc = biosSettings->COMGETTER(LogoFadeIn)(&fFadeIn); H();
515 rc = CFGMR3InsertInteger(pCfg, "FadeIn", fFadeIn ? 1 : 0); RC_CHECK();
516 BOOL fFadeOut;
517 hrc = biosSettings->COMGETTER(LogoFadeOut)(&fFadeOut); H();
518 rc = CFGMR3InsertInteger(pCfg, "FadeOut", fFadeOut ? 1: 0); RC_CHECK();
519 ULONG logoDisplayTime;
520 hrc = biosSettings->COMGETTER(LogoDisplayTime)(&logoDisplayTime); H();
521 rc = CFGMR3InsertInteger(pCfg, "LogoTime", logoDisplayTime); RC_CHECK();
522 Bstr logoImagePath;
523 hrc = biosSettings->COMGETTER(LogoImagePath)(logoImagePath.asOutParam()); H();
524 rc = CFGMR3InsertString(pCfg, "LogoFile", logoImagePath ? Utf8Str(logoImagePath) : ""); RC_CHECK();
525
526 /*
527 * Boot menu
528 */
529 BIOSBootMenuMode_T bootMenuMode;
530 int value;
531 biosSettings->COMGETTER(BootMenuMode)(&bootMenuMode);
532 switch (bootMenuMode)
533 {
534 case BIOSBootMenuMode_Disabled:
535 value = 0;
536 break;
537 case BIOSBootMenuMode_MenuOnly:
538 value = 1;
539 break;
540 default:
541 value = 2;
542 }
543 rc = CFGMR3InsertInteger(pCfg, "ShowBootMenu", value); RC_CHECK();
544
545 /* Custom VESA mode list */
546 unsigned cModes = 0;
547 for (unsigned iMode = 1; iMode <= 16; iMode++)
548 {
549 char szExtraDataKey[sizeof("CustomVideoModeXX")];
550 RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%d", iMode);
551 hrc = pMachine->GetExtraData(Bstr(szExtraDataKey), &str); H();
552 if (!str || !*str)
553 break;
554 STR_CONV();
555 rc = CFGMR3InsertString(pCfg, szExtraDataKey, psz);
556 STR_FREE();
557 cModes++;
558 }
559 rc = CFGMR3InsertInteger(pCfg, "CustomVideoModes", cModes);
560
561 /* VESA height reduction */
562 ULONG ulHeightReduction;
563 IFramebuffer *pFramebuffer = pConsole->getDisplay()->getFramebuffer();
564 if (pFramebuffer)
565 {
566 hrc = pFramebuffer->COMGETTER(HeightReduction)(&ulHeightReduction); H();
567 }
568 else
569 {
570 /* If framebuffer is not available, there is no height reduction. */
571 ulHeightReduction = 0;
572 }
573 rc = CFGMR3InsertInteger(pCfg, "HeightReduction", ulHeightReduction); RC_CHECK();
574
575 /* Attach the display. */
576 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
577 rc = CFGMR3InsertString(pLunL0, "Driver", "MainDisplay"); RC_CHECK();
578 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
579 Display *pDisplay = pConsole->mDisplay;
580 rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pDisplay); RC_CHECK();
581
582 /*
583 * IDE (update this when the main interface changes)
584 */
585 rc = CFGMR3InsertNode(pDevices, "piix3ide", &pDev); /* piix3 */ RC_CHECK();
586 rc = CFGMR3InsertNode(pDev, "0", &pIdeInst); RC_CHECK();
587 rc = CFGMR3InsertInteger(pIdeInst, "Trusted", 1); /* boolean */ RC_CHECK();
588 rc = CFGMR3InsertInteger(pIdeInst, "PCIDeviceNo", 1); RC_CHECK();
589 Assert(!afPciDeviceNo[1]);
590 afPciDeviceNo[1] = true;
591 rc = CFGMR3InsertInteger(pIdeInst, "PCIFunctionNo", 1); RC_CHECK();
592 rc = CFGMR3InsertNode(pIdeInst, "Config", &pCfg); RC_CHECK();
593 rc = CFGMR3InsertInteger(pCfg, "PIIX4", fPIIX4); /* boolean */ RC_CHECK();
594
595 /* Attach the status driver */
596 rc = CFGMR3InsertNode(pIdeInst, "LUN#999", &pLunL0); RC_CHECK();
597 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
598 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
599 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapIDELeds[0]);RC_CHECK();
600 rc = CFGMR3InsertInteger(pCfg, "First", 0); RC_CHECK();
601 rc = CFGMR3InsertInteger(pCfg, "Last", 3); RC_CHECK();
602
603 /*
604 * SATA controller
605 */
606 ComPtr<ISATAController> sataController;
607 hrc = pMachine->COMGETTER(SATAController)(sataController.asOutParam());
608 BOOL enabled = FALSE;
609
610 if (sataController)
611 {
612 hrc = sataController->COMGETTER(Enabled)(&enabled); H();
613
614 if (enabled)
615 {
616 rc = CFGMR3InsertNode(pDevices, "ahci", &pDev); RC_CHECK();
617 rc = CFGMR3InsertNode(pDev, "0", &pSataInst); RC_CHECK();
618 rc = CFGMR3InsertInteger(pSataInst, "Trusted", 1); RC_CHECK();
619 rc = CFGMR3InsertInteger(pSataInst, "PCIDeviceNo", 13); RC_CHECK();
620 Assert(!afPciDeviceNo[13]);
621 afPciDeviceNo[13] = true;
622 rc = CFGMR3InsertInteger(pSataInst, "PCIFunctionNo", 0); RC_CHECK();
623 rc = CFGMR3InsertNode(pSataInst, "Config", &pCfg); RC_CHECK();
624
625 ULONG cPorts = 0;
626 hrc = sataController->COMGETTER(PortCount)(&cPorts); H();
627 rc = CFGMR3InsertInteger(pCfg, "PortCount", cPorts); RC_CHECK();
628
629 /* Needed configuration values for the bios. */
630 rc = CFGMR3InsertString(pBiosCfg, "SataHardDiskDevice", "ahci"); RC_CHECK();
631
632 for (uint32_t i = 0; i < 4; i++)
633 {
634 static const char *s_apszConfig[4] =
635 { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
636 static const char *s_apszBiosConfig[4] =
637 { "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
638
639 LONG lPortNumber = -1;
640 hrc = sataController->GetIDEEmulationPort(i, &lPortNumber); H();
641 rc = CFGMR3InsertInteger(pCfg, s_apszConfig[i], lPortNumber); RC_CHECK();
642 rc = CFGMR3InsertInteger(pBiosCfg, s_apszBiosConfig[i], lPortNumber); RC_CHECK();
643 }
644
645 /* Attach the status driver */
646 rc = CFGMR3InsertNode(pSataInst,"LUN#999", &pLunL0); RC_CHECK();
647 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
648 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
649 AssertRelease(cPorts <= RT_ELEMENTS(pConsole->mapSATALeds));
650 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapSATALeds[0]); RC_CHECK();
651 rc = CFGMR3InsertInteger(pCfg, "First", 0); RC_CHECK();
652 rc = CFGMR3InsertInteger(pCfg, "Last", cPorts - 1); RC_CHECK();
653 }
654 }
655
656 /* Attach the harddisks */
657 ComPtr<IHardDiskAttachmentCollection> hdaColl;
658 hrc = pMachine->COMGETTER(HardDiskAttachments)(hdaColl.asOutParam()); H();
659 ComPtr<IHardDiskAttachmentEnumerator> hdaEnum;
660 hrc = hdaColl->Enumerate(hdaEnum.asOutParam()); H();
661
662 BOOL fMore = FALSE;
663 while ( SUCCEEDED(hrc = hdaEnum->HasMore(&fMore))
664 && fMore)
665 {
666 PCFGMNODE pHardDiskCtl;
667 ComPtr<IHardDiskAttachment> hda;
668 hrc = hdaEnum->GetNext(hda.asOutParam()); H();
669 ComPtr<IHardDisk> hardDisk;
670 hrc = hda->COMGETTER(HardDisk)(hardDisk.asOutParam()); H();
671 StorageBus_T enmBus;
672 hrc = hda->COMGETTER(Bus)(&enmBus); H();
673 LONG lDev;
674 hrc = hda->COMGETTER(Device)(&lDev); H();
675 LONG lChannel;
676 hrc = hda->COMGETTER(Channel)(&lChannel); H();
677
678 int iLUN;
679 switch (enmBus)
680 {
681 case StorageBus_IDE:
682 {
683 if (lChannel >= 2 || lChannel < 0)
684 {
685 AssertMsgFailed(("invalid controller channel number: %d\n", lChannel));
686 return VERR_GENERAL_FAILURE;
687 }
688
689 if (lDev >= 2 || lDev < 0)
690 {
691 AssertMsgFailed(("invalid controller device number: %d\n", lDev));
692 return VERR_GENERAL_FAILURE;
693 }
694 iLUN = 2*lChannel + lDev;
695 pHardDiskCtl = pIdeInst;
696 }
697 break;
698 case StorageBus_SATA:
699 iLUN = lChannel;
700 pHardDiskCtl = enabled ? pSataInst : NULL;
701 break;
702 default:
703 AssertMsgFailed(("invalid disk controller type: %d\n", enmBus));
704 return VERR_GENERAL_FAILURE;
705 }
706
707 /* Can be NULL if SATA controller is not enabled and current hard disk is attached to SATA controller. */
708 if (pHardDiskCtl)
709 {
710 char szLUN[16];
711 RTStrPrintf(szLUN, sizeof(szLUN), "LUN#%d", iLUN);
712 rc = CFGMR3InsertNode(pHardDiskCtl, szLUN, &pLunL0); RC_CHECK();
713 rc = CFGMR3InsertString(pLunL0, "Driver", "Block"); RC_CHECK();
714 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
715 rc = CFGMR3InsertString(pCfg, "Type", "HardDisk"); RC_CHECK();
716 rc = CFGMR3InsertInteger(pCfg, "Mountable", 0); RC_CHECK();
717
718 HardDiskStorageType_T hddType;
719 hardDisk->COMGETTER(StorageType)(&hddType);
720 if (hddType == HardDiskStorageType_VirtualDiskImage)
721 {
722 ComPtr<IVirtualDiskImage> vdiDisk = hardDisk;
723 AssertBreak (!vdiDisk.isNull(), hrc = E_FAIL);
724
725 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
726 rc = CFGMR3InsertString(pLunL1, "Driver", "VBoxHDD"); RC_CHECK();
727 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
728 hrc = vdiDisk->COMGETTER(FilePath)(&str); H();
729 STR_CONV();
730 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
731 STR_FREE();
732
733 /* Create an inversed tree of parents. */
734 ComPtr<IHardDisk> parentHardDisk = hardDisk;
735 for (PCFGMNODE pParent = pCfg;;)
736 {
737 ComPtr<IHardDisk> curHardDisk;
738 hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam()); H();
739 if (!curHardDisk)
740 break;
741
742 vdiDisk = curHardDisk;
743 AssertBreak (!vdiDisk.isNull(), hrc = E_FAIL);
744
745 PCFGMNODE pCur;
746 rc = CFGMR3InsertNode(pParent, "Parent", &pCur); RC_CHECK();
747 hrc = vdiDisk->COMGETTER(FilePath)(&str); H();
748 STR_CONV();
749 rc = CFGMR3InsertString(pCur, "Path", psz); RC_CHECK();
750 STR_FREE();
751 rc = CFGMR3InsertInteger(pCur, "ReadOnly", 1); RC_CHECK();
752
753 /* next */
754 pParent = pCur;
755 parentHardDisk = curHardDisk;
756 }
757 }
758 else if (hddType == HardDiskStorageType_ISCSIHardDisk)
759 {
760 ComPtr<IISCSIHardDisk> iSCSIDisk = hardDisk;
761 AssertBreak (!iSCSIDisk.isNull(), hrc = E_FAIL);
762
763 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
764 rc = CFGMR3InsertString(pLunL1, "Driver", "iSCSI"); RC_CHECK();
765 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
766
767 /* Set up the iSCSI initiator driver configuration. */
768 hrc = iSCSIDisk->COMGETTER(Target)(&str); H();
769 STR_CONV();
770 rc = CFGMR3InsertString(pCfg, "TargetName", psz); RC_CHECK();
771 STR_FREE();
772
773 // @todo currently there is no Initiator name config.
774 rc = CFGMR3InsertString(pCfg, "InitiatorName", "iqn.2008-04.com.sun.virtualbox.initiator"); RC_CHECK();
775
776 ULONG64 lun;
777 hrc = iSCSIDisk->COMGETTER(Lun)(&lun); H();
778 rc = CFGMR3InsertInteger(pCfg, "LUN", lun); RC_CHECK();
779
780 hrc = iSCSIDisk->COMGETTER(Server)(&str); H();
781 STR_CONV();
782 USHORT port;
783 hrc = iSCSIDisk->COMGETTER(Port)(&port); H();
784 if (port != 0)
785 {
786 char *pszTN;
787 RTStrAPrintf(&pszTN, "%s:%u", psz, port);
788 rc = CFGMR3InsertString(pCfg, "TargetAddress", pszTN); RC_CHECK();
789 RTStrFree(pszTN);
790 }
791 else
792 {
793 rc = CFGMR3InsertString(pCfg, "TargetAddress", psz); RC_CHECK();
794 }
795 STR_FREE();
796
797 hrc = iSCSIDisk->COMGETTER(UserName)(&str); H();
798 if (str)
799 {
800 STR_CONV();
801 rc = CFGMR3InsertString(pCfg, "InitiatorUsername", psz); RC_CHECK();
802 STR_FREE();
803 }
804
805 hrc = iSCSIDisk->COMGETTER(Password)(&str); H();
806 if (str)
807 {
808 STR_CONV();
809 rc = CFGMR3InsertString(pCfg, "InitiatorSecret", psz); RC_CHECK();
810 STR_FREE();
811 }
812
813 // @todo currently there is no target username config.
814 //rc = CFGMR3InsertString(pCfg, "TargetUsername", ""); RC_CHECK();
815
816 // @todo currently there is no target password config.
817 //rc = CFGMR3InsertString(pCfg, "TargetSecret", ""); RC_CHECK();
818
819 /* The iSCSI initiator needs an attached iSCSI transport driver. */
820 rc = CFGMR3InsertNode(pLunL1, "AttachedDriver", &pLunL2); RC_CHECK();
821 rc = CFGMR3InsertString(pLunL2, "Driver", "iSCSITCP"); RC_CHECK();
822 /* Currently the transport driver has no config options. */
823 }
824 else if (hddType == HardDiskStorageType_VMDKImage)
825 {
826 ComPtr<IVMDKImage> vmdkDisk = hardDisk;
827 AssertBreak (!vmdkDisk.isNull(), hrc = E_FAIL);
828
829 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
830#if 1 /* Enable new VD container code (and new VMDK), as the bugs are fixed. */
831 rc = CFGMR3InsertString(pLunL1, "Driver", "VD"); RC_CHECK();
832#else
833 rc = CFGMR3InsertString(pLunL1, "Driver", "VmdkHDD"); RC_CHECK();
834#endif
835 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
836 hrc = vmdkDisk->COMGETTER(FilePath)(&str); H();
837 STR_CONV();
838 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
839 STR_FREE();
840 rc = CFGMR3InsertString(pCfg, "Format", "VMDK"); RC_CHECK();
841 }
842 else if (hddType == HardDiskStorageType_CustomHardDisk)
843 {
844 ComPtr<ICustomHardDisk> customHardDisk = hardDisk;
845 AssertBreak (!customHardDisk.isNull(), hrc = E_FAIL);
846
847 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
848 rc = CFGMR3InsertString(pLunL1, "Driver", "VD"); RC_CHECK();
849 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
850 hrc = customHardDisk->COMGETTER(Location)(&str); H();
851 STR_CONV();
852 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
853 STR_FREE();
854 hrc = customHardDisk->COMGETTER(Format)(&str); H();
855 STR_CONV();
856 rc = CFGMR3InsertString(pCfg, "Format", psz); RC_CHECK();
857 STR_FREE();
858 }
859 else if (hddType == HardDiskStorageType_VHDImage)
860 {
861 ComPtr<IVHDImage> vhdDisk = hardDisk;
862 AssertBreak (!vhdDisk.isNull(), hrc = E_FAIL);
863
864 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
865 rc = CFGMR3InsertString(pLunL1, "Driver", "VD"); RC_CHECK();
866 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
867 hrc = vhdDisk->COMGETTER(FilePath)(&str); H();
868 STR_CONV();
869 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
870 rc = CFGMR3InsertString(pCfg, "Format", "VHD"); RC_CHECK();
871 STR_FREE();
872 }
873 else
874 AssertFailed();
875 }
876 }
877 H();
878
879 ComPtr<IDVDDrive> dvdDrive;
880 hrc = pMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam()); H();
881 if (dvdDrive)
882 {
883 // ASSUME: DVD drive is always attached to LUN#2 (i.e. secondary IDE master)
884 rc = CFGMR3InsertNode(pIdeInst, "LUN#2", &pLunL0); RC_CHECK();
885 ComPtr<IHostDVDDrive> hostDvdDrive;
886 hrc = dvdDrive->GetHostDrive(hostDvdDrive.asOutParam()); H();
887 if (hostDvdDrive)
888 {
889 pConsole->meDVDState = DriveState_HostDriveCaptured;
890 rc = CFGMR3InsertString(pLunL0, "Driver", "HostDVD"); RC_CHECK();
891 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
892 hrc = hostDvdDrive->COMGETTER(Name)(&str); H();
893 STR_CONV();
894 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
895 STR_FREE();
896 BOOL fPassthrough;
897 hrc = dvdDrive->COMGETTER(Passthrough)(&fPassthrough); H();
898 rc = CFGMR3InsertInteger(pCfg, "Passthrough", !!fPassthrough); RC_CHECK();
899 }
900 else
901 {
902 pConsole->meDVDState = DriveState_NotMounted;
903 rc = CFGMR3InsertString(pLunL0, "Driver", "Block"); RC_CHECK();
904 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
905 rc = CFGMR3InsertString(pCfg, "Type", "DVD"); RC_CHECK();
906 rc = CFGMR3InsertInteger(pCfg, "Mountable", 1); RC_CHECK();
907
908 ComPtr<IDVDImage> dvdImage;
909 hrc = dvdDrive->GetImage(dvdImage.asOutParam()); H();
910 if (dvdImage)
911 {
912 pConsole->meDVDState = DriveState_ImageMounted;
913 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
914 rc = CFGMR3InsertString(pLunL1, "Driver", "MediaISO"); RC_CHECK();
915 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK();
916 hrc = dvdImage->COMGETTER(FilePath)(&str); H();
917 STR_CONV();
918 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK();
919 STR_FREE();
920 }
921 }
922 }
923
924 /*
925 * Network adapters
926 */
927 PCFGMNODE pDevPCNet = NULL; /* PCNet-type devices */
928 rc = CFGMR3InsertNode(pDevices, "pcnet", &pDevPCNet); RC_CHECK();
929#ifdef VBOX_WITH_E1000
930 PCFGMNODE pDevE1000 = NULL; /* E1000-type devices */
931 rc = CFGMR3InsertNode(pDevices, "e1000", &pDevE1000); RC_CHECK();
932#endif
933 for (ULONG ulInstance = 0; ulInstance < SchemaDefs::NetworkAdapterCount; ulInstance++)
934 {
935 ComPtr<INetworkAdapter> networkAdapter;
936 hrc = pMachine->GetNetworkAdapter(ulInstance, networkAdapter.asOutParam()); H();
937 BOOL fEnabled = FALSE;
938 hrc = networkAdapter->COMGETTER(Enabled)(&fEnabled); H();
939 if (!fEnabled)
940 continue;
941
942 /*
943 * The virtual hardware type. Create appropriate device first.
944 */
945 NetworkAdapterType_T adapterType;
946 hrc = networkAdapter->COMGETTER(AdapterType)(&adapterType); H();
947 switch (adapterType)
948 {
949 case NetworkAdapterType_Am79C970A:
950 case NetworkAdapterType_Am79C973:
951 pDev = pDevPCNet;
952 break;
953#ifdef VBOX_WITH_E1000
954 case NetworkAdapterType_I82540EM:
955 pDev = pDevE1000;
956 break;
957#endif
958 default:
959 AssertMsgFailed(("Invalid network adapter type '%d' for slot '%d'",
960 adapterType, ulInstance));
961 return VERR_GENERAL_FAILURE;
962 }
963
964 char szInstance[4]; Assert(ulInstance <= 999);
965 RTStrPrintf(szInstance, sizeof(szInstance), "%lu", ulInstance);
966 rc = CFGMR3InsertNode(pDev, szInstance, &pInst); RC_CHECK();
967 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
968 /* the first network card gets the PCI ID 3, the next 3 gets 8..10. */
969 const unsigned iPciDeviceNo = !ulInstance ? 3 : ulInstance - 1 + 8;
970 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", iPciDeviceNo); RC_CHECK();
971 Assert(!afPciDeviceNo[iPciDeviceNo]);
972 afPciDeviceNo[iPciDeviceNo] = true;
973 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
974 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
975
976 /*
977 * The virtual hardware type. PCNet supports two types.
978 */
979 switch (adapterType)
980 {
981 case NetworkAdapterType_Am79C970A:
982 rc = CFGMR3InsertInteger(pCfg, "Am79C973", 0); RC_CHECK();
983 break;
984 case NetworkAdapterType_Am79C973:
985 rc = CFGMR3InsertInteger(pCfg, "Am79C973", 1); RC_CHECK();
986 break;
987 }
988
989 /*
990 * Get the MAC address and convert it to binary representation
991 */
992 Bstr macAddr;
993 hrc = networkAdapter->COMGETTER(MACAddress)(macAddr.asOutParam()); H();
994 Assert(macAddr);
995 Utf8Str macAddrUtf8 = macAddr;
996 char *macStr = (char*)macAddrUtf8.raw();
997 Assert(strlen(macStr) == 12);
998 PDMMAC Mac;
999 memset(&Mac, 0, sizeof(Mac));
1000 char *pMac = (char*)&Mac;
1001 for (uint32_t i = 0; i < 6; i++)
1002 {
1003 char c1 = *macStr++ - '0';
1004 if (c1 > 9)
1005 c1 -= 7;
1006 char c2 = *macStr++ - '0';
1007 if (c2 > 9)
1008 c2 -= 7;
1009 *pMac++ = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
1010 }
1011 rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac)); RC_CHECK();
1012
1013 /*
1014 * Check if the cable is supposed to be unplugged
1015 */
1016 BOOL fCableConnected;
1017 hrc = networkAdapter->COMGETTER(CableConnected)(&fCableConnected); H();
1018 rc = CFGMR3InsertInteger(pCfg, "CableConnected", fCableConnected ? 1 : 0); RC_CHECK();
1019
1020 /*
1021 * Line speed to report from custom drivers
1022 */
1023 ULONG ulLineSpeed;
1024 hrc = networkAdapter->COMGETTER(LineSpeed)(&ulLineSpeed); H();
1025 rc = CFGMR3InsertInteger(pCfg, "LineSpeed", ulLineSpeed); RC_CHECK();
1026
1027 /*
1028 * Attach the status driver.
1029 */
1030 rc = CFGMR3InsertNode(pInst, "LUN#999", &pLunL0); RC_CHECK();
1031 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
1032 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1033 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapNetworkLeds[ulInstance]); RC_CHECK();
1034
1035 /*
1036 * Enable the packet sniffer if requested.
1037 */
1038 BOOL fSniffer;
1039 hrc = networkAdapter->COMGETTER(TraceEnabled)(&fSniffer); H();
1040 if (fSniffer)
1041 {
1042 /* insert the sniffer filter driver. */
1043 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1044 rc = CFGMR3InsertString(pLunL0, "Driver", "NetSniffer"); RC_CHECK();
1045 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1046 hrc = networkAdapter->COMGETTER(TraceFile)(&str); H();
1047 if (str) /* check convention for indicating default file. */
1048 {
1049 STR_CONV();
1050 rc = CFGMR3InsertString(pCfg, "File", psz); RC_CHECK();
1051 STR_FREE();
1052 }
1053 }
1054
1055 NetworkAttachmentType_T networkAttachment;
1056 hrc = networkAdapter->COMGETTER(AttachmentType)(&networkAttachment); H();
1057 switch (networkAttachment)
1058 {
1059 case NetworkAttachmentType_Null:
1060 break;
1061
1062 case NetworkAttachmentType_NAT:
1063 {
1064 if (fSniffer)
1065 {
1066 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); RC_CHECK();
1067 }
1068 else
1069 {
1070 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1071 }
1072 rc = CFGMR3InsertString(pLunL0, "Driver", "NAT"); RC_CHECK();
1073 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1074 /* (Port forwarding goes here.) */
1075
1076 /* Configure TFTP prefix and boot filename. */
1077 hrc = virtualBox->COMGETTER(HomeFolder)(&str); H();
1078 STR_CONV();
1079 if (psz && *psz)
1080 {
1081 char *pszTFTPPrefix = NULL;
1082 RTStrAPrintf(&pszTFTPPrefix, "%s%c%s", psz, RTPATH_DELIMITER, "TFTP");
1083 rc = CFGMR3InsertString(pCfg, "TFTPPrefix", pszTFTPPrefix); RC_CHECK();
1084 RTStrFree(pszTFTPPrefix);
1085 }
1086 STR_FREE();
1087 hrc = pMachine->COMGETTER(Name)(&str); H();
1088 STR_CONV();
1089 char *pszBootFile = NULL;
1090 RTStrAPrintf(&pszBootFile, "%s.pxe", psz);
1091 STR_FREE();
1092 rc = CFGMR3InsertString(pCfg, "BootFile", pszBootFile); RC_CHECK();
1093 RTStrFree(pszBootFile);
1094 break;
1095 }
1096
1097 case NetworkAttachmentType_HostInterface:
1098 {
1099 /*
1100 * Perform the attachment if required (don't return on error!)
1101 */
1102 hrc = pConsole->attachToHostInterface(networkAdapter);
1103 if (SUCCEEDED(hrc))
1104 {
1105#ifdef VBOX_WITH_UNIXY_TAP_NETWORKING
1106 Assert (pConsole->maTapFD[ulInstance] >= 0);
1107 if (pConsole->maTapFD[ulInstance] >= 0)
1108 {
1109 if (fSniffer)
1110 {
1111 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); RC_CHECK();
1112 }
1113 else
1114 {
1115 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1116 }
1117 rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface"); RC_CHECK();
1118 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1119# if defined(RT_OS_SOLARIS)
1120 /* Device name/number is required for Solaris as we need it for TAP PPA. */
1121 Bstr tapDeviceName;
1122 networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
1123 if (!tapDeviceName.isEmpty())
1124 rc = CFGMR3InsertString(pCfg, "Device", Utf8Str(tapDeviceName)); RC_CHECK();
1125
1126 /* TAP setup application/script */
1127 Bstr tapSetupApp;
1128 networkAdapter->COMGETTER(TAPSetupApplication)(tapSetupApp.asOutParam());
1129 if (!tapSetupApp.isEmpty())
1130 rc = CFGMR3InsertString(pCfg, "TAPSetupApplication", Utf8Str(tapSetupApp)); RC_CHECK();
1131
1132 /* TAP terminate application/script */
1133 Bstr tapTerminateApp;
1134 networkAdapter->COMGETTER(TAPTerminateApplication)(tapTerminateApp.asOutParam());
1135 if (!tapTerminateApp.isEmpty())
1136 rc = CFGMR3InsertString(pCfg, "TAPTerminateApplication", Utf8Str(tapTerminateApp)); RC_CHECK();
1137
1138 /* "FileHandle" must NOT be inserted here, it is done in DrvTAP.cpp */
1139
1140# ifdef VBOX_WITH_CROSSBOW
1141 /* Crossbow: needs the MAC address for setting up TAP. */
1142 rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac)); RC_CHECK();
1143# endif
1144# else
1145 rc = CFGMR3InsertInteger(pCfg, "FileHandle", pConsole->maTapFD[ulInstance]); RC_CHECK();
1146# endif
1147 }
1148#elif defined(RT_OS_WINDOWS)
1149 if (fSniffer)
1150 {
1151 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); RC_CHECK();
1152 }
1153 else
1154 {
1155 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1156 }
1157 Bstr hostInterfaceName;
1158 hrc = networkAdapter->COMGETTER(HostInterface)(hostInterfaceName.asOutParam()); H();
1159 ComPtr<IHostNetworkInterfaceCollection> coll;
1160 hrc = host->COMGETTER(NetworkInterfaces)(coll.asOutParam()); H();
1161 ComPtr<IHostNetworkInterface> hostInterface;
1162 rc = coll->FindByName(hostInterfaceName, hostInterface.asOutParam());
1163 if (!SUCCEEDED(rc))
1164 {
1165 AssertMsgFailed(("Cannot get GUID for host interface '%ls'\n", hostInterfaceName));
1166 hrc = networkAdapter->Detach(); H();
1167 }
1168 else
1169 {
1170 rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface"); RC_CHECK();
1171 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1172 rc = CFGMR3InsertString(pCfg, "HostInterfaceName", Utf8Str(hostInterfaceName)); RC_CHECK();
1173 Guid hostIFGuid;
1174 hrc = hostInterface->COMGETTER(Id)(hostIFGuid.asOutParam()); H();
1175 char szDriverGUID[256] = {0};
1176 /* add curly brackets */
1177 szDriverGUID[0] = '{';
1178 strcpy(szDriverGUID + 1, hostIFGuid.toString().raw());
1179 strcat(szDriverGUID, "}");
1180 rc = CFGMR3InsertBytes(pCfg, "GUID", szDriverGUID, sizeof(szDriverGUID)); RC_CHECK();
1181 }
1182#else
1183# error "Port me"
1184#endif
1185 }
1186 else
1187 {
1188 switch (hrc)
1189 {
1190#ifdef RT_OS_LINUX
1191 case VERR_ACCESS_DENIED:
1192 return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
1193 "Failed to open '/dev/net/tun' for read/write access. Please check the "
1194 "permissions of that node. Either run 'chmod 0666 /dev/net/tun' or "
1195 "change the group of that node and make yourself a member of that group. Make "
1196 "sure that these changes are permanent, especially if you are "
1197 "using udev"));
1198#endif /* RT_OS_LINUX */
1199 default:
1200 AssertMsgFailed(("Could not attach to host interface! Bad!\n"));
1201 return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_(
1202 "Failed to initialize Host Interface Networking"));
1203 }
1204 }
1205 break;
1206 }
1207
1208 case NetworkAttachmentType_Internal:
1209 {
1210 hrc = networkAdapter->COMGETTER(InternalNetwork)(&str); H();
1211 STR_CONV();
1212 if (psz && *psz)
1213 {
1214 if (fSniffer)
1215 {
1216 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); RC_CHECK();
1217 }
1218 else
1219 {
1220 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1221 }
1222 rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet"); RC_CHECK();
1223 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1224 rc = CFGMR3InsertString(pCfg, "Network", psz); RC_CHECK();
1225 }
1226 STR_FREE();
1227 break;
1228 }
1229
1230 default:
1231 AssertMsgFailed(("should not get here!\n"));
1232 break;
1233 }
1234 }
1235
1236 /*
1237 * Serial (UART) Ports
1238 */
1239 rc = CFGMR3InsertNode(pDevices, "serial", &pDev); RC_CHECK();
1240 for (ULONG ulInstance = 0; ulInstance < SchemaDefs::SerialPortCount; ulInstance++)
1241 {
1242 ComPtr<ISerialPort> serialPort;
1243 hrc = pMachine->GetSerialPort (ulInstance, serialPort.asOutParam()); H();
1244 BOOL fEnabled = FALSE;
1245 if (serialPort)
1246 hrc = serialPort->COMGETTER(Enabled)(&fEnabled); H();
1247 if (!fEnabled)
1248 continue;
1249
1250 char szInstance[4]; Assert(ulInstance <= 999);
1251 RTStrPrintf(szInstance, sizeof(szInstance), "%lu", ulInstance);
1252
1253 rc = CFGMR3InsertNode(pDev, szInstance, &pInst); RC_CHECK();
1254 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1255
1256 ULONG ulIRQ, ulIOBase;
1257 PortMode_T HostMode;
1258 Bstr path;
1259 BOOL fServer;
1260 hrc = serialPort->COMGETTER(HostMode)(&HostMode); H();
1261 hrc = serialPort->COMGETTER(IRQ)(&ulIRQ); H();
1262 hrc = serialPort->COMGETTER(IOBase)(&ulIOBase); H();
1263 hrc = serialPort->COMGETTER(Path)(path.asOutParam()); H();
1264 hrc = serialPort->COMGETTER(Server)(&fServer); H();
1265 rc = CFGMR3InsertInteger(pCfg, "IRQ", ulIRQ); RC_CHECK();
1266 rc = CFGMR3InsertInteger(pCfg, "IOBase", ulIOBase); RC_CHECK();
1267 if (HostMode != PortMode_Disconnected)
1268 {
1269 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1270 if (HostMode == PortMode_HostPipe)
1271 {
1272 rc = CFGMR3InsertString(pLunL0, "Driver", "Char"); RC_CHECK();
1273 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
1274 rc = CFGMR3InsertString(pLunL1, "Driver", "NamedPipe"); RC_CHECK();
1275 rc = CFGMR3InsertNode(pLunL1, "Config", &pLunL2); RC_CHECK();
1276 rc = CFGMR3InsertString(pLunL2, "Location", Utf8Str(path)); RC_CHECK();
1277 rc = CFGMR3InsertInteger(pLunL2, "IsServer", fServer); RC_CHECK();
1278 }
1279 else if (HostMode == PortMode_HostDevice)
1280 {
1281 rc = CFGMR3InsertString(pLunL0, "Driver", "Host Serial"); RC_CHECK();
1282 rc = CFGMR3InsertNode(pLunL0, "Config", &pLunL1); RC_CHECK();
1283 rc = CFGMR3InsertString(pLunL1, "DevicePath", Utf8Str(path)); RC_CHECK();
1284 }
1285 }
1286 }
1287
1288 /*
1289 * Parallel (LPT) Ports
1290 */
1291 rc = CFGMR3InsertNode(pDevices, "parallel", &pDev); RC_CHECK();
1292 for (ULONG ulInstance = 0; ulInstance < SchemaDefs::ParallelPortCount; ulInstance++)
1293 {
1294 ComPtr<IParallelPort> parallelPort;
1295 hrc = pMachine->GetParallelPort (ulInstance, parallelPort.asOutParam()); H();
1296 BOOL fEnabled = FALSE;
1297 if (parallelPort)
1298 hrc = parallelPort->COMGETTER(Enabled)(&fEnabled); H();
1299 if (!fEnabled)
1300 continue;
1301
1302 char szInstance[4]; Assert(ulInstance <= 999);
1303 RTStrPrintf(szInstance, sizeof(szInstance), "%lu", ulInstance);
1304
1305 rc = CFGMR3InsertNode(pDev, szInstance, &pInst); RC_CHECK();
1306 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1307
1308 ULONG ulIRQ, ulIOBase;
1309 Bstr DevicePath;
1310 hrc = parallelPort->COMGETTER(IRQ)(&ulIRQ); H();
1311 hrc = parallelPort->COMGETTER(IOBase)(&ulIOBase); H();
1312 hrc = parallelPort->COMGETTER(Path)(DevicePath.asOutParam()); H();
1313 rc = CFGMR3InsertInteger(pCfg, "IRQ", ulIRQ); RC_CHECK();
1314 rc = CFGMR3InsertInteger(pCfg, "IOBase", ulIOBase); RC_CHECK();
1315 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1316 rc = CFGMR3InsertString(pLunL0, "Driver", "HostParallel"); RC_CHECK();
1317 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK();
1318 rc = CFGMR3InsertString(pLunL1, "DevicePath", Utf8Str(DevicePath)); RC_CHECK();
1319 }
1320
1321 /*
1322 * VMM Device
1323 */
1324 rc = CFGMR3InsertNode(pDevices, "VMMDev", &pDev); RC_CHECK();
1325 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
1326 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1327 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
1328 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 4); RC_CHECK();
1329 Assert(!afPciDeviceNo[4]);
1330 afPciDeviceNo[4] = true;
1331 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
1332
1333 /* the VMM device's Main driver */
1334 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1335 rc = CFGMR3InsertString(pLunL0, "Driver", "MainVMMDev"); RC_CHECK();
1336 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1337 VMMDev *pVMMDev = pConsole->mVMMDev;
1338 rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pVMMDev); RC_CHECK();
1339
1340 /*
1341 * Attach the status driver.
1342 */
1343 rc = CFGMR3InsertNode(pInst, "LUN#999", &pLunL0); RC_CHECK();
1344 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
1345 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1346 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapSharedFolderLed); RC_CHECK();
1347 rc = CFGMR3InsertInteger(pCfg, "First", 0); RC_CHECK();
1348 rc = CFGMR3InsertInteger(pCfg, "Last", 0); RC_CHECK();
1349
1350 /*
1351 * Audio Sniffer Device
1352 */
1353 rc = CFGMR3InsertNode(pDevices, "AudioSniffer", &pDev); RC_CHECK();
1354 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
1355 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1356
1357 /* the Audio Sniffer device's Main driver */
1358 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1359 rc = CFGMR3InsertString(pLunL0, "Driver", "MainAudioSniffer"); RC_CHECK();
1360 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1361 AudioSniffer *pAudioSniffer = pConsole->mAudioSniffer;
1362 rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pAudioSniffer); RC_CHECK();
1363
1364 /*
1365 * AC'97 ICH / SoundBlaster16 audio
1366 */
1367 ComPtr<IAudioAdapter> audioAdapter;
1368 hrc = pMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam()); H();
1369 if (audioAdapter)
1370 hrc = audioAdapter->COMGETTER(Enabled)(&enabled); H();
1371
1372 if (enabled)
1373 {
1374 AudioControllerType_T audioController;
1375 hrc = audioAdapter->COMGETTER(AudioController)(&audioController); H();
1376 switch (audioController)
1377 {
1378 case AudioControllerType_AC97:
1379 {
1380 /* default: ICH AC97 */
1381 rc = CFGMR3InsertNode(pDevices, "ichac97", &pDev); RC_CHECK();
1382 rc = CFGMR3InsertNode(pDev, "0", &pInst);
1383 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
1384 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 5); RC_CHECK();
1385 Assert(!afPciDeviceNo[5]);
1386 afPciDeviceNo[5] = true;
1387 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
1388 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1389 break;
1390 }
1391 case AudioControllerType_SB16:
1392 {
1393 /* legacy SoundBlaster16 */
1394 rc = CFGMR3InsertNode(pDevices, "sb16", &pDev); RC_CHECK();
1395 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
1396 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
1397 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1398 rc = CFGMR3InsertInteger(pCfg, "IRQ", 5); RC_CHECK();
1399 rc = CFGMR3InsertInteger(pCfg, "DMA", 1); RC_CHECK();
1400 rc = CFGMR3InsertInteger(pCfg, "DMA16", 5); RC_CHECK();
1401 rc = CFGMR3InsertInteger(pCfg, "Port", 0x220); RC_CHECK();
1402 rc = CFGMR3InsertInteger(pCfg, "Version", 0x0405); RC_CHECK();
1403 break;
1404 }
1405 }
1406
1407 /* the Audio driver */
1408 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1409 rc = CFGMR3InsertString(pLunL0, "Driver", "AUDIO"); RC_CHECK();
1410 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1411
1412 AudioDriverType_T audioDriver;
1413 hrc = audioAdapter->COMGETTER(AudioDriver)(&audioDriver); H();
1414 switch (audioDriver)
1415 {
1416 case AudioDriverType_Null:
1417 {
1418 rc = CFGMR3InsertString(pCfg, "AudioDriver", "null"); RC_CHECK();
1419 break;
1420 }
1421#ifdef RT_OS_WINDOWS
1422#ifdef VBOX_WITH_WINMM
1423 case AudioDriverType_WinMM:
1424 {
1425 rc = CFGMR3InsertString(pCfg, "AudioDriver", "winmm"); RC_CHECK();
1426 break;
1427 }
1428#endif
1429 case AudioDriverType_DirectSound:
1430 {
1431 rc = CFGMR3InsertString(pCfg, "AudioDriver", "dsound"); RC_CHECK();
1432 break;
1433 }
1434#endif /* RT_OS_WINDOWS */
1435#ifdef RT_OS_SOLARIS
1436 case AudioDriverType_SolAudio:
1437 {
1438 rc = CFGMR3InsertString(pCfg, "AudioDriver", "solaudio"); RC_CHECK();
1439 break;
1440 }
1441#endif
1442#ifdef RT_OS_LINUX
1443 case AudioDriverType_OSS:
1444 {
1445 rc = CFGMR3InsertString(pCfg, "AudioDriver", "oss"); RC_CHECK();
1446 break;
1447 }
1448# ifdef VBOX_WITH_ALSA
1449 case AudioDriverType_ALSA:
1450 {
1451 rc = CFGMR3InsertString(pCfg, "AudioDriver", "alsa"); RC_CHECK();
1452 break;
1453 }
1454# endif
1455# ifdef VBOX_WITH_PULSE
1456 case AudioDriverType_Pulse:
1457 {
1458 rc = CFGMR3InsertString(pCfg, "AudioDriver", "pulse"); RC_CHECK();
1459 break;
1460 }
1461# endif
1462#endif /* RT_OS_LINUX */
1463#ifdef RT_OS_DARWIN
1464 case AudioDriverType_CoreAudio:
1465 {
1466 rc = CFGMR3InsertString(pCfg, "AudioDriver", "coreaudio"); RC_CHECK();
1467 break;
1468 }
1469#endif
1470 }
1471 hrc = pMachine->COMGETTER(Name)(&str); H();
1472 STR_CONV();
1473 rc = CFGMR3InsertString(pCfg, "StreamName", psz); RC_CHECK();
1474 STR_FREE();
1475 }
1476
1477 /*
1478 * The USB Controller.
1479 */
1480 ComPtr<IUSBController> USBCtlPtr;
1481 hrc = pMachine->COMGETTER(USBController)(USBCtlPtr.asOutParam());
1482 if (USBCtlPtr)
1483 {
1484 BOOL fEnabled;
1485 hrc = USBCtlPtr->COMGETTER(Enabled)(&fEnabled); H();
1486 if (fEnabled)
1487 {
1488 rc = CFGMR3InsertNode(pDevices, "usb-ohci", &pDev); RC_CHECK();
1489 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
1490 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1491 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
1492 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 6); RC_CHECK();
1493 Assert(!afPciDeviceNo[6]);
1494 afPciDeviceNo[6] = true;
1495 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
1496
1497 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1498 rc = CFGMR3InsertString(pLunL0, "Driver", "VUSBRootHub"); RC_CHECK();
1499 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1500
1501 /*
1502 * Attach the status driver.
1503 */
1504 rc = CFGMR3InsertNode(pInst, "LUN#999", &pLunL0); RC_CHECK();
1505 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
1506 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1507 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapUSBLed[0]);RC_CHECK();
1508 rc = CFGMR3InsertInteger(pCfg, "First", 0); RC_CHECK();
1509 rc = CFGMR3InsertInteger(pCfg, "Last", 0); RC_CHECK();
1510
1511#ifdef VBOX_WITH_EHCI
1512 hrc = USBCtlPtr->COMGETTER(EnabledEhci)(&fEnabled); H();
1513 if (fEnabled)
1514 {
1515 rc = CFGMR3InsertNode(pDevices, "usb-ehci", &pDev); RC_CHECK();
1516 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK();
1517 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK();
1518 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK();
1519 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 11); RC_CHECK();
1520 Assert(!afPciDeviceNo[11]);
1521 afPciDeviceNo[11] = true;
1522 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); RC_CHECK();
1523
1524 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); RC_CHECK();
1525 rc = CFGMR3InsertString(pLunL0, "Driver", "VUSBRootHub"); RC_CHECK();
1526 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1527
1528 /*
1529 * Attach the status driver.
1530 */
1531 rc = CFGMR3InsertNode(pInst, "LUN#999", &pLunL0); RC_CHECK();
1532 rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); RC_CHECK();
1533 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK();
1534 rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&pConsole->mapUSBLed[1]);RC_CHECK();
1535 rc = CFGMR3InsertInteger(pCfg, "First", 0); RC_CHECK();
1536 rc = CFGMR3InsertInteger(pCfg, "Last", 0); RC_CHECK();
1537 }
1538 else
1539#endif
1540 {
1541 /*
1542 * Enable the 2.0 -> 1.1 device morphing of proxied devies to keep windows quiet.
1543 */
1544 rc = CFGMR3InsertNode(pRoot, "USB", &pCfg); RC_CHECK();
1545 rc = CFGMR3InsertNode(pCfg, "USBProxy", &pCfg); RC_CHECK();
1546 rc = CFGMR3InsertNode(pCfg, "GlobalConfig", &pCfg); RC_CHECK();
1547 rc = CFGMR3InsertInteger(pCfg, "Force11Device", true); RC_CHECK();
1548 // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
1549 // that it's documented somewhere.) Users needing it can use:
1550 // VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
1551 //rc = CFGMR3InsertInteger(pCfg, "Force11PacketSize", true); RC_CHECK();
1552 }
1553 }
1554 }
1555
1556 /*
1557 * Clipboard
1558 */
1559 {
1560 ClipboardMode_T mode = ClipboardMode_Disabled;
1561 hrc = pMachine->COMGETTER(ClipboardMode) (&mode); H();
1562
1563 if (mode != ClipboardMode_Disabled)
1564 {
1565 /* Load the service */
1566 rc = pConsole->mVMMDev->hgcmLoadService ("VBoxSharedClipboard", "VBoxSharedClipboard");
1567
1568 if (VBOX_FAILURE (rc))
1569 {
1570 LogRel(("VBoxSharedClipboard is not available. rc = %Vrc\n", rc));
1571 /* That is not a fatal failure. */
1572 rc = VINF_SUCCESS;
1573 }
1574 else
1575 {
1576 /* Setup the service. */
1577 VBOXHGCMSVCPARM parm;
1578
1579 parm.type = VBOX_HGCM_SVC_PARM_32BIT;
1580
1581 switch (mode)
1582 {
1583 default:
1584 case ClipboardMode_Disabled:
1585 {
1586 LogRel(("VBoxSharedClipboard mode: Off\n"));
1587 parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_OFF;
1588 break;
1589 }
1590 case ClipboardMode_GuestToHost:
1591 {
1592 LogRel(("VBoxSharedClipboard mode: Guest to Host\n"));
1593 parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST;
1594 break;
1595 }
1596 case ClipboardMode_HostToGuest:
1597 {
1598 LogRel(("VBoxSharedClipboard mode: Host to Guest\n"));
1599 parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST;
1600 break;
1601 }
1602 case ClipboardMode_Bidirectional:
1603 {
1604 LogRel(("VBoxSharedClipboard mode: Bidirectional\n"));
1605 parm.u.uint32 = VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL;
1606 break;
1607 }
1608 }
1609
1610 pConsole->mVMMDev->hgcmHostCall ("VBoxSharedClipboard", VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE, 1, &parm);
1611
1612 Log(("Set VBoxSharedClipboard mode\n"));
1613 }
1614 }
1615 }
1616
1617 /*
1618 * CFGM overlay handling.
1619 *
1620 * Here we check the extra data entries for CFGM values
1621 * and create the nodes and insert the values on the fly. Existing
1622 * values will be removed and reinserted. If a value is a valid number,
1623 * it will be inserted as a number, otherwise as a string.
1624 *
1625 * We first perform a run on global extra data, then on the machine
1626 * extra data to support global settings with local overrides.
1627 *
1628 */
1629 Bstr strExtraDataKey;
1630 bool fGlobalExtraData = true;
1631 for (;;)
1632 {
1633 Bstr strNextExtraDataKey;
1634 Bstr strExtraDataValue;
1635
1636 /* get the next key */
1637 if (fGlobalExtraData)
1638 hrc = virtualBox->GetNextExtraDataKey(strExtraDataKey, strNextExtraDataKey.asOutParam(),
1639 strExtraDataValue.asOutParam());
1640 else
1641 hrc = pMachine->GetNextExtraDataKey(strExtraDataKey, strNextExtraDataKey.asOutParam(),
1642 strExtraDataValue.asOutParam());
1643
1644 /* stop if for some reason there's nothing more to request */
1645 if (FAILED(hrc) || !strNextExtraDataKey)
1646 {
1647 /* if we're out of global keys, continue with machine, otherwise we're done */
1648 if (fGlobalExtraData)
1649 {
1650 fGlobalExtraData = false;
1651 strExtraDataKey.setNull();
1652 continue;
1653 }
1654 break;
1655 }
1656
1657 strExtraDataKey = strNextExtraDataKey;
1658 Utf8Str strExtraDataKeyUtf8 = Utf8Str(strExtraDataKey);
1659
1660 /* we only care about keys starting with "VBoxInternal/" */
1661 if (strncmp(strExtraDataKeyUtf8.raw(), "VBoxInternal/", 13) != 0)
1662 continue;
1663 char *pszExtraDataKey = (char*)strExtraDataKeyUtf8.raw() + 13;
1664
1665 /* the key will be in the format "Node1/Node2/Value" or simply "Value". */
1666 PCFGMNODE pNode;
1667 char *pszCFGMValueName = strrchr(pszExtraDataKey, '/');
1668 if (pszCFGMValueName)
1669 {
1670 /* terminate the node and advance to the value */
1671 *pszCFGMValueName = '\0';
1672 pszCFGMValueName++;
1673
1674 /* does the node already exist? */
1675 pNode = CFGMR3GetChild(pRoot, pszExtraDataKey);
1676 if (pNode)
1677 {
1678 /* the value might already exist, remove it to be safe */
1679 CFGMR3RemoveValue(pNode, pszCFGMValueName);
1680 }
1681 else
1682 {
1683 /* create the node */
1684 rc = CFGMR3InsertNode(pRoot, pszExtraDataKey, &pNode);
1685 AssertMsgRC(rc, ("failed to insert node '%s'\n", pszExtraDataKey));
1686 if (VBOX_FAILURE(rc) || !pNode)
1687 continue;
1688 }
1689 }
1690 else
1691 {
1692 pNode = pRoot;
1693 pszCFGMValueName = pszExtraDataKey;
1694 pszExtraDataKey--;
1695
1696 /* the value might already exist, remove it to be safe */
1697 CFGMR3RemoveValue(pNode, pszCFGMValueName);
1698 }
1699
1700 /* now let's have a look at the value */
1701 Utf8Str strCFGMValueUtf8 = Utf8Str(strExtraDataValue);
1702 const char *pszCFGMValue = strCFGMValueUtf8.raw();
1703 /* empty value means remove value which we've already done */
1704 if (pszCFGMValue && *pszCFGMValue)
1705 {
1706 /* if it's a valid number, we'll insert it as such, otherwise string */
1707 uint64_t u64Value;
1708 char *pszNext = NULL;
1709 if ( RTStrToUInt64Ex(pszCFGMValue, &pszNext, 0, &u64Value) == VINF_SUCCESS
1710 && (!pszNext || *pszNext == '\0') /* check if the _whole_ string is a valid number */
1711 )
1712 {
1713 rc = CFGMR3InsertInteger(pNode, pszCFGMValueName, u64Value);
1714 }
1715 else
1716 {
1717 rc = CFGMR3InsertString(pNode, pszCFGMValueName, pszCFGMValue);
1718 }
1719 AssertMsgRC(rc, ("failed to insert CFGM value '%s' to key '%s'\n", pszCFGMValue, pszExtraDataKey));
1720 }
1721 }
1722
1723#undef H
1724#undef RC_CHECK
1725#undef STR_FREE
1726#undef STR_CONV
1727
1728 /* Register VM state change handler */
1729 int rc2 = VMR3AtStateRegister (pVM, Console::vmstateChangeCallback, pConsole);
1730 AssertRC (rc2);
1731 if (VBOX_SUCCESS (rc))
1732 rc = rc2;
1733
1734 /* Register VM runtime error handler */
1735 rc2 = VMR3AtRuntimeErrorRegister (pVM, Console::setVMRuntimeErrorCallback, pConsole);
1736 AssertRC (rc2);
1737 if (VBOX_SUCCESS (rc))
1738 rc = rc2;
1739
1740 /* Save the VM pointer in the machine object */
1741 pConsole->mpVM = pVM;
1742
1743 LogFlowFunc (("vrc = %Vrc\n", rc));
1744 LogFlowFuncLeave();
1745
1746 return rc;
1747}
1748
1749
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