VBoxGuest-win-pnp.cpp revision 485e602154df33e5466e0dcca16d8f97914ce41d
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/** @file
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VBoxGuest-win-pnp - Windows Plug'n'Play specifics.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Copyright (C) 2010 Oracle Corporation
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * available from http://www.virtualbox.org. This file is free software;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * General Public License (GPL) as published by the Free Software
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/*******************************************************************************
b2640405e06105d868b5fc8f7b676bb680884380vboxsync* Header Files *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync*******************************************************************************/
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include "VBoxGuest-win.h"
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include "VBoxGuestInternal.h"
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <VBox/err.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <VBox/log.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <VBox/version.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <VBox/VBoxGuestLib.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/*******************************************************************************
b2640405e06105d868b5fc8f7b676bb680884380vboxsync* Defined Constants And Macros *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync*******************************************************************************/
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncextern winVersion_t g_winVersion;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncRT_C_DECLS_BEGIN
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic NTSTATUS vboxguestwinSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pIrp, BOOLEAN fStrict);
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic NTSTATUS vboxguestwinPnPIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent);
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic VOID vboxguestwinShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceList);
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncRT_C_DECLS_END
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef ALLOC_PRAGMA
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#pragma alloc_text (PAGE, vboxguestwinPnP)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#pragma alloc_text (PAGE, vboxguestwinPower)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#pragma alloc_text (PAGE, vboxguestwinSendIrpSynchronously)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#pragma alloc_text (PAGE, vboxguestwinShowDeviceResources)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/* Reenable logging, this was #undef'ed on iprt/log.h for RING0. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#define LOG_ENABLED
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/*******************************************************************************
b2640405e06105d868b5fc8f7b676bb680884380vboxsync* Internal Functions *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync*******************************************************************************/
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Irp completion routine for PnP Irps we send.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pDevObj Device object.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pIrp Request packet.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param event Semaphore.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @return NT status code
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic NTSTATUS vboxguestwinPnpIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync KeSetEvent(pEvent, 0, FALSE);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return STATUS_MORE_PROCESSING_REQUIRED;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Helper to send a PnP IRP and wait until it's done.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pDevObj Device object.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pIrp Request packet.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param fStrict When set, returns an error if the IRP gives an error.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @return NT status code
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic NTSTATUS vboxguestwinSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pIrp, BOOLEAN fStrict)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync KEVENT event;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync KeInitializeEvent(&event, SynchronizationEvent, FALSE);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync IoCopyCurrentIrpStackLocationToNext(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync IoSetCompletionRoutine(pIrp, (PIO_COMPLETION_ROUTINE)vboxguestwinPnpIrpComplete,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync &event, TRUE, TRUE, TRUE);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync NTSTATUS rc = IoCallDriver(pDevObj, pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (rc == STATUS_PENDING)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = pIrp->IoStatus.Status;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!fStrict
b2640405e06105d868b5fc8f7b676bb680884380vboxsync && (rc == STATUS_NOT_SUPPORTED || rc == STATUS_INVALID_DEVICE_REQUEST))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = STATUS_SUCCESS;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinSendIrpSynchronously: Returning 0x%x\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * PnP Request handler.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pDevObj Device object.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pIrp Request packet.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncNTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef LOG_ENABLED
b2640405e06105d868b5fc8f7b676bb680884380vboxsync static char* aszFnctName[] =
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_START_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_REMOVE_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_REMOVE_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_CANCEL_REMOVE_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_STOP_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_STOP_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_CANCEL_STOP_DEVICE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_DEVICE_RELATIONS",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_INTERFACE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_CAPABILITIES",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_RESOURCES",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_DEVICE_TEXT",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_READ_CONFIG",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_WRITE_CONFIG",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_EJECT",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_SET_LOCK",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_ID",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_PNP_DEVICE_STATE",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_QUERY_BUS_INFORMATION",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_DEVICE_USAGE_NOTIFICATION",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync "IRP_MN_SURPRISE_REMOVAL",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync };
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: MinorFunction: %s\n",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pStack->MinorFunction < (sizeof(aszFnctName) / sizeof(aszFnctName[0]))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync ? aszFnctName[pStack->MinorFunction]
b2640405e06105d868b5fc8f7b676bb680884380vboxsync : "Unknown"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync NTSTATUS rc = STATUS_SUCCESS;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (pStack->MinorFunction)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_START_DEVICE:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* This must be handled first by the lower driver. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if ( NT_SUCCESS(rc)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync && NT_SUCCESS(pIrp->IoStatus.Status))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE: pStack->Parameters.StartDevice.AllocatedResources = %p\n",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pStack->Parameters.StartDevice.AllocatedResources));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!pStack->Parameters.StartDevice.AllocatedResources)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE: No resources, pDevExt = %p, nextLowerDriver = %p!\n",
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pDevExt, pDevExt ? pDevExt->win.s.pNextLowerDriver : NULL));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = STATUS_UNSUCCESSFUL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync rc = vboxguestwinInit(pDevObj, pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
2347f07aa55c4c0035118a2a1634e5187a3ffdf4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync if (NT_ERROR(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: START_DEVICE: Error: rc = 0x%x\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* Need to unmap memory in case of errors ... */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxguestwinUnmapVMMDevMemory(pDevExt);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync break;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync case IRP_MN_CANCEL_REMOVE_DEVICE:
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync {
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_REMOVE_DEVICE\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* This must be handled first by the lower driver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync if (NT_SUCCESS(rc) && pDevExt->win.s.devState == PENDINGREMOVE)
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync {
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Return to the state prior to receiving the IRP_MN_QUERY_REMOVE_DEVICE request. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pDevExt->win.s.devState = pDevExt->win.s.prevDevState;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync }
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Complete the IRP. */
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync break;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync case IRP_MN_SURPRISE_REMOVAL:
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync {
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: IRP_MN_SURPRISE_REMOVAL\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync VBOXGUEST_UPDATE_DEVSTATE(pDevExt, SURPRISEREMOVED);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Do nothing here actually. Cleanup is done in IRP_MN_REMOVE_DEVICE.
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync * This request is not expected for VBoxGuest.
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync LogRel(("VBoxGuest: unexpected device removal\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Pass to the lower driver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pIrp->IoStatus.Status = STATUS_SUCCESS;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync IoSkipCurrentIrpStackLocation(pIrp);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Do not complete the IRP. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_QUERY_REMOVE_DEVICE:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_REMOVE_DEVICE\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOX_REBOOT_ON_UNINSTALL
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot.\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = STATUS_UNSUCCESSFUL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif /* VBOX_REBOOT_ON_UNINSTALL */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync if (NT_SUCCESS(rc))
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync {
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync VBOXGUEST_UPDATE_DEVSTATE(pDevExt, PENDINGREMOVE);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* This IRP passed down to lower driver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pIrp->IoStatus.Status = STATUS_SUCCESS;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync IoSkipCurrentIrpStackLocation(pIrp);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync
485e602154df33e5466e0dcca16d8f97914ce41dvboxsync /* we must not do anything here after doing IoSkip & CallDriver
485e602154df33e5466e0dcca16d8f97914ce41dvboxsync * since the driver below us will complete (or already have completed) the IRP.
485e602154df33e5466e0dcca16d8f97914ce41dvboxsync * I.e. just return the status we got from IoCallDriver */
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync return rc;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync }
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Complete the IRP on failure. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_REMOVE_DEVICE:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: REMOVE_DEVICE\n"));
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync VBOXGUEST_UPDATE_DEVSTATE(pDevExt, REMOVED);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Free hardware resources. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* @todo this should actually free I/O ports, interrupts, etc. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = vboxguestwinCleanup(pDevObj);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: vboxguestwinCleanup rc = 0x%08X\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /*
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync * We need to send the remove down the stack before we detach,
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync * but we don't need to wait for the completion of this operation
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync * (and to register a completion routine).
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pIrp->IoStatus.Status = STATUS_SUCCESS;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync IoSkipCurrentIrpStackLocation(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Removing device ...\n"));
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Destroy device extension and clean up everything else. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync VBoxGuestDeleteDevExt(pDevExt);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Remove DOS device + symbolic link. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync UNICODE_STRING win32Name;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync IoDeleteSymbolicLink(&win32Name);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Deleting device ...\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Last action: Delete our device! pDevObj is *not* failed
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync * anymore after this call! */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync IoDeleteDevice(pDevObj);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Device removed!\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Propagating rc from IoCallDriver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync return rc; /* Make sure that we don't do anything below here anymore! */
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync case IRP_MN_CANCEL_STOP_DEVICE:
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync {
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_STOP_DEVICE\n"));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* This must be handled first by the lower driver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync if (NT_SUCCESS(rc) && pDevExt->win.s.devState == PENDINGSTOP)
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync {
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Return to the state prior to receiving the IRP_MN_QUERY_STOP_DEVICE request. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pDevExt->win.s.devState = pDevExt->win.s.prevDevState;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync }
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Complete the IRP. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_QUERY_STOP_DEVICE:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_STOP_DEVICE\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync#ifdef VBOX_REBOOT_ON_UNINSTALL
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped without a reboot!\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif /* VBOX_REBOOT_ON_UNINSTALL */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync if (NT_SUCCESS(rc))
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync {
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync VBOXGUEST_UPDATE_DEVSTATE(pDevExt, PENDINGSTOP);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* This IRP passed down to lower driver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pIrp->IoStatus.Status = STATUS_SUCCESS;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync IoSkipCurrentIrpStackLocation(pIrp);
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
485e602154df33e5466e0dcca16d8f97914ce41dvboxsync /* we must not do anything here after doing IoSkip & CallDriver
485e602154df33e5466e0dcca16d8f97914ce41dvboxsync * since the driver below us will complete (or already have completed) the IRP.
485e602154df33e5466e0dcca16d8f97914ce41dvboxsync * I.e. just return the status we got from IoCallDriver */
3383321ffc6907012f92f16b26b026908de7fe7fvboxsync return rc;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync }
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Complete the IRP on failure. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_STOP_DEVICE:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: STOP_DEVICE\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync VBOXGUEST_UPDATE_DEVSTATE(pDevExt, STOPPED);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Free hardware resources. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* @todo this should actually free I/O ports, interrupts, etc. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = vboxguestwinCleanup(pDevObj);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: cleaning up, rc = 0x%x\n", rc));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /* Pass to the lower driver. */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync pIrp->IoStatus.Status = STATUS_SUCCESS;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync IoSkipCurrentIrpStackLocation(pIrp);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync default:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync IoSkipCurrentIrpStackLocation(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync pIrp->IoStatus.Status = rc;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync Log(("VBoxGuest::vboxguestwinGuestPnp: Returning with rc = 0x%x\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Handle the power completion event.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns NT status code.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pDevObj Targetted device object.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pIrp IO request packet.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pContext Context value passed to IoSetCompletionRoutine in VBoxGuestPower.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncNTSTATUS vboxguestwinPowerComplete(IN PDEVICE_OBJECT pDevObj,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync IN PIRP pIrp, IN PVOID pContext)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PIO_STACK_LOCATION pIrpSp;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pContext;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync ASSERT(pDevExt);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync ASSERT(pDevExt->signature == DEVICE_EXTENSION_SIGNATURE);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (pIrpSp)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync ASSERT(pIrpSp->MajorFunction == IRP_MJ_POWER);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (NT_SUCCESS(pIrp->IoStatus.Status))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (pIrpSp->MinorFunction)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_SET_POWER:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (pIrpSp->Parameters.Power.Type)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case DevicePowerState:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (pIrpSp->Parameters.Power.State.DeviceState)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case PowerDeviceD0:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return STATUS_SUCCESS;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Handle the Power requests.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns NT status code
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pDevObj device object
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pIrp IRP
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncNTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync POWER_STATE_TYPE powerType;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync POWER_STATE powerState;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync POWER_ACTION powerAction;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync powerType = pStack->Parameters.Power.Type;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync powerAction = pStack->Parameters.Power.ShutdownType;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync powerState = pStack->Parameters.Power.State;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (pStack->MinorFunction)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case IRP_MN_SET_POWER:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: IRP_MN_SET_POWER, type= %d\n", powerType));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (powerType)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case SystemPowerState:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: SystemPowerState, action = %d, state = %d\n", powerAction, powerState));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (powerAction)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case PowerActionSleep:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* System now is in a working state. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (powerState.SystemState == PowerSystemWorking)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if ( pDevExt
b2640405e06105d868b5fc8f7b676bb680884380vboxsync && pDevExt->win.s.LastSystemPowerAction == PowerActionHibernate)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: Returning from hibernation!\n"));
2347f07aa55c4c0035118a2a1634e5187a3ffdf4vboxsync int rc = VBoxGuestReinitDevExtAfterHibernation(pDevExt, vboxguestwinVersionToOSType(g_winVersion));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_FAILURE(rc))
2347f07aa55c4c0035118a2a1634e5187a3ffdf4vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: Cannot re-init VMMDev chain, rc = %d!\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case PowerActionShutdownReset:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: Power action reset!\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* Tell the VMM that we no longer support mouse pointer integration. */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync VMMDevReqMouseStatus *pReq = NULL;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync if (RT_SUCCESS(vrc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pReq->mouseFeatures = 0;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pReq->pointerXPos = 0;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pReq->pointerYPos = 0;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync vrc = VbglGRPerform(&pReq->header);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync if (RT_FAILURE(vrc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::PowerStateRequest: error communicating new power status to VMMDev. "
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync "vrc = %Rrc\n", vrc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync VbglGRFree(&pReq->header);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
ce95f18112057771f68abe58df709edd7c467db1vboxsync /* Don't do any cleanup here; there might be still coming in some IOCtls after we got this
ce95f18112057771f68abe58df709edd7c467db1vboxsync * power action and would assert/crash when we already cleaned up all the stuff! */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case PowerActionShutdown:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case PowerActionShutdownOff:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: Power action shutdown!\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (powerState.SystemState >= PowerSystemShutdown)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: Telling the VMMDev to close the VM ...\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync VMMDevPowerStateRequest *pReq = pDevExt->win.s.pPowerStateRequest;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync int vrc = VERR_NOT_IMPLEMENTED;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (pReq)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pReq->header.requestType = VMMDevReq_SetPowerStatus;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pReq->powerState = VMMDevPowerState_PowerOff;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync vrc = VbglGRPerform(&pReq->header);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync if (RT_FAILURE(vrc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::PowerStateRequest: Error communicating new power status to VMMDev. "
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync "vrc = %Rrc\n", vrc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync /* No need to do cleanup here; at this point we should've been
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync * turned off by VMMDev already! */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync case PowerActionHibernate:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxGuest::vboxguestwinGuestPower: Power action hibernate!\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Save the current system power action for later use.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This becomes handy when we return from hibernation for example.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (pDevExt)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pDevExt->win.s.LastSystemPowerAction = powerAction;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync default:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync default:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync break;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Whether we are completing or relaying this power IRP,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * we must call PoStartNextPowerIrp.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PoStartNextPowerIrp(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Send the IRP down the driver stack,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * using PoCallDriver (not IoCallDriver, as for non-power irps).
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync IoCopyCurrentIrpStackLocationToNext(pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync IoSetCompletionRoutine(pIrp,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxguestwinPowerComplete,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync (PVOID)pDevExt,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync TRUE,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync TRUE,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync TRUE);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return PoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}