VirtualBox

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

Last change on this file since 6171 was 6140, checked in by vboxsync, 17 years ago

Pass the VM name to the audio driver. PulseAudio will name the name of the stream according to that name.

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