VirtualKD.cpp revision 5e47fdf0b8d2d5cb396977e21d78fb8834385392
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/* $Id$ */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/** @file
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * VirtualKD - Device stub/loader for fast Windows kernel-mode debugging.
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync *
5e47fdf0b8d2d5cb396977e21d78fb8834385392vboxsync * Contributed by: Ivan Shcherbakov
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * Heavily modified after the contribution.
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/*
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * Copyright (C) 2010-2014 Oracle Corporation
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync *
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * available from http://www.virtualbox.org. This file is free software;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * General Public License (GPL) as published by the Free Software
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/*******************************************************************************
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync* Header Files *
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync*******************************************************************************/
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#define LOG_GROUP LOG_GROUP_DEV_VIRTUALKD
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#include <VBox/vmm/pdmdev.h>
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#include <iprt/assert.h>
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#include <iprt/path.h>
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#include "VBoxDD.h"
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/*******************************************************************************
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync* Defined Constants And Macros *
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync*******************************************************************************/
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
6e8c5b206eaaff1b2e1e743f61e43fc4815d7b46vboxsync#define IKDClient_InterfaceVersion 3
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/*******************************************************************************
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync* Structures and Typedefs *
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync*******************************************************************************/
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsynctypedef struct VKDREQUESTHDR
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync unsigned cbData;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync unsigned cbReplyMax;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync} VKDREQUESTHDR;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
5023970fa7fe0114d61c36c941b33cfb5a375c53vboxsync#pragma pack(1)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsynctypedef struct VKDREPLYHDR
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync unsigned cbData;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync char chOne;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync char chSpace;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync} VKDREPLYHDR;
5023970fa7fe0114d61c36c941b33cfb5a375c53vboxsync#pragma pack()
5023970fa7fe0114d61c36c941b33cfb5a375c53vboxsyncAssertCompileSize(VKDREPLYHDR, 6);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncclass IKDClient
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncpublic:
6e8c5b206eaaff1b2e1e743f61e43fc4815d7b46vboxsync virtual unsigned OnRequest(const char *pRequestIncludingRpcHeader, unsigned RequestSizeWithRpcHeader, char **ppReply)=0;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync virtual ~IKDClient() {}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync};
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsynctypedef IKDClient *(*PFNCreateVBoxKDClientEx)(unsigned version);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsynctypedef struct VIRTUALKD
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync bool fOpenChannelDetected;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync bool fChannelDetectSuccessful;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync RTLDRMOD hLib;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync IKDClient *pKDClient;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync char abCmdBody[262144];
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync} VIRTUALKD;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/*******************************************************************************
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync* Internal Functions *
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync*******************************************************************************/
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncstatic DECLCALLBACK(int) vkdPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (pThis->fOpenChannelDetected)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync *pu32 = RT_MAKE_U32_FROM_U8('V', 'B', 'O', 'X'); /* 'XOBV', checked in VMWRPC.H */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->fOpenChannelDetected = false;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->fChannelDetectSuccessful = true;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync else
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync *pu32 = -1;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncstatic DECLCALLBACK(int) vkdPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (Port == 0x5659)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
6e8c5b206eaaff1b2e1e743f61e43fc4815d7b46vboxsync VKDREQUESTHDR RequestHeader = {0, };
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync int rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)u32, &RequestHeader, sizeof(RequestHeader));
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!RT_SUCCESS(rc) || !RequestHeader.cbData)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)(u32 + sizeof(RequestHeader)), pThis->abCmdBody, RequestHeader.cbData);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!RT_SUCCESS(rc))
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync char *pReply = NULL;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync unsigned cbReply;
6e8c5b206eaaff1b2e1e743f61e43fc4815d7b46vboxsync cbReply = pThis->pKDClient->OnRequest(pThis->abCmdBody,
6e8c5b206eaaff1b2e1e743f61e43fc4815d7b46vboxsync RequestHeader.cbData,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync &pReply);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!pReply)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync cbReply = 0;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync VKDREPLYHDR ReplyHeader;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync ReplyHeader.cbData = cbReply + 2;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync ReplyHeader.chOne = '1';
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync ReplyHeader.chSpace = ' ';
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)u32, &ReplyHeader, sizeof(ReplyHeader));
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!RT_SUCCESS(rc))
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (cbReply)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)(u32 + sizeof(ReplyHeader)), pReply, cbReply);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!RT_SUCCESS(rc))
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync else if (Port == 0x5658)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (u32 == 0x564D5868)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->fOpenChannelDetected = true;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync else
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->fOpenChannelDetected = false;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/**
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * @interface_method_impl{PDMDEVREG,pfnConstruct}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncstatic DECLCALLBACK(int) vkdConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->fOpenChannelDetected = false;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->fChannelDetectSuccessful = false;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->hLib = NIL_RTLDRMOD;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->pKDClient = NULL;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!CFGMR3AreValuesValid(pCfg,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "Path\0"))
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* This device is a bit unusual, after this point it will not fail to be
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * constructed, but there will be a warning and it will not work. */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync char szPath[RTPATH_MAX] = "";
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync CFGMR3QueryString(pCfg, "Path", szPath, sizeof(szPath));
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync RTPathAppend(szPath, sizeof(szPath),
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#if HC_ARCH_BITS == 64
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "kdclient64.dll"
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#else
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "kdclient.dll"
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync#endif
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync );
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync int rc = RTLdrLoad(szPath, &pThis->hLib);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (RT_FAILURE(rc))
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_LOAD",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync N_("Failed to load VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PFNCreateVBoxKDClientEx pfnInit;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync rc = RTLdrGetSymbol(pThis->hLib, "CreateVBoxKDClientEx", (void **)&pfnInit);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (RT_FAILURE(rc))
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync RTLdrClose(pThis->hLib);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->hLib = NIL_RTLDRMOD;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_SYMBOL",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync N_("Failed to find entry point for VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->pKDClient = pfnInit(IKDClient_InterfaceVersion);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (!pThis->pKDClient)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync {
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync RTLdrClose(pThis->hLib);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync pThis->hLib = NIL_RTLDRMOD;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_INIT",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync N_("Failed to initialize VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync }
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDMDevHlpIOPortRegister(pDevIns, 0x5658, 2, NULL, vkdPortWrite, vkdPortRead, NULL, NULL, "VirtualKD");
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/**
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * @interface_method_impl{PDMDEVREG,pfnDestruct}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncstatic DECLCALLBACK(int) vkdDestruct(PPDMDEVINS pDevIns)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync delete pThis->pKDClient;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync if (pThis->hLib != NIL_RTLDRMOD)
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync RTLdrClose(pThis->hLib);
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync return VINF_SUCCESS;
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync}
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync/**
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync * The device registration structure.
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsyncconst PDMDEVREG g_DeviceVirtualKD =
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync{
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* u32Version */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDM_DEVREG_VERSION,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* szName */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "VirtualKD",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* szRCMod */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* szR0Mod */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pszDescription */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync "Provides fast debugging interface when debugging Windows kernel",
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* fFlags */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDM_DEVREG_FLAGS_DEFAULT_BITS,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* fClass */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDM_DEVREG_CLASS_MISC,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* cMaxInstances */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync 1,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* cbInstance */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync sizeof(VIRTUALKD),
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnConstruct */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync vkdConstruct,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnDestruct */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync vkdDestruct,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnRelocate */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnIOCtl */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnPowerOn */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnReset */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnSuspend */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnResume */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnAttach */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnDetach */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnQueryInterface */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnInitComplete */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnPowerOff */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* pfnSoftReset */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync NULL,
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync /* u32VersionEnd */
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync PDM_DEVREG_VERSION
c05577cf78fa798f48bfad5d32a939f077f9760cvboxsync};