VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxGuest/Helper.cpp@ 29593

Last change on this file since 29593 was 29191, checked in by vboxsync, 15 years ago

Grrr

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/** @file
2 * VBoxGuest -- VirtualBox Win32 guest support driver
3 */
4
5/*
6 * Copyright (C) 2006-2007 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17//#define LOG_ENABLED
18
19#include "VBoxGuest_Internal.h"
20#include "Helper.h"
21#include <iprt/string.h>
22#include <VBox/err.h>
23#include <VBox/log.h>
24#include <VBox/VBoxGuestLib.h>
25#include <VBox/version.h>
26
27#ifdef ALLOC_PRAGMA
28#pragma alloc_text (PAGE, VBoxScanPCIResourceList)
29#endif
30
31/* CM_RESOURCE_MEMORY_* flags which were used on XP or earlier. */
32#define VBOX_CM_PRE_VISTA_MASK (0x3f)
33
34/**
35 * Helper to scan the PCI resource list and remember stuff.
36 *
37 * @param pResList Resource list
38 * @param pDevExt Device extension
39 */
40NTSTATUS VBoxScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXT pDevExt)
41{
42 NTSTATUS rc = STATUS_SUCCESS;
43 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialData;
44
45 // enumerate the resource list
46 dprintf(("found %d resources\n", pResList->List->PartialResourceList.Count));
47 ULONG rangeCount = 0;
48 ULONG cMMIORange = 0;
49 PBASE_ADDRESS baseAddress = pDevExt->baseAddress;
50 for (ULONG i = 0; i < pResList->List->PartialResourceList.Count; i++)
51 {
52 partialData = &pResList->List->PartialResourceList.PartialDescriptors[i];
53 switch (partialData->Type)
54 {
55 case CmResourceTypePort:
56 {
57 // overflow protection
58 if (rangeCount < PCI_TYPE0_ADDRESSES)
59 {
60 dprintf(("I/O range: Base = %08x : %08x Length = %08x \n",
61 partialData->u.Port.Start.HighPart,
62 partialData->u.Port.Start.LowPart,
63 partialData->u.Port.Length));
64 //@todo not so gut
65 dprintf(("I got all I want, my dear port, oh!\n"));
66 pDevExt->startPortAddress = (ULONG)partialData->u.Port.Start.LowPart;
67 // save resource information
68 baseAddress->RangeStart = partialData->u.Port.Start;
69 baseAddress->RangeLength = partialData->u.Port.Length;
70 baseAddress->RangeInMemory = FALSE;
71 baseAddress->ResourceMapped = FALSE;
72 // next item
73 rangeCount++; baseAddress++;
74 }
75 break;
76 }
77
78 case CmResourceTypeInterrupt:
79 {
80 dprintf(("Interrupt: Level = %x Vector = %x Mode = %x \n",
81 partialData->u.Interrupt.Level,
82 partialData->u.Interrupt.Vector,
83 partialData->Flags));
84 // save information
85 pDevExt->interruptLevel = partialData->u.Interrupt.Level;
86 pDevExt->interruptVector = partialData->u.Interrupt.Vector;
87 pDevExt->interruptAffinity = partialData->u.Interrupt.Affinity;
88 // check interrupt mode
89 if (partialData->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
90 {
91 pDevExt->interruptMode = Latched;
92 }
93 else
94 {
95 pDevExt->interruptMode = LevelSensitive;
96 }
97 break;
98 }
99
100 case CmResourceTypeMemory:
101 {
102 // overflow protection
103 if (rangeCount < PCI_TYPE0_ADDRESSES)
104 {
105 dprintf(("Memory range: Base = %08x : %08x Length = %08x \n",
106 partialData->u.Memory.Start.HighPart,
107 partialData->u.Memory.Start.LowPart,
108 partialData->u.Memory.Length));
109 // we only care about read/write memory
110 /** @todo reconsider memory type */
111 if ( cMMIORange == 0 /* only care about the first mmio range (!!!) */
112 && (partialData->Flags & VBOX_CM_PRE_VISTA_MASK) == CM_RESOURCE_MEMORY_READ_WRITE)
113 {
114 pDevExt->memoryAddress = partialData->u.Memory.Start;
115 pDevExt->memoryLength = (ULONG)partialData->u.Memory.Length;
116 // save resource information
117 baseAddress->RangeStart = partialData->u.Memory.Start;
118 baseAddress->RangeLength = partialData->u.Memory.Length;
119 baseAddress->RangeInMemory = TRUE;
120 baseAddress->ResourceMapped = FALSE;
121 // next item
122 rangeCount++; baseAddress++;cMMIORange++;
123 } else
124 {
125 dprintf(("Ignoring memory: flags = %08x \n", partialData->Flags));
126 }
127 }
128 break;
129 }
130
131 case CmResourceTypeDma:
132 {
133 dprintf(("DMA resource found. Hmm...\n"));
134 break;
135 }
136
137 default:
138 {
139 dprintf(("Unexpected resource found %d. Hmm...\n", partialData->Type));
140 break;
141 }
142 }
143 }
144 // memorize the number of resources found
145 pDevExt->addressCount = rangeCount;
146
147 return rc;
148}
149
150
151NTSTATUS hlpVBoxMapVMMDevMemory (PVBOXGUESTDEVEXT pDevExt)
152{
153 NTSTATUS rc = STATUS_SUCCESS;
154
155 if (pDevExt->memoryLength != 0)
156 {
157 pDevExt->pVMMDevMemory = (VMMDevMemory *)MmMapIoSpace (pDevExt->memoryAddress, pDevExt->memoryLength, MmNonCached);
158 dprintf(("VBoxGuest::VBoxGuestPnp: VMMDevMemory: ptr = 0x%x\n", pDevExt->pVMMDevMemory));
159 if (pDevExt->pVMMDevMemory)
160 {
161 dprintf(("VBoxGuest::VBoxGuestPnp: VMMDevMemory: version = 0x%x, size = %d\n", pDevExt->pVMMDevMemory->u32Version, pDevExt->pVMMDevMemory->u32Size));
162
163 /* Check version of the structure */
164 if (pDevExt->pVMMDevMemory->u32Version != VMMDEV_MEMORY_VERSION)
165 {
166 /* Not our version, refuse operation and unmap the memory */
167 hlpVBoxUnmapVMMDevMemory (pDevExt);
168
169 rc = STATUS_UNSUCCESSFUL;
170 }
171 }
172 else
173 {
174 rc = STATUS_UNSUCCESSFUL;
175 }
176 }
177
178 return rc;
179}
180
181void hlpVBoxUnmapVMMDevMemory (PVBOXGUESTDEVEXT pDevExt)
182{
183 if (pDevExt->pVMMDevMemory)
184 {
185 MmUnmapIoSpace (pDevExt->pVMMDevMemory, pDevExt->memoryLength);
186 pDevExt->pVMMDevMemory = NULL;
187 }
188
189 pDevExt->memoryAddress.QuadPart = 0;
190 pDevExt->memoryLength = 0;
191}
192
193/** @todo maybe we should drop this routine entirely later because we detecting
194 * the running OS via VBoxService in ring 3 using guest properties since a while. */
195NTSTATUS hlpVBoxReportGuestInfo (PVBOXGUESTDEVEXT pDevExt)
196{
197 VMMDevReportGuestInfo *pReq = NULL;
198 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo);
199 dprintf(("hlpVBoxReportGuestInfo: VbglGRAlloc rc = %d\n", rc));
200 if (RT_SUCCESS(rc))
201 {
202 pReq->guestInfo.additionsVersion = VMMDEV_VERSION;
203
204 /* we've already determined the Windows product before */
205 switch (winVersion)
206 {
207 case WINNT4:
208 pReq->guestInfo.osType = VBOXOSTYPE_WinNT4;
209 break;
210 case WIN2K:
211 pReq->guestInfo.osType = VBOXOSTYPE_Win2k;
212 break;
213 case WINXP:
214 pReq->guestInfo.osType = VBOXOSTYPE_WinXP;
215 break;
216 case WIN2K3:
217 pReq->guestInfo.osType = VBOXOSTYPE_Win2k3;
218 break;
219 case WINVISTA:
220 pReq->guestInfo.osType = VBOXOSTYPE_WinVista;
221 break;
222 case WIN7:
223 pReq->guestInfo.osType = VBOXOSTYPE_Win7;
224 break;
225 default:
226 /* we don't know, therefore NT family */
227 pReq->guestInfo.osType = VBOXOSTYPE_WinNT;
228 break;
229 }
230
231 /** @todo registry lookup for additional information */
232
233 rc = VbglGRPerform (&pReq->header);
234 if (RT_FAILURE(rc))
235 {
236 dprintf(("VBoxGuest::hlpVBoxReportGuestInfo: error reporting guest info to VMMDev. "
237 "rc = %Rrc\n", rc));
238 }
239 rc = RT_SUCCESS(rc) ? pReq->header.rc : rc;
240
241 VbglGRFree (&pReq->header);
242 }
243
244 VMMDevReportGuestInfo2 *pReq2 = NULL;
245 if (RT_SUCCESS(rc))
246 rc = VbglGRAlloc ((VMMDevRequestHeader **)&pReq2, sizeof (VMMDevReportGuestInfo2), VMMDevReq_ReportGuestInfo2);
247 dprintf(("hlpVBoxReportGuestInfo2: VbglGRAlloc rc = %d\n", rc));
248
249 if (RT_SUCCESS(rc))
250 {
251 pReq2->guestInfo.additionsMajor = VBOX_VERSION_MAJOR;
252 pReq2->guestInfo.additionsMinor = VBOX_VERSION_MINOR;
253 pReq2->guestInfo.additionsBuild = VBOX_VERSION_BUILD;
254 pReq2->guestInfo.additionsRevision = VBOX_SVN_REV;
255 pReq2->guestInfo.additionsFeatures = 0;
256 RTStrCopy(pReq2->guestInfo.szName, sizeof(pReq2->guestInfo.szName), VBOX_VERSION_STRING);
257
258 rc = VbglGRPerform (&pReq2->header);
259 if (RT_FAILURE(rc))
260 {
261 dprintf(("VBoxGuest::hlpVBoxReportGuestInfo: error reporting guest info to VMMDev. "
262 "rc = %Rrc\n", rc));
263 }
264 rc = RT_SUCCESS(rc) ? pReq2->header.rc : rc;
265 if (rc == VERR_NOT_IMPLEMENTED)
266 rc = VINF_SUCCESS;
267
268 VbglGRFree (&pReq2->header);
269 }
270
271 return RT_FAILURE(rc) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
272}
273
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