VirtualBox

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

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

Pass the VM's GUID to DevPcBIOS so that the GUID can be stored in DMI/SMBIOS
tables and used by applications.

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