VBoxGuest-win.cpp revision b394f699c1a81998b6216e59bac82704a937e4f5
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * VBoxGuest - Windows specifics.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * Copyright (C) 2010 Oracle Corporation
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * available from http://www.virtualbox.org. This file is free software;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * General Public License (GPL) as published by the Free Software
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync/*******************************************************************************
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync* Header Files *
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync*******************************************************************************/
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsync * XP DDK #defines ExFreePool to ExFreePoolWithTag. The latter does not exist
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * on NT4, so... The same for ExAllocatePool.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync/*******************************************************************************
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync* Defined Constants And Macros *
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync*******************************************************************************/
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync/*******************************************************************************
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync* Entry Points *
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync*******************************************************************************/
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync/*******************************************************************************
bb424850773b1cf1ae7a69650e7841f0cda3b350vboxsync* Internal Functions *
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync*******************************************************************************/
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync static void vboxguestwinDoTests(void);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync/*******************************************************************************
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync* Exported Functions *
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync*******************************************************************************/
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsyncULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync#pragma alloc_text (PAGE, vboxguestwinNotSupportedStub)
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync#pragma alloc_text (PAGE, vboxguestwinScanPCIResourceList)
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync/** The detected Windows version. */
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsync * Driver entry point.
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsync * @returns appropriate status code.
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsync * @param pDrvObj Pointer to driver object.
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsync * @param pRegPath Registry base path.
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsyncULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync Log(("VBoxGuest::DriverEntry. Driver built: %s %s\n", __DATE__, __TIME__));
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync BOOLEAN bCheckedBuild = PsGetVersion(&majorVersion, &minorVersion, &buildNumber, NULL);
67be63ee622575061bd19d462a747767ddca9900vboxsync Log(("VBoxGuest::DriverEntry: Running on Windows NT version %d.%d, build %d\n", majorVersion, minorVersion, buildNumber));
b0857f8608931dbbc92393a6cb8f478e65e7c2f1vboxsync Log(("VBoxGuest::DriverEntry: Running on a Windows checked build (debug)!\n"));
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync case 6: /* Windows Vista or Windows 7 (based on minor ver) */
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync case 0: /* Note: Also could be Windows 2008 Server! */
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync case 1: /* Note: Also could be Windows 2008 Server R2! */
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n",
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n",
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync Log(("VBoxGuest::DriverEntry: At least Windows NT4 required!\n"));
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * Setup the driver entry points in pDrvObj.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_CREATE] = vboxguestwinCreate;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_CLOSE] = vboxguestwinClose;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxguestwinIOCtl;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinIOCtl;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN] = vboxguestwinShutdown;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_READ] = vboxguestwinNotSupportedStub;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_WRITE] = vboxguestwinNotSupportedStub;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync rc = vboxguestwinnt4CreateDevice(pDrvObj, NULL /* pDevObj */, pRegPath);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_PNP] = vboxguestwinPnP;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_POWER] = vboxguestwinPower;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxguestwinSystemControl;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDrvObj->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)vboxguestwinAddDevice;
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync Log(("VBoxGuest::DriverEntry returning %#x\n", rc));
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * Handle request from the Plug & Play subsystem.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * @returns NT status code
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * @param pDrvObj Driver object
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * @param pDevObj Device object
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsyncstatic NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
bb424850773b1cf1ae7a69650e7841f0cda3b350vboxsync * Create device.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync RtlInitUnicodeString(&devName, VBOXGUEST_DEVICE_NAME_NT);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXT), &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * Create symbolic link (DOS devices).
bb424850773b1cf1ae7a69650e7841f0cda3b350vboxsync RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync * Setup the device extension.
0c1a49387cf675cfb205c773eae123c59ffea2c4vboxsync pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n"));
if (pDevExt)
if (pDeviceObject)
return rc;
#ifdef LOG_ENABLED
ULONG i;
static char* aszName[] =
switch (uType)
case CmResourceTypePort:
case CmResourceTypeMemory:
case CmResourceTypeInterrupt:
case CmResourceTypeDma:
#ifndef TARGET_NT4
#ifndef TARGET_NT4
#ifdef TARGET_NT4
vboxguestwinShowDeviceResources(&pStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList);
pDevExt);
&cbMMIO);
Log(("VBoxGuest::vboxguestwinInit: pvMMIOBase = 0x%p, pDevExt = 0x%p, pDevExt->pVMMDevMemory = 0x%p\n",
#ifdef TARGET_NT4
Log(("VBoxGuest::vboxguestwinInit: Getting interrupt vector (HAL): Bus: %u, IRQL: %u, Vector: %u\n",
&irqLevel,
if (uInterruptVector == 0)
#ifdef TARGET_NT4
#ifdef VBOX_WITH_HGCM
return rc;
if (pDevExt)
return STATUS_SUCCESS;
#ifdef TARGET_NT4
#ifdef VBOX_WITH_HGCM
if (pFileObj)
int vrc;
return rc;
#ifdef VBOX_WITH_HGCM
if (pSession)
return STATUS_SUCCESS;
unsigned cbOut = 0;
switch (uCmd)
Log(("VBoxGuest::vboxguestwinGuestDeviceControl: rc=%Rrc, pBuf=0x%p, cbData=%u, cbDataReturned=%u\n",
Log(("VBoxGuest::vboxguestwinGuestDeviceControl: Too much output data %u - expected %u!\n", cbDataReturned, cbData));
if (cbDataReturned > 0)
return Status;
if (pReq)
return STATUS_SUCCESS;
return STATUS_NOT_SUPPORTED;
return FALSE;
if (fIRQTaken)
return fIRQTaken;
case CmResourceTypePort:
Log(("VBoxGuest::vboxguestwinScanPCIResourceList: I/O range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
case CmResourceTypeInterrupt:
case CmResourceTypeMemory:
Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Memory range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Unhandled resource found, type = %d\n", pPartialData->Type));
return rc;
NTSTATUS vboxguestwinMapVMMDevMemory(PVBOXGUESTDEVEXT pDevExt, PHYSICAL_ADDRESS physicalAdr, ULONG ulLength,
if (pVMMDevMemory)
*ppvMMIOBase));
return rc;
switch (winVer)
case WINNT4:
case WIN2K:
case WINXP:
case WIN2K3:
case WINVISTA:
case WIN7:
return enmOsType;
#ifdef DEBUG
u32Mask));
while (iBitOffset > 0)
if (fSet)
return u32Result;
AssertLogRelMsgFailed(("%s: TEST FAILED: u32Mask=0x%x, u32Bits (before)=0x%x, u32Bits (after)=0x%x, u32Result=0x%x, u32Exp=ox%x\n",
u32Result));
static void vboxguestwinDoTests()