VirtualBox

source: vbox/trunk/src/VBox/Devices/Misc/VirtualKD.cpp@ 52880

Last change on this file since 52880 was 52610, checked in by vboxsync, 10 years ago

Devices/Misc/VirtualKD: mistake in contributor name, apologies.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/* $Id: VirtualKD.cpp 52610 2014-09-05 09:42:58Z vboxsync $ */
2/** @file
3 * VirtualKD - Device stub/loader for fast Windows kernel-mode debugging.
4 *
5 * Contributed by: Ivan Shcherbakov
6 * Heavily modified after the contribution.
7 */
8
9/*
10 * Copyright (C) 2010-2014 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21/*******************************************************************************
22* Header Files *
23*******************************************************************************/
24#define LOG_GROUP LOG_GROUP_DEV_VIRTUALKD
25#include <VBox/vmm/pdmdev.h>
26#include <iprt/assert.h>
27#include <iprt/path.h>
28
29#include "VBoxDD.h"
30
31
32/*******************************************************************************
33* Defined Constants And Macros *
34*******************************************************************************/
35
36#define IKDClient_InterfaceVersion 3
37
38
39/*******************************************************************************
40* Structures and Typedefs *
41*******************************************************************************/
42
43typedef struct VKDREQUESTHDR
44{
45 unsigned cbData;
46 unsigned cbReplyMax;
47} VKDREQUESTHDR;
48
49#pragma pack(1)
50typedef struct VKDREPLYHDR
51{
52 unsigned cbData;
53 char chOne;
54 char chSpace;
55} VKDREPLYHDR;
56#pragma pack()
57AssertCompileSize(VKDREPLYHDR, 6);
58
59class IKDClient
60{
61public:
62 virtual unsigned OnRequest(const char *pRequestIncludingRpcHeader, unsigned RequestSizeWithRpcHeader, char **ppReply)=0;
63 virtual ~IKDClient() {}
64};
65
66typedef IKDClient *(*PFNCreateVBoxKDClientEx)(unsigned version);
67
68typedef struct VIRTUALKD
69{
70 bool fOpenChannelDetected;
71 bool fChannelDetectSuccessful;
72 RTLDRMOD hLib;
73 IKDClient *pKDClient;
74 char abCmdBody[262144];
75} VIRTUALKD;
76
77
78/*******************************************************************************
79* Internal Functions *
80*******************************************************************************/
81
82static DECLCALLBACK(int) vkdPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
83{
84 VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
85
86 if (pThis->fOpenChannelDetected)
87 {
88 *pu32 = RT_MAKE_U32_FROM_U8('V', 'B', 'O', 'X'); /* 'XOBV', checked in VMWRPC.H */
89 pThis->fOpenChannelDetected = false;
90 pThis->fChannelDetectSuccessful = true;
91 }
92 else
93 *pu32 = -1;
94
95 return VINF_SUCCESS;
96}
97
98static DECLCALLBACK(int) vkdPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
99{
100 VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
101
102 if (Port == 0x5659)
103 {
104 VKDREQUESTHDR RequestHeader = {0, };
105 int rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)u32, &RequestHeader, sizeof(RequestHeader));
106 if (!RT_SUCCESS(rc) || !RequestHeader.cbData)
107 return VINF_SUCCESS;
108 rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)(u32 + sizeof(RequestHeader)), pThis->abCmdBody, RequestHeader.cbData);
109 if (!RT_SUCCESS(rc))
110 return VINF_SUCCESS;
111
112 char *pReply = NULL;
113 unsigned cbReply;
114 cbReply = pThis->pKDClient->OnRequest(pThis->abCmdBody,
115 RequestHeader.cbData,
116 &pReply);
117
118 if (!pReply)
119 cbReply = 0;
120
121 VKDREPLYHDR ReplyHeader;
122 ReplyHeader.cbData = cbReply + 2;
123 ReplyHeader.chOne = '1';
124 ReplyHeader.chSpace = ' ';
125 rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)u32, &ReplyHeader, sizeof(ReplyHeader));
126 if (!RT_SUCCESS(rc))
127 return VINF_SUCCESS;
128 if (cbReply)
129 {
130 rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)(u32 + sizeof(ReplyHeader)), pReply, cbReply);
131 if (!RT_SUCCESS(rc))
132 return VINF_SUCCESS;
133 }
134 }
135 else if (Port == 0x5658)
136 {
137 if (u32 == 0x564D5868)
138 pThis->fOpenChannelDetected = true;
139 else
140 pThis->fOpenChannelDetected = false;
141 }
142
143 return VINF_SUCCESS;
144}
145
146
147/**
148 * @interface_method_impl{PDMDEVREG,pfnConstruct}
149 */
150static DECLCALLBACK(int) vkdConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
151{
152 VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
153
154 pThis->fOpenChannelDetected = false;
155 pThis->fChannelDetectSuccessful = false;
156 pThis->hLib = NIL_RTLDRMOD;
157 pThis->pKDClient = NULL;
158
159 if (!CFGMR3AreValuesValid(pCfg,
160 "Path\0"))
161 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
162
163 /* This device is a bit unusual, after this point it will not fail to be
164 * constructed, but there will be a warning and it will not work. */
165
166 char szPath[RTPATH_MAX] = "";
167 CFGMR3QueryString(pCfg, "Path", szPath, sizeof(szPath));
168
169 RTPathAppend(szPath, sizeof(szPath),
170#if HC_ARCH_BITS == 64
171 "kdclient64.dll"
172#else
173 "kdclient.dll"
174#endif
175 );
176 int rc = RTLdrLoad(szPath, &pThis->hLib);
177 if (RT_FAILURE(rc))
178 {
179 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_LOAD",
180 N_("Failed to load VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
181 return VINF_SUCCESS;
182 }
183
184 PFNCreateVBoxKDClientEx pfnInit;
185 rc = RTLdrGetSymbol(pThis->hLib, "CreateVBoxKDClientEx", (void **)&pfnInit);
186 if (RT_FAILURE(rc))
187 {
188 RTLdrClose(pThis->hLib);
189 pThis->hLib = NIL_RTLDRMOD;
190 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_SYMBOL",
191 N_("Failed to find entry point for VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
192 return VINF_SUCCESS;
193 }
194
195 pThis->pKDClient = pfnInit(IKDClient_InterfaceVersion);
196 if (!pThis->pKDClient)
197 {
198 RTLdrClose(pThis->hLib);
199 pThis->hLib = NIL_RTLDRMOD;
200 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_INIT",
201 N_("Failed to initialize VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
202 return VINF_SUCCESS;
203 }
204
205 PDMDevHlpIOPortRegister(pDevIns, 0x5658, 2, NULL, vkdPortWrite, vkdPortRead, NULL, NULL, "VirtualKD");
206
207 return VINF_SUCCESS;
208}
209
210/**
211 * @interface_method_impl{PDMDEVREG,pfnDestruct}
212 */
213static DECLCALLBACK(int) vkdDestruct(PPDMDEVINS pDevIns)
214{
215 VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
216
217 delete pThis->pKDClient;
218 if (pThis->hLib != NIL_RTLDRMOD)
219 RTLdrClose(pThis->hLib);
220
221 return VINF_SUCCESS;
222}
223
224/**
225 * The device registration structure.
226 */
227const PDMDEVREG g_DeviceVirtualKD =
228{
229 /* u32Version */
230 PDM_DEVREG_VERSION,
231 /* szName */
232 "VirtualKD",
233 /* szRCMod */
234 "",
235 /* szR0Mod */
236 "",
237 /* pszDescription */
238 "Provides fast debugging interface when debugging Windows kernel",
239 /* fFlags */
240 PDM_DEVREG_FLAGS_DEFAULT_BITS,
241 /* fClass */
242 PDM_DEVREG_CLASS_MISC,
243 /* cMaxInstances */
244 1,
245 /* cbInstance */
246 sizeof(VIRTUALKD),
247 /* pfnConstruct */
248 vkdConstruct,
249 /* pfnDestruct */
250 vkdDestruct,
251 /* pfnRelocate */
252 NULL,
253 /* pfnIOCtl */
254 NULL,
255 /* pfnPowerOn */
256 NULL,
257 /* pfnReset */
258 NULL,
259 /* pfnSuspend */
260 NULL,
261 /* pfnResume */
262 NULL,
263 /* pfnAttach */
264 NULL,
265 /* pfnDetach */
266 NULL,
267 /* pfnQueryInterface */
268 NULL,
269 /* pfnInitComplete */
270 NULL,
271 /* pfnPowerOff */
272 NULL,
273 /* pfnSoftReset */
274 NULL,
275 /* u32VersionEnd */
276 PDM_DEVREG_VERSION
277};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette