VirtualBox

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

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

pc bios

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette