[68550] | 1 | /* $Id: VBoxGuestR0LibIdc.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * VBoxGuestLib - Ring-0 Support Library for VBoxGuest, IDC.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2008-2023 Oracle and/or its affiliates.
|
---|
[68550] | 8 | *
|
---|
[72627] | 9 | * Permission is hereby granted, free of charge, to any person
|
---|
| 10 | * obtaining a copy of this software and associated documentation
|
---|
| 11 | * files (the "Software"), to deal in the Software without
|
---|
| 12 | * restriction, including without limitation the rights to use,
|
---|
| 13 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
| 14 | * copies of the Software, and to permit persons to whom the
|
---|
| 15 | * Software is furnished to do so, subject to the following
|
---|
| 16 | * conditions:
|
---|
[68550] | 17 | *
|
---|
[72627] | 18 | * The above copyright notice and this permission notice shall be
|
---|
| 19 | * included in all copies or substantial portions of the Software.
|
---|
[68550] | 20 | *
|
---|
[72627] | 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
---|
| 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
---|
| 23 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
---|
| 24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
---|
| 25 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
---|
| 26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
---|
| 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
| 28 | * OTHER DEALINGS IN THE SOFTWARE.
|
---|
[68550] | 29 | */
|
---|
| 30 |
|
---|
| 31 |
|
---|
| 32 | /*********************************************************************************************************************************
|
---|
| 33 | * Header Files *
|
---|
| 34 | *********************************************************************************************************************************/
|
---|
| 35 | #include "VBoxGuestR0LibInternal.h"
|
---|
[76474] | 36 | #include <iprt/errcore.h>
|
---|
[68550] | 37 | #include <VBox/VBoxGuest.h>
|
---|
| 38 | /*#include <iprt/asm.h>*/
|
---|
| 39 |
|
---|
[68653] | 40 | #ifdef VBGL_VBOXGUEST
|
---|
| 41 | # error "This file shouldn't be part of the VBoxGuestR0LibBase library that is linked into VBoxGuest. It's client code."
|
---|
| 42 | #endif
|
---|
[68550] | 43 |
|
---|
[68653] | 44 |
|
---|
| 45 |
|
---|
[68550] | 46 | /*********************************************************************************************************************************
|
---|
| 47 | * Global Variables *
|
---|
| 48 | *********************************************************************************************************************************/
|
---|
| 49 | /*static PVBGLIDCHANDLE volatile g_pMainHandle = NULL;*/
|
---|
| 50 |
|
---|
| 51 |
|
---|
| 52 | /**
|
---|
| 53 | * Opens the IDC interface of the support driver.
|
---|
| 54 | *
|
---|
| 55 | * This will perform basic version negotiations and fail if the
|
---|
| 56 | * minimum requirements aren't met.
|
---|
| 57 | *
|
---|
| 58 | * @returns VBox status code.
|
---|
| 59 | * @param pHandle The handle structure (output).
|
---|
| 60 | * @param uReqVersion The requested version. Pass 0 for default.
|
---|
| 61 | * @param uMinVersion The minimum required version. Pass 0 for default.
|
---|
| 62 | * @param puSessionVersion Where to store the session version. Optional.
|
---|
| 63 | * @param puDriverVersion Where to store the session version. Optional.
|
---|
| 64 | * @param puDriverRevision Where to store the SVN revision of the driver. Optional.
|
---|
| 65 | */
|
---|
| 66 | DECLR0VBGL(int) VbglR0IdcOpen(PVBGLIDCHANDLE pHandle, uint32_t uReqVersion, uint32_t uMinVersion,
|
---|
| 67 | uint32_t *puSessionVersion, uint32_t *puDriverVersion, uint32_t *puDriverRevision)
|
---|
| 68 | {
|
---|
| 69 | unsigned uDefaultMinVersion;
|
---|
| 70 | VBGLIOCIDCCONNECT Req;
|
---|
| 71 | int rc;
|
---|
| 72 |
|
---|
| 73 | /*
|
---|
| 74 | * Validate and set failure return values.
|
---|
| 75 | */
|
---|
| 76 | AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
|
---|
| 77 | pHandle->s.pvSession = NULL;
|
---|
| 78 |
|
---|
| 79 | AssertPtrNullReturn(puSessionVersion, VERR_INVALID_POINTER);
|
---|
| 80 | if (puSessionVersion)
|
---|
| 81 | *puSessionVersion = 0;
|
---|
| 82 |
|
---|
| 83 | AssertPtrNullReturn(puDriverVersion, VERR_INVALID_POINTER);
|
---|
| 84 | if (puDriverVersion)
|
---|
| 85 | *puDriverVersion = 0;
|
---|
| 86 |
|
---|
| 87 | AssertPtrNullReturn(puDriverRevision, VERR_INVALID_POINTER);
|
---|
| 88 | if (puDriverRevision)
|
---|
| 89 | *puDriverRevision = 0;
|
---|
| 90 |
|
---|
| 91 | AssertReturn(!uMinVersion || (uMinVersion & UINT32_C(0xffff0000)) == (VBGL_IOC_VERSION & UINT32_C(0xffff0000)), VERR_INVALID_PARAMETER);
|
---|
| 92 | AssertReturn(!uReqVersion || (uReqVersion & UINT32_C(0xffff0000)) == (VBGL_IOC_VERSION & UINT32_C(0xffff0000)), VERR_INVALID_PARAMETER);
|
---|
| 93 |
|
---|
| 94 | /*
|
---|
| 95 | * Handle default version input and enforce minimum requirements made
|
---|
| 96 | * by this library.
|
---|
| 97 | *
|
---|
| 98 | * The clients will pass defaults (0), and only in the case that some
|
---|
| 99 | * special API feature was just added will they set an actual version.
|
---|
| 100 | * So, this is the place where can easily enforce a minimum IDC version
|
---|
| 101 | * on bugs and similar. It corresponds a bit to what SUPR3Init is
|
---|
| 102 | * responsible for.
|
---|
| 103 | */
|
---|
| 104 | uDefaultMinVersion = VBGL_IOC_VERSION & UINT32_C(0xffff0000);
|
---|
| 105 | if (!uMinVersion || uMinVersion < uDefaultMinVersion)
|
---|
| 106 | uMinVersion = uDefaultMinVersion;
|
---|
| 107 | if (!uReqVersion || uReqVersion < uDefaultMinVersion)
|
---|
| 108 | uReqVersion = uDefaultMinVersion;
|
---|
| 109 |
|
---|
| 110 | /*
|
---|
| 111 | * Setup the connect request packet and call the OS specific function.
|
---|
| 112 | */
|
---|
| 113 | VBGLREQHDR_INIT(&Req.Hdr, IDC_CONNECT);
|
---|
| 114 | Req.u.In.u32MagicCookie = VBGL_IOCTL_IDC_CONNECT_MAGIC_COOKIE;
|
---|
| 115 | Req.u.In.uMinVersion = uMinVersion;
|
---|
| 116 | Req.u.In.uReqVersion = uReqVersion;
|
---|
| 117 | Req.u.In.uReserved = 0;
|
---|
| 118 | rc = vbglR0IdcNativeOpen(pHandle, &Req);
|
---|
| 119 | if (RT_SUCCESS(rc))
|
---|
| 120 | rc = Req.Hdr.rc;
|
---|
| 121 | if (RT_SUCCESS(rc))
|
---|
| 122 | {
|
---|
| 123 | pHandle->s.pvSession = Req.u.Out.pvSession;
|
---|
| 124 | if (puSessionVersion)
|
---|
| 125 | *puSessionVersion = Req.u.Out.uSessionVersion;
|
---|
| 126 | if (puDriverVersion)
|
---|
| 127 | *puDriverVersion = Req.u.Out.uDriverVersion;
|
---|
| 128 | if (puDriverRevision)
|
---|
| 129 | *puDriverRevision = Req.u.Out.uDriverRevision;
|
---|
| 130 |
|
---|
| 131 | /*
|
---|
| 132 | * We don't really trust anyone, make sure the returned
|
---|
| 133 | * session and version values actually makes sense.
|
---|
| 134 | */
|
---|
| 135 | if ( RT_VALID_PTR(Req.u.Out.pvSession)
|
---|
| 136 | && Req.u.Out.uSessionVersion >= uMinVersion
|
---|
| 137 | && (Req.u.Out.uSessionVersion & UINT32_C(0xffff0000)) == (VBGL_IOC_VERSION & UINT32_C(0xffff0000)))
|
---|
| 138 | {
|
---|
| 139 | /*ASMAtomicCmpXchgPtr(&g_pMainHandle, pHandle, NULL);*/
|
---|
| 140 | return rc;
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | AssertMsgFailed(("pSession=%p uSessionVersion=0x%x (r%u)\n", Req.u.Out.pvSession, Req.u.Out.uSessionVersion, Req.u.Out.uDriverRevision));
|
---|
| 144 | rc = VERR_VERSION_MISMATCH;
|
---|
| 145 | VbglR0IdcClose(pHandle);
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | return rc;
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 |
|
---|
| 152 | /**
|
---|
| 153 | * Closes a IDC connection established by VbglR0IdcOpen.
|
---|
| 154 | *
|
---|
| 155 | * @returns VBox status code.
|
---|
| 156 | * @param pHandle The IDC handle.
|
---|
| 157 | */
|
---|
| 158 | DECLR0VBGL(int) VbglR0IdcClose(PVBGLIDCHANDLE pHandle)
|
---|
| 159 | {
|
---|
| 160 | VBGLIOCIDCDISCONNECT Req;
|
---|
| 161 | int rc;
|
---|
| 162 |
|
---|
| 163 | /*
|
---|
| 164 | * Catch closed handles and check that the session is valid.
|
---|
| 165 | */
|
---|
| 166 | AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
|
---|
| 167 | if (!pHandle->s.pvSession)
|
---|
| 168 | return VERR_INVALID_HANDLE;
|
---|
| 169 | AssertPtrReturn(pHandle->s.pvSession, VERR_INVALID_HANDLE);
|
---|
| 170 |
|
---|
| 171 | /*
|
---|
| 172 | * Create the request and hand it to the OS specific code.
|
---|
| 173 | */
|
---|
| 174 | VBGLREQHDR_INIT(&Req.Hdr, IDC_DISCONNECT);
|
---|
| 175 | Req.u.In.pvSession = pHandle->s.pvSession;
|
---|
| 176 | rc = vbglR0IdcNativeClose(pHandle, &Req);
|
---|
| 177 | if (RT_SUCCESS(rc))
|
---|
| 178 | rc = Req.Hdr.rc;
|
---|
| 179 | if (RT_SUCCESS(rc))
|
---|
| 180 | {
|
---|
| 181 | pHandle->s.pvSession = NULL;
|
---|
| 182 | /*ASMAtomicCmpXchgPtr(&g_pMainHandle, NULL, pHandle);*/
|
---|
| 183 | }
|
---|
| 184 | return rc;
|
---|
| 185 | }
|
---|
| 186 |
|
---|
| 187 |
|
---|
| 188 | /**
|
---|
| 189 | * Makes an IDC call, returning the request status.
|
---|
| 190 | *
|
---|
| 191 | * @returns VBox status code. Request status if the I/O control succeeds,
|
---|
| 192 | * otherwise the I/O control failure status.
|
---|
| 193 | * @param pHandle The IDC handle.
|
---|
| 194 | * @param uReq The request number.
|
---|
| 195 | * @param pReqHdr The request header.
|
---|
| 196 | * @param cbReq The request size.
|
---|
| 197 | */
|
---|
| 198 | DECLR0VBGL(int) VbglR0IdcCall(PVBGLIDCHANDLE pHandle, uintptr_t uReq, PVBGLREQHDR pReqHdr, uint32_t cbReq)
|
---|
| 199 | {
|
---|
| 200 | int rc = VbglR0IdcCallRaw(pHandle, uReq, pReqHdr, cbReq);
|
---|
| 201 | if (RT_SUCCESS(rc))
|
---|
| 202 | rc = pReqHdr->rc;
|
---|
| 203 | return rc;
|
---|
| 204 | }
|
---|
| 205 |
|
---|