DrvNamedPipe.cpp revision 2e00eb43f4c5beb9652e4411370a0f41f8fe8ac9
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * VBox stream devices:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Named pipe stream
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Copyright (C) 2006-2007 innotek GmbH
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * available from http://www.virtualbox.org. This file is free software;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * General Public License as published by the Free Software Foundation,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If you received this file as part of a commercial VirtualBox
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * distribution, then only the terms of your commercial VirtualBox
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * license agreement apply instead of the previous paragraph.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*******************************************************************************
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync* Header Files *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync*******************************************************************************/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#else /* !RT_OS_WINDOWS */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif /* !RT_OS_WINDOWS */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*******************************************************************************
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync* Defined Constants And Macros *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync*******************************************************************************/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/** Converts a pointer to DRVNAMEDPIPE::IMedia to a PDRVNAMEDPIPE. */
#define PDMISTREAM_2_DRVNAMEDPIPE(pInterface) ( (PDRVNAMEDPIPE)((uintptr_t)pInterface - RT_OFFSETOF(DRVNAMEDPIPE, IStream)) )
#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
typedef struct DRVNAMEDPIPE
char *pszLocation;
bool fIsServer;
#ifdef RT_OS_WINDOWS
bool fShutdown;
#ifdef RT_OS_WINDOWS
cbReallyRead = 0;
uError = 0;
if (GetOverlappedResult((HANDLE)pData->NamedPipe, &pData->OverlappedRead, &cbReallyRead, TRUE) == FALSE)
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((HANDLE)pData->NamedPipe, &pData->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
char *pszLocation;
return rc;
bool fIsServer;
goto out;
#ifdef RT_OS_WINDOWS
if (fIsServer)
HANDLE hPipe = CreateNamedPipe(pData->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(&pData->ListenThread, drvNamedPipeListenLoop, (void *)pData, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "NamedPipe");
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create listening thread"), pDrvIns->iInstance);
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(&pData->ListenThread, drvNamedPipeListenLoop, (void *)pData, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "NamedPipe");
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 rc;
#ifdef RT_OS_WINDOWS
sizeof(DRVNAMEDPIPE),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,