VirtualBox

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

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

Put the UUID in the root as well.

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