VBoxGuestIDC-unix.c.h revision e1ed9baf425f4c757302ec417a815aab945fdbf0
/* $Rev$ */
/** @file
* VBoxGuest - Inter Driver Communication, unix implementation.
*
* This file is included by the platform specific source file.
*/
/*
* Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/** @todo Use some header that we have in common with VBoxGuestLib.h... */
/** @todo fix DECLVBGL usage. */
RT_C_DECLS_BEGIN
DECLEXPORT(void *) VBOXCALL VBoxGuestIDCOpen(uint32_t *pu32Version);
DECLEXPORT(int) VBOXCALL VBoxGuestIDCClose(void *pvSession);
DECLEXPORT(int) VBOXCALL VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
RT_C_DECLS_END
/**
* Open a new IDC connection.
*
* @returns Opaque pointer to session object.
* @param pu32Version Where to store VMMDev version.
*/
DECLEXPORT(void *) VBOXCALL VBoxGuestIDCOpen(uint32_t *pu32Version)
{
PVBOXGUESTSESSION pSession;
int rc;
LogFlow(("VBoxGuestIDCOpen: Version=%#x\n", pu32Version ? *pu32Version : 0));
AssertPtrReturn(pu32Version, NULL);
#ifdef RT_OS_SOLARIS
mutex_enter(&g_LdiMtx);
if (!g_LdiHandle)
{
ldi_ident_t DevIdent = ldi_ident_from_anon();
rc = ldi_open_by_name(VBOXGUEST_DEVICE_NAME, FREAD, kcred, &g_LdiHandle, DevIdent);
ldi_ident_release(DevIdent);
if (rc)
{
LogRel(("VBoxGuestIDCOpen: ldi_open_by_name failed. rc=%d\n", rc));
mutex_exit(&g_LdiMtx);
return NULL;
}
}
++g_cLdiOpens;
mutex_exit(&g_LdiMtx);
#endif
rc = VbgdCommonCreateKernelSession(&g_DevExt, &pSession);
if (RT_SUCCESS(rc))
{
*pu32Version = VMMDEV_VERSION;
return pSession;
}
#ifdef RT_OS_SOLARIS
mutex_enter(&g_LdiMtx);
if (g_cLdiOpens > 0)
--g_cLdiOpens;
if ( g_cLdiOpens == 0
&& g_LdiHandle)
{
ldi_close(g_LdiHandle, FREAD, kcred);
g_LdiHandle = NULL;
}
mutex_exit(&g_LdiMtx);
#endif
LogRel(("VBoxGuestIDCOpen: VbgdCommonCreateKernelSession failed. rc=%d\n", rc));
return NULL;
}
/**
* Close an IDC connection.
*
* @returns VBox error code.
* @param pvState Opaque pointer to the session object.
*/
DECLEXPORT(int) VBOXCALL VBoxGuestIDCClose(void *pvSession)
{
PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
LogFlow(("VBoxGuestIDCClose:\n"));
AssertPtrReturn(pSession, VERR_INVALID_POINTER);
VbgdCommonCloseSession(&g_DevExt, pSession);
#ifdef RT_OS_SOLARIS
mutex_enter(&g_LdiMtx);
if (g_cLdiOpens > 0)
--g_cLdiOpens;
if ( g_cLdiOpens == 0
&& g_LdiHandle)
{
ldi_close(g_LdiHandle, FREAD, kcred);
g_LdiHandle = NULL;
}
mutex_exit(&g_LdiMtx);
#endif
return VINF_SUCCESS;
}
/**
* Perform an IDC call.
*
* @returns VBox error code.
* @param pvSession Opaque pointer to the session.
* @param iCmd Requested function.
* @param pvData IO data buffer.
* @param cbData Size of the data buffer.
* @param pcbDataReturned Where to store the amount of returned data.
*/
DECLEXPORT(int) VBOXCALL VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
{
PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
LogFlow(("VBoxGuestIDCCall: %pvSession=%p Cmd=%u pvData=%p cbData=%d\n", pvSession, iCmd, pvData, cbData));
AssertPtrReturn(pSession, VERR_INVALID_POINTER);
AssertMsgReturn(pSession->pDevExt == &g_DevExt,
("SC: %p != %p\n", pSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
return VbgdCommonIoCtl(iCmd, &g_DevExt, pSession, pvData, cbData, pcbDataReturned);
}