3 * VBoxGuestLib - Host-Guest Communication Manager.
5 * These public functions can be only used by other drivers. They all
6 * do an IOCTL to VBoxGuest via IDC.
10 * Copyright (C) 2006-2016 Oracle Corporation
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
30 /* Entire file is ifdef'ed with !VBGL_VBOXGUEST */
31 #ifndef VBGL_VBOXGUEST
33 #include "VBGLInternal.h"
35 #include <iprt/assert.h>
36 #include <iprt/semaphore.h>
37 #include <iprt/string.h>
39 #define VBGL_HGCM_ASSERT_MSG AssertReleaseMsg
42 * Initializes the HGCM VBGL bits.
44 * @return VBox status code.
46 int vbglR0HGCMInit(void)
48 return RTSemFastMutexCreate(&g_vbgldata
.mutexHGCMHandle
);
52 * Initializes the HGCM VBGL bits.
54 * @return VBox status code.
56 int vbglR0HGCMTerminate(void)
58 RTSemFastMutexDestroy(g_vbgldata
.mutexHGCMHandle
);
59 g_vbgldata
.mutexHGCMHandle
= NIL_RTSEMFASTMUTEX
;
64 DECLINLINE(int) vbglHandleHeapEnter(void)
66 int rc
= RTSemFastMutexRequest(g_vbgldata
.mutexHGCMHandle
);
68 VBGL_HGCM_ASSERT_MSG(RT_SUCCESS(rc
), ("Failed to request handle heap mutex, rc = %Rrc\n", rc
));
73 DECLINLINE(void) vbglHandleHeapLeave(void)
75 RTSemFastMutexRelease(g_vbgldata
.mutexHGCMHandle
);
78 struct VBGLHGCMHANDLEDATA
*vbglHGCMHandleAlloc(void)
80 struct VBGLHGCMHANDLEDATA
*p
= NULL
;
81 int rc
= vbglHandleHeapEnter();
86 /* Simple linear search in array. This will be called not so often, only connect/disconnect. */
87 /** @todo bitmap for faster search and other obvious optimizations. */
88 for (i
= 0; i
< RT_ELEMENTS(g_vbgldata
.aHGCMHandleData
); i
++)
90 if (!g_vbgldata
.aHGCMHandleData
[i
].fAllocated
)
92 p
= &g_vbgldata
.aHGCMHandleData
[i
];
98 vbglHandleHeapLeave();
100 VBGL_HGCM_ASSERT_MSG(p
!= NULL
, ("Not enough HGCM handles.\n"));
105 void vbglHGCMHandleFree(struct VBGLHGCMHANDLEDATA
*pHandle
)
109 int rc
= vbglHandleHeapEnter();
112 VBGL_HGCM_ASSERT_MSG(pHandle
->fAllocated
, ("Freeing not allocated handle.\n"));
115 vbglHandleHeapLeave();
120 DECLVBGL(int) VbglHGCMConnect(VBGLHGCMHANDLE
*pHandle
, VBoxGuestHGCMConnectInfo
*pData
)
123 if (pHandle
&& pData
)
125 struct VBGLHGCMHANDLEDATA
*pHandleData
= vbglHGCMHandleAlloc();
128 rc
= vbglDriverOpen(&pHandleData
->driver
);
131 rc
= vbglDriverIOCtl(&pHandleData
->driver
, VBOXGUEST_IOCTL_HGCM_CONNECT
, pData
, sizeof(*pData
));
136 *pHandle
= pHandleData
;
140 vbglDriverClose(&pHandleData
->driver
);
143 vbglHGCMHandleFree(pHandleData
);
149 rc
= VERR_INVALID_PARAMETER
;
153 DECLVBGL(int) VbglHGCMDisconnect(VBGLHGCMHANDLE handle
, VBoxGuestHGCMDisconnectInfo
*pData
)
155 int rc
= vbglDriverIOCtl(&handle
->driver
, VBOXGUEST_IOCTL_HGCM_DISCONNECT
, pData
, sizeof(*pData
));
157 vbglDriverClose(&handle
->driver
);
159 vbglHGCMHandleFree(handle
);
164 DECLVBGL(int) VbglHGCMCall(VBGLHGCMHANDLE handle
, VBoxGuestHGCMCallInfo
*pData
, uint32_t cbData
)
166 VBGL_HGCM_ASSERT_MSG(cbData
>= sizeof(VBoxGuestHGCMCallInfo
) + pData
->cParms
* sizeof(HGCMFunctionParameter
),
167 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData
, pData
->cParms
,
168 sizeof(VBoxGuestHGCMCallInfo
) + pData
->cParms
* sizeof(VBoxGuestHGCMCallInfo
)));
170 return vbglDriverIOCtl(&handle
->driver
, VBOXGUEST_IOCTL_HGCM_CALL(cbData
), pData
, cbData
);
173 DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle
, VBoxGuestHGCMCallInfo
*pData
, uint32_t cbData
)
175 VBGL_HGCM_ASSERT_MSG(cbData
>= sizeof(VBoxGuestHGCMCallInfo
) + pData
->cParms
* sizeof(HGCMFunctionParameter
),
176 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData
, pData
->cParms
,
177 sizeof(VBoxGuestHGCMCallInfo
) + pData
->cParms
* sizeof(VBoxGuestHGCMCallInfo
)));
179 return vbglDriverIOCtl(&handle
->driver
, VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(cbData
), pData
, cbData
);
183 DECLVBGL(int) VbglHGCMCallTimed(VBGLHGCMHANDLE handle
, VBoxGuestHGCMCallInfoTimed
*pData
, uint32_t cbData
)
185 uint32_t cbExpected
= sizeof(VBoxGuestHGCMCallInfoTimed
)
186 + pData
->info
.cParms
* sizeof(HGCMFunctionParameter
);
187 VBGL_HGCM_ASSERT_MSG(cbData
>= cbExpected
,
188 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData
, pData
->info
.cParms
, cbExpected
));
191 return vbglDriverIOCtl(&handle
->driver
, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData
), pData
, cbData
);
194 #endif /* !VBGL_VBOXGUEST */