VirtualBox

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

最後變更 在這個檔案從28800是 28800,由 vboxsync 提交於 15 年 前

Automated rebranding to Oracle copyright/license strings via filemuncher

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.8 KB
 
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.alldomusa.eu.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 <VBox/err.h>
22#include <VBox/log.h>
23#include <VBox/VBoxGuestLib.h>
24
25#ifdef ALLOC_PRAGMA
26#pragma alloc_text (PAGE, VBoxScanPCIResourceList)
27#endif
28
29/* CM_RESOURCE_MEMORY_* flags which were used on XP or earlier. */
30#define VBOX_CM_PRE_VISTA_MASK (0x3f)
31
32/**
33 * Helper to scan the PCI resource list and remember stuff.
34 *
35 * @param pResList Resource list
36 * @param pDevExt Device extension
37 */
38NTSTATUS VBoxScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXT pDevExt)
39{
40 NTSTATUS rc = STATUS_SUCCESS;
41 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialData;
42
43 // enumerate the resource list
44 dprintf(("found %d resources\n", pResList->List->PartialResourceList.Count));
45 ULONG rangeCount = 0;
46 ULONG cMMIORange = 0;
47 PBASE_ADDRESS baseAddress = pDevExt->baseAddress;
48 for (ULONG i = 0; i < pResList->List->PartialResourceList.Count; i++)
49 {
50 partialData = &pResList->List->PartialResourceList.PartialDescriptors[i];
51 switch (partialData->Type)
52 {
53 case CmResourceTypePort:
54 {
55 // overflow protection
56 if (rangeCount < PCI_TYPE0_ADDRESSES)
57 {
58 dprintf(("I/O range: Base = %08x : %08x Length = %08x \n",
59 partialData->u.Port.Start.HighPart,
60 partialData->u.Port.Start.LowPart,
61 partialData->u.Port.Length));
62 //@todo not so gut
63 dprintf(("I got all I want, my dear port, oh!\n"));
64 pDevExt->startPortAddress = (ULONG)partialData->u.Port.Start.LowPart;
65 // save resource information
66 baseAddress->RangeStart = partialData->u.Port.Start;
67 baseAddress->RangeLength = partialData->u.Port.Length;
68 baseAddress->RangeInMemory = FALSE;
69 baseAddress->ResourceMapped = FALSE;
70 // next item
71 rangeCount++; baseAddress++;
72 }
73 break;
74 }
75
76 case CmResourceTypeInterrupt:
77 {
78 dprintf(("Interrupt: Level = %x Vector = %x Mode = %x \n",
79 partialData->u.Interrupt.Level,
80 partialData->u.Interrupt.Vector,
81 partialData->Flags));
82 // save information
83 pDevExt->interruptLevel = partialData->u.Interrupt.Level;
84 pDevExt->interruptVector = partialData->u.Interrupt.Vector;
85 pDevExt->interruptAffinity = partialData->u.Interrupt.Affinity;
86 // check interrupt mode
87 if (partialData->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
88 {
89 pDevExt->interruptMode = Latched;
90 }
91 else
92 {
93 pDevExt->interruptMode = LevelSensitive;
94 }
95 break;
96 }
97
98 case CmResourceTypeMemory:
99 {
100 // overflow protection
101 if (rangeCount < PCI_TYPE0_ADDRESSES)
102 {
103 dprintf(("Memory range: Base = %08x : %08x Length = %08x \n",
104 partialData->u.Memory.Start.HighPart,
105 partialData->u.Memory.Start.LowPart,
106 partialData->u.Memory.Length));
107 // we only care about read/write memory
108 /** @todo reconsider memory type */
109 if ( cMMIORange == 0 /* only care about the first mmio range (!!!) */
110 && (partialData->Flags & VBOX_CM_PRE_VISTA_MASK) == CM_RESOURCE_MEMORY_READ_WRITE)
111 {
112 pDevExt->memoryAddress = partialData->u.Memory.Start;
113 pDevExt->memoryLength = (ULONG)partialData->u.Memory.Length;
114 // save resource information
115 baseAddress->RangeStart = partialData->u.Memory.Start;
116 baseAddress->RangeLength = partialData->u.Memory.Length;
117 baseAddress->RangeInMemory = TRUE;
118 baseAddress->ResourceMapped = FALSE;
119 // next item
120 rangeCount++; baseAddress++;cMMIORange++;
121 } else
122 {
123 dprintf(("Ignoring memory: flags = %08x \n", partialData->Flags));
124 }
125 }
126 break;
127 }
128
129 case CmResourceTypeDma:
130 {
131 dprintf(("DMA resource found. Hmm...\n"));
132 break;
133 }
134
135 default:
136 {
137 dprintf(("Unexpected resource found %d. Hmm...\n", partialData->Type));
138 break;
139 }
140 }
141 }
142 // memorize the number of resources found
143 pDevExt->addressCount = rangeCount;
144
145 return rc;
146}
147
148
149NTSTATUS hlpVBoxMapVMMDevMemory (PVBOXGUESTDEVEXT pDevExt)
150{
151 NTSTATUS rc = STATUS_SUCCESS;
152
153 if (pDevExt->memoryLength != 0)
154 {
155 pDevExt->pVMMDevMemory = (VMMDevMemory *)MmMapIoSpace (pDevExt->memoryAddress, pDevExt->memoryLength, MmNonCached);
156 dprintf(("VBoxGuest::VBoxGuestPnp: VMMDevMemory: ptr = 0x%x\n", pDevExt->pVMMDevMemory));
157 if (pDevExt->pVMMDevMemory)
158 {
159 dprintf(("VBoxGuest::VBoxGuestPnp: VMMDevMemory: version = 0x%x, size = %d\n", pDevExt->pVMMDevMemory->u32Version, pDevExt->pVMMDevMemory->u32Size));
160
161 /* Check version of the structure */
162 if (pDevExt->pVMMDevMemory->u32Version != VMMDEV_MEMORY_VERSION)
163 {
164 /* Not our version, refuse operation and unmap the memory */
165 hlpVBoxUnmapVMMDevMemory (pDevExt);
166
167 rc = STATUS_UNSUCCESSFUL;
168 }
169 }
170 else
171 {
172 rc = STATUS_UNSUCCESSFUL;
173 }
174 }
175
176 return rc;
177}
178
179void hlpVBoxUnmapVMMDevMemory (PVBOXGUESTDEVEXT pDevExt)
180{
181 if (pDevExt->pVMMDevMemory)
182 {
183 MmUnmapIoSpace (pDevExt->pVMMDevMemory, pDevExt->memoryLength);
184 pDevExt->pVMMDevMemory = NULL;
185 }
186
187 pDevExt->memoryAddress.QuadPart = 0;
188 pDevExt->memoryLength = 0;
189}
190
191/** @todo maybe we should drop this routine entirely later because we detecting
192 * the running OS via VBoxService in ring 3 using guest properties since a while. */
193NTSTATUS hlpVBoxReportGuestInfo (PVBOXGUESTDEVEXT pDevExt)
194{
195 VMMDevReportGuestInfo *req = NULL;
196
197 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo);
198
199 dprintf(("hlpVBoxReportGuestInfo: VbglGRAlloc rc = %d\n", rc));
200
201 if (RT_SUCCESS(rc))
202 {
203 req->guestInfo.additionsVersion = VMMDEV_VERSION;
204
205 /* we've already determined the Windows product before */
206 switch (winVersion)
207 {
208 case WINNT4:
209 req->guestInfo.osType = VBOXOSTYPE_WinNT4;
210 break;
211 case WIN2K:
212 req->guestInfo.osType = VBOXOSTYPE_Win2k;
213 break;
214 case WINXP:
215 req->guestInfo.osType = VBOXOSTYPE_WinXP;
216 break;
217 case WIN2K3:
218 req->guestInfo.osType = VBOXOSTYPE_Win2k3;
219 break;
220 case WINVISTA:
221 req->guestInfo.osType = VBOXOSTYPE_WinVista;
222 break;
223 case WIN7:
224 req->guestInfo.osType = VBOXOSTYPE_Win7;
225 break;
226 default:
227 /* we don't know, therefore NT family */
228 req->guestInfo.osType = VBOXOSTYPE_WinNT;
229 break;
230 }
231
232 /** @todo registry lookup for additional information */
233
234 rc = VbglGRPerform (&req->header);
235
236 if (RT_FAILURE(rc))
237 {
238 dprintf(("VBoxGuest::hlpVBoxReportGuestInfo: error reporting guest info to VMMDev. "
239 "rc = %Rrc\n", rc));
240 }
241
242 rc = RT_SUCCESS(rc) ? req->header.rc : rc;
243
244 VbglGRFree (&req->header);
245 }
246
247 return RT_FAILURE(rc) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
248}
249
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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