VirtualBox

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

Last change on this file since 4426 was 4426, checked in by vboxsync, 18 years ago

Workaround for VC++ 8 / amd64 optimization issue (it took ages to compile ConsoleImp.cpp with optimizations enabled).

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