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