DBGCTcp.cpp revision 489ff469f658c1a9e95ec8c62fec535c9ca6c6a7
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * DBGC - Debugger Console, TCP backend.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/dbg.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/cfgm.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/err.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/thread.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/tcp.h>
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync#include <VBox/log.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/assert.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <string.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Structures and Typedefs *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Debug console TCP backend instance data.
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct DBGCTCP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The I/O backend for the console. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBGCBACK Back;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The socket of the connection. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSOCKET Sock;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Connection status. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fAlive;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync} DBGCTCP;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync/** Pointer to the instance data of the console TCP backend. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef DBGCTCP *PDBGCTCP;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Converts a pointer to DBGCTCP::Back to a pointer to DBGCTCP. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define DBGCTCP_BACK2DBGCTCP(pBack) ( (PDBGCTCP)((char *)pBack - RT_OFFSETOF(DBGCTCP, Back)) )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int dbgcTcpConnection(RTSOCKET Sock, void *pvUser);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync * Checks if there is input.
2daaccf68be3773aee600c5c3e48bcf5401418a6vboxsync *
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync * @returns true if there is input ready.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * @returns false if there not input ready.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * @param pBack Pointer to the backend structure supplied by
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * the backend. The backend can use this to find
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * it's instance data.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * @param cMillies Number of milliseconds to wait on input data.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync */
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsyncstatic DECLCALLBACK(bool) dbgcTcpBackInput(PDBGCBACK pBack, uint32_t cMillies)
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDBGCTCP pDbgcTcp = DBGCTCP_BACK2DBGCTCP(pBack);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pDbgcTcp->fAlive)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = RTTcpSelectOne(pDbgcTcp->Sock, cMillies);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc) && rc != VERR_TIMEOUT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pDbgcTcp->fAlive = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc != VERR_TIMEOUT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Read input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pBack Pointer to the backend structure supplied by
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the backend. The backend can use this to find
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * it's instance data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvBuf Where to put the bytes we read.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param cbBuf Maximum nymber of bytes to read.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pcbRead Where to store the number of bytes actually read.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * If NULL the entire buffer must be filled for a
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * successful return.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync */
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) dbgcTcpBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync{
22e281e75ed636601178296c6daebda8f1d17c59vboxsync PDBGCTCP pDbgcTcp = DBGCTCP_BACK2DBGCTCP(pBack);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if (!pDbgcTcp->fAlive)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync return VERR_INVALID_HANDLE;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync int rc = RTTcpRead(pDbgcTcp->Sock, pvBuf, cbBuf, pcbRead);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if (VBOX_FAILURE(rc))
22e281e75ed636601178296c6daebda8f1d17c59vboxsync pDbgcTcp->fAlive = false;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync return rc;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync}
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync/**
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * Write (output).
22e281e75ed636601178296c6daebda8f1d17c59vboxsync *
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @returns VBox status code.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param pBack Pointer to the backend structure supplied by
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * the backend. The backend can use this to find
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * it's instance data.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param pvBuf What to write.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param cbBuf Number of bytes to write.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param pcbWritten Where to store the number of bytes actually written.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * If NULL the entire buffer must be successfully written.
7b80828e5760a8814fe6cd494d2715a4544fbddcvboxsync */
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) dbgcTcpBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync{
22e281e75ed636601178296c6daebda8f1d17c59vboxsync PDBGCTCP pDbgcTcp = DBGCTCP_BACK2DBGCTCP(pBack);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if (!pDbgcTcp->fAlive)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync return VERR_INVALID_HANDLE;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /*
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * convert '\n' to '\r\n' while writing.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync int rc = 0;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync size_t cbLeft = cbBuf;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync while (cbLeft)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync {
22e281e75ed636601178296c6daebda8f1d17c59vboxsync size_t cb = cbLeft;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* write newlines */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if (*(const char *)pvBuf == '\n')
22e281e75ed636601178296c6daebda8f1d17c59vboxsync {
d1cbbd799d8912978f5146960b6780f387bb414bvboxsync rc = RTTcpWrite(pDbgcTcp->Sock, "\n\r", 2);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync cb = 1;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync }
c17f5c90f2cb60b38ecabebce128724c6ff2d036vboxsync /* write till next newline */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pszNL = (const char *)memchr(pvBuf, '\n', cbLeft);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pszNL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cb = (uintptr_t)pszNL - (uintptr_t)pvBuf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTTcpWrite(pDbgcTcp->Sock, pvBuf, cb);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pDbgcTcp->fAlive = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* advance */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLeft -= cb;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pvBuf = (const char *)pvBuf + cb;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Set returned value and return.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pcbWritten)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pcbWritten = cbBuf - cbLeft;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Serve a TCP Server connection.
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync *
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VERR_TCP_SERVER_STOP to terminate the server loop forcing
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the RTTcpCreateServer() call to return.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Sock The socket which the client is connected to.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The call will close this socket.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvUser The VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int dbgcTcpConnection(RTSOCKET Sock, void *pvUser)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("dbgcTcpConnection: connection! Sock=%d pvUser=%p\n", Sock, pvUser));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Start the console.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBGCTCP DbgcTcp;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DbgcTcp.Back.pfnInput = dbgcTcpBackInput;
3ecf9412133496b2aeb090cfd33a286404ec59fbvboxsync DbgcTcp.Back.pfnRead = dbgcTcpBackRead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DbgcTcp.Back.pfnWrite = dbgcTcpBackWrite;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DbgcTcp.fAlive = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DbgcTcp.Sock = Sock;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = DBGCCreate((PVM)pvUser, &DbgcTcp.Back, 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("dbgcTcpConnection: disconnect rc=%Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
750d4d0506a38b2e80c997075d40aad474e675fbvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Spawns a new thread with a TCP based debugging console service.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppvData Where to store a pointer to the instance data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvData)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Check what the configuration says.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync PCFGMNODE pKey = CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGC");
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync bool fEnabled;
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync int rc = CFGMR3QueryBool(pKey, "Enabled", &fEnabled);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync#if defined(VBOX_WITH_DEBUGGER) && !defined(__L4ENV__) && !defined(DEBUG_dmik)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync fEnabled = true;
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync#else
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync fEnabled = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync else if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync AssertMsgFailed(("Configuration error: Querying \"Enabled\" -> %Vrc\n", rc));
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync return rc;
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!fEnabled)
72ef2b9fc5ffc01d0dabd5052d6e8baa3a952773vboxsync {
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync LogFlow(("DBGCTcpCreate: returns VINF_SUCCESS (Disabled)\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get the port configuration.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t u32Port;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = CFGMR3QueryU32(pKey, "Port", &u32Port);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync u32Port = 5000;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Configuration error: Querying \"Port\" -> %Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get the address configuration.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync char szAddress[512];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = CFGMR3QueryString(pKey, "Address", szAddress, sizeof(szAddress));
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
9782b553bdb12385214a3ac596aff1476bcb7cbdvboxsync szAddress[0] = '\0';
22e281e75ed636601178296c6daebda8f1d17c59vboxsync else if (VBOX_FAILURE(rc))
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync {
e50404712a2b5234c42bdf9740bddab5729ba188vboxsync AssertMsgFailed(("Configuration error: Querying \"Address\" -> %Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Create the server (separate thread).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRTTCPSERVER pServer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTTcpServerCreate(szAddress, u32Port, RTTHREADTYPE_DEBUGGER, "DBGC", dbgcTcpConnection, pVM, &pServer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_SUCCESS(rc))
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync {
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync LogFlow(("DBGCTcpCreate: Created server on port %d %s\n", u32Port, szAddress));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppvData = pServer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("DBGCTcpCreate: returns %Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync * Terminates any running TCP base debugger consolse service.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM handle.
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync */
57399ab65e2825c324fb9dcb4642d4ae2c232509vboxsyncDBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync{
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync /*
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * Destroy the server instance if any.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pvData)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = RTTcpServerDestroy((PRTTCPSERVER)pvData);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync