3
* VBoxGuest-win-legacy - Windows NT4 specifics.
5
* Copyright (C) 2010 Oracle Corporation
7
* This file is part of VirtualBox Open Source Edition (OSE), as
8
* available from http://www.virtualbox.org. This file is free software;
9
* you can redistribute it and/or modify it under the terms of the GNU
10
* General Public License (GPL) as published by the Free Software
11
* Foundation, in version 2 as it comes in the "COPYING" file of the
12
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16
/*******************************************************************************
18
*******************************************************************************/
19
#include "VBoxGuest-win.h"
20
#include "VBoxGuestInternal.h"
23
#include <VBox/version.h>
24
#include <VBox/VBoxGuestLib.h>
27
/*******************************************************************************
28
* Defined Constants And Macros *
29
*******************************************************************************/
31
/* Reenable logging, this was #undef'ed on iprt/log.h for RING0. */
35
# define PCI_MAX_BUSES 256
39
/*******************************************************************************
40
* Internal Functions *
41
*******************************************************************************/
43
NTSTATUS vboxguestwinnt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath);
44
static NTSTATUS vboxguestwinnt4FindPCIDevice(PULONG pBusNumber, PPCI_SLOT_NUMBER pSlotNumber);
48
#pragma alloc_text (INIT, vboxguestwinnt4CreateDevice)
49
#pragma alloc_text (INIT, vboxguestwinnt4FindPCIDevice)
54
* Legacy helper function to create the device object.
56
* @returns NT status code.
62
NTSTATUS vboxguestwinnt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath)
64
int vrc = VINF_SUCCESS;
65
NTSTATUS rc = STATUS_SUCCESS;
67
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: pDrvObj=%p, pDevObj=%p, pRegPath=%p\n",
68
pDrvObj, pDevObj, pRegPath));
71
* Find our virtual PCI device
73
ULONG uBusNumber, uSlotNumber;
74
rc = vboxguestwinnt4FindPCIDevice(&uBusNumber, (PCI_SLOT_NUMBER*)&uSlotNumber);
76
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Device not found!\n"));
78
bool fSymbolicLinkCreated = false;
79
UNICODE_STRING szDosName;
80
PDEVICE_OBJECT pDeviceObject = NULL;
86
UNICODE_STRING szDevName;
87
RtlInitUnicodeString(&szDevName, VBOXGUEST_DEVICE_NAME_NT);
88
rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXT), &szDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
91
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Device created\n"));
93
RtlInitUnicodeString(&szDosName, VBOXGUEST_DEVICE_NAME_DOS);
94
rc = IoCreateSymbolicLink(&szDosName, &szDevName);
97
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Symlink created\n"));
98
fSymbolicLinkCreated = true;
101
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: IoCreateSymbolicLink failed with rc = %#x\n", rc));
104
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: IoCreateDevice failed with rc = %#x\n", rc));
108
* Setup the device extension.
110
PVBOXGUESTDEVEXT pDevExt = NULL;
113
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Setting up device extension ...\n"));
115
pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
116
RtlZeroMemory(pDevExt, sizeof(VBOXGUESTDEVEXT));
119
if (NT_SUCCESS(rc) && pDevExt)
121
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Device extension created\n"));
123
/* Store a reference to ourself. */
124
pDevExt->win.s.pDeviceObject = pDeviceObject;
126
/* Store bus and slot number we've queried before. */
127
pDevExt->win.s.busNumber = uBusNumber;
128
pDevExt->win.s.slotNumber = uSlotNumber;
130
#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
131
rc = hlpRegisterBugCheckCallback(pDevExt);
135
/* Do the actual VBox init ... */
137
rc = vboxguestwinInit(pDrvObj, pDeviceObject, pRegPath);
139
/* Clean up in case of errors. */
142
if (fSymbolicLinkCreated && szDosName.Length > 0)
143
IoDeleteSymbolicLink(&szDosName);
145
IoDeleteDevice(pDeviceObject);
148
Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Returning rc = 0x%x\n", rc));
154
* Helper function to handle the PCI device lookup.
156
* @returns NT status code.
162
static NTSTATUS vboxguestwinnt4FindPCIDevice(PULONG pBusNumber, PPCI_SLOT_NUMBER pSlotNumber)
168
ULONG functionNumber;
169
PCI_SLOT_NUMBER slotNumber;
170
PCI_COMMON_CONFIG pciData;
172
Log(("VBoxGuest::vboxguestwinnt4FindPCIDevice\n"));
174
rc = STATUS_DEVICE_DOES_NOT_EXIST;
175
slotNumber.u.AsULONG = 0;
178
for (busNumber = 0; busNumber < PCI_MAX_BUSES; busNumber++)
180
/* Scan each device. */
181
for (deviceNumber = 0; deviceNumber < PCI_MAX_DEVICES; deviceNumber++)
183
slotNumber.u.bits.DeviceNumber = deviceNumber;
185
/* Scan each function (not really required...). */
186
for (functionNumber = 0; functionNumber < PCI_MAX_FUNCTION; functionNumber++)
188
slotNumber.u.bits.FunctionNumber = functionNumber;
190
/* Have a look at what's in this slot. */
191
if (!HalGetBusData(PCIConfiguration, busNumber, slotNumber.u.AsULONG,
192
&pciData, sizeof(ULONG)))
194
/* No such bus, we're done with it. */
195
deviceNumber = PCI_MAX_DEVICES;
199
if (pciData.VendorID == PCI_INVALID_VENDORID)
201
/* We have to proceed to the next function. */
205
/* Check if it's another device. */
206
if ((pciData.VendorID != VMMDEV_VENDORID) ||
207
(pciData.DeviceID != VMMDEV_DEVICEID))
212
/* Hooray, we've found it! */
213
Log(("VBoxGuest::vboxguestwinnt4FindPCIDevice: Device found!\n"));
215
*pBusNumber = busNumber;
216
*pSlotNumber = slotNumber;