DrvNamedPipe.cpp revision fe813b3594039ba864493438e78ee0e7132bc445
af062818b47340eef15700d2f0211576ba3506eevboxsync * VBox stream devices:
af062818b47340eef15700d2f0211576ba3506eevboxsync * Named pipe stream
af062818b47340eef15700d2f0211576ba3506eevboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
af062818b47340eef15700d2f0211576ba3506eevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
af062818b47340eef15700d2f0211576ba3506eevboxsync * available from http://www.virtualbox.org. This file is free software;
af062818b47340eef15700d2f0211576ba3506eevboxsync * you can redistribute it and/or modify it under the terms of the GNU
af062818b47340eef15700d2f0211576ba3506eevboxsync * General Public License (GPL) as published by the Free Software
af062818b47340eef15700d2f0211576ba3506eevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
af062818b47340eef15700d2f0211576ba3506eevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
af062818b47340eef15700d2f0211576ba3506eevboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
af062818b47340eef15700d2f0211576ba3506eevboxsync * additional information or have any questions.
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync/*******************************************************************************
589fd26cedb2b4ebbed14f2964cad03cc8ebbca2vboxsync* Header Files *
589fd26cedb2b4ebbed14f2964cad03cc8ebbca2vboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync#else /* !RT_OS_WINDOWS */
ee6bcfc59fe3b0230aad85e2ef63d0402b7719b2vboxsync#endif /* !RT_OS_WINDOWS */
ee6bcfc59fe3b0230aad85e2ef63d0402b7719b2vboxsync/*******************************************************************************
ee6bcfc59fe3b0230aad85e2ef63d0402b7719b2vboxsync* Defined Constants And Macros *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync/** Converts a pointer to DRVNAMEDPIPE::IMedia to a PDRVNAMEDPIPE. */
af062818b47340eef15700d2f0211576ba3506eevboxsync#define PDMISTREAM_2_DRVNAMEDPIPE(pInterface) ( (PDRVNAMEDPIPE)((uintptr_t)pInterface - RT_OFFSETOF(DRVNAMEDPIPE, IStream)) )
af062818b47340eef15700d2f0211576ba3506eevboxsync/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
af062818b47340eef15700d2f0211576ba3506eevboxsync#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Structures and Typedefs *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync * Named pipe driver instance data.
af062818b47340eef15700d2f0211576ba3506eevboxsynctypedef struct DRVNAMEDPIPE
af062818b47340eef15700d2f0211576ba3506eevboxsync /** The stream interface. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /** Pointer to the driver instance. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /** Pointer to the named pipe file name. (Freed by MM) */
af062818b47340eef15700d2f0211576ba3506eevboxsync /** Flag whether VirtualBox represents the server or client side. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* File handle of the named pipe. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* Overlapped structure for writes. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* Overlapped structure for reads. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* Listen thread wakeup semaphore */
af062818b47340eef15700d2f0211576ba3506eevboxsync#else /* !RT_OS_WINDOWS */
af062818b47340eef15700d2f0211576ba3506eevboxsync /** Socket handle of the local socket for server. */
af062818b47340eef15700d2f0211576ba3506eevboxsync /** Socket handle of the local socket. */
5112e32d7072e280613921c982a6672f2c859cf3vboxsync#endif /* !RT_OS_WINDOWS */
5112e32d7072e280613921c982a6672f2c859cf3vboxsync /** Thread for listening for new connections. */
5112e32d7072e280613921c982a6672f2c859cf3vboxsync /** Flag to signal listening thread to shut down. */
5112e32d7072e280613921c982a6672f2c859cf3vboxsync/*******************************************************************************
5112e32d7072e280613921c982a6672f2c859cf3vboxsync* Internal Functions *
5112e32d7072e280613921c982a6672f2c859cf3vboxsync*******************************************************************************/
5112e32d7072e280613921c982a6672f2c859cf3vboxsync/** @copydoc PDMISTREAM::pfnRead */
5112e32d7072e280613921c982a6672f2c859cf3vboxsyncstatic DECLCALLBACK(int) drvNamedPipeRead(PPDMISTREAM pInterface, void *pvBuf, size_t *cbRead)
5112e32d7072e280613921c982a6672f2c859cf3vboxsync PDRVNAMEDPIPE pThis = PDMISTREAM_2_DRVNAMEDPIPE(pInterface);
5112e32d7072e280613921c982a6672f2c859cf3vboxsync LogFlow(("%s: pvBuf=%p cbRead=%#x (%s)\n", __FUNCTION__, pvBuf, cbRead, pThis->pszLocation));
cbReallyRead = 0;
uError = 0;
cbReallyRead = 0;
if (cbReallyRead == 0)
cbReallyRead = 0;
*cbRead = 0;
return rc;
static DECLCALLBACK(int) drvNamedPipeWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *cbWrite)
#ifdef RT_OS_WINDOWS
unsigned cbWritten;
if (GetOverlappedResult(pThis->NamedPipe, &pThis->OverlappedWrite, (DWORD *)&cbWritten, TRUE) == FALSE)
cbWritten = 0;
if (cbWritten == 0)
cbWritten = 0;
return rc;
static DECLCALLBACK(void *) drvNamedPipeQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
switch (enmInterface)
case PDMINTERFACE_BASE:
case PDMINTERFACE_STREAM:
return NULL;
#ifdef RT_OS_WINDOWS
#ifdef RT_OS_WINDOWS
if ( !fConnected
hrc = 0;
close(s);
#ifdef RT_OS_WINDOWS
return VINF_SUCCESS;
int rc;
#ifdef RT_OS_WINDOWS
goto out;
goto out;
bool fIsServer;
goto out;
#ifdef RT_OS_WINDOWS
if (fIsServer)
HANDLE hPipe = CreateNamedPipe(pThis->pszLocation, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 32, 32, 10000, NULL);
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create named pipe %s"), pDrvIns->iInstance, pszLocation);
rc = RTThreadCreate(&pThis->ListenThread, drvNamedPipeListenLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SerPipe");
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create listening thread"), pDrvIns->iInstance);
HANDLE hPipe = CreateFile(pThis->pszLocation, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to connect to named pipe %s"), pDrvIns->iInstance, pszLocation);
return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("NamedPipe#%d failed to create local socket"), pDrvIns->iInstance);
if (fIsServer)
return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("NamedPipe#%d failed to bind to local socket %s"), pDrvIns->iInstance, pszLocation);
rc = RTThreadCreate(&pThis->ListenThread, drvNamedPipeListenLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SerPipe");
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create listening thread"), pDrvIns->iInstance);
return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("NamedPipe#%d failed to connect to local socket %s"), pDrvIns->iInstance, pszLocation);
out:
if (pszLocation)
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to initialize"), pDrvIns->iInstance);
return VINF_SUCCESS;
#ifdef RT_OS_WINDOWS
sizeof(DRVNAMEDPIPE),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,