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