#if 0 /* dead */ /* $Id: SysHlp.cpp 68550 2017-08-31 12:09:41Z vboxsync $ */ /** @file * VBoxGuestLibR0 - IDC with VBoxGuest and HGCM helpers. */ /* * Copyright (C) 2006-2016 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. */ #define LOG_GROUP LOG_GROUP_HGCM #include #include "SysHlp.h" /* Must be included before VBoxGuest.h */ #include #include #ifndef VBGL_VBOXGUEST # ifdef RT_OS_OS2 # include /* for VBOXGUESTOS2IDCCONNECT */ RT_C_DECLS_BEGIN /* * On OS/2 we'll do the connecting in the assembly code of the * client driver, exporting a g_VBoxGuestIDC symbol containing * the connection information obtained from the 16-bit IDC. */ extern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC; RT_C_DECLS_END # endif # if !defined(RT_OS_OS2) \ && !defined(RT_OS_WINDOWS) RT_C_DECLS_BEGIN extern DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version); extern DECLVBGL(void) VBoxGuestIDCClose(void *pvOpaque); extern DECLVBGL(int) VBoxGuestIDCCall(void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn); RT_C_DECLS_END # endif bool vbglDriverIsOpened(VBGLDRIVER *pDriver) { # ifdef RT_OS_WINDOWS return pDriver->pFileObject != NULL; # elif defined (RT_OS_OS2) return pDriver->u32Session != UINT32_MAX && pDriver->u32Session != 0; # else return pDriver->pvOpaque != NULL; # endif } int vbglDriverOpen(VBGLDRIVER *pDriver) { # ifdef RT_OS_WINDOWS UNICODE_STRING uszDeviceName; RtlInitUnicodeString(&uszDeviceName, L"\\Device\\VBoxGuest"); PDEVICE_OBJECT pDeviceObject = NULL; PFILE_OBJECT pFileObject = NULL; NTSTATUS rc = IoGetDeviceObjectPointer(&uszDeviceName, FILE_ALL_ACCESS, &pFileObject, &pDeviceObject); if (NT_SUCCESS(rc)) { Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject)); pDriver->pDeviceObject = pDeviceObject; pDriver->pFileObject = pFileObject; return VINF_SUCCESS; } /** @todo return RTErrConvertFromNtStatus(rc)! */ Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc)); return rc; # elif defined (RT_OS_OS2) /* * Just check whether the connection was made or not. */ if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION && RT_VALID_PTR(g_VBoxGuestIDC.u32Session) && RT_VALID_PTR(g_VBoxGuestIDC.pfnServiceEP)) { pDriver->u32Session = g_VBoxGuestIDC.u32Session; return VINF_SUCCESS; } pDriver->u32Session = UINT32_MAX; Log(("vbglDriverOpen: failed\n")); return VERR_FILE_NOT_FOUND; # else uint32_t u32VMMDevVersion; pDriver->pvOpaque = VBoxGuestIDCOpen(&u32VMMDevVersion); if ( pDriver->pvOpaque && u32VMMDevVersion == VMMDEV_VERSION) return VINF_SUCCESS; Log(("vbglDriverOpen: failed\n")); return VERR_FILE_NOT_FOUND; # endif } # ifdef RT_OS_WINDOWS static NTSTATUS vbglDriverIOCtlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { RT_NOREF2(DeviceObject, Irp); Log(("VBGL completion %x\n", Irp)); KEVENT *pEvent = (KEVENT *)Context; KeSetEvent(pEvent, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } # endif int vbglDriverIOCtl(VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData) { Log(("vbglDriverIOCtl: pDriver: %p, Func: %x, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData)); # ifdef RT_OS_WINDOWS KEVENT Event; KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Have to use the IoAllocateIRP method because this code is generic and * must work in any thread context. * The IoBuildDeviceIoControlRequest, which was used here, does not work * when APCs are disabled, for example. */ PIRP irp = IoAllocateIrp(pDriver->pDeviceObject->StackSize, FALSE); Log(("vbglDriverIOCtl: irp %p, IRQL = %d\n", irp, KeGetCurrentIrql())); if (irp == NULL) { Log(("vbglDriverIOCtl: IRP allocation failed!\n")); return VERR_NO_MEMORY; } /* * Setup the IRP_MJ_DEVICE_CONTROL IRP. */ PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(irp); nextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL; nextStack->MinorFunction = 0; nextStack->DeviceObject = pDriver->pDeviceObject; nextStack->Parameters.DeviceIoControl.OutputBufferLength = cbData; nextStack->Parameters.DeviceIoControl.InputBufferLength = cbData; nextStack->Parameters.DeviceIoControl.IoControlCode = u32Function; nextStack->Parameters.DeviceIoControl.Type3InputBuffer = pvData; irp->AssociatedIrp.SystemBuffer = pvData; /* Output buffer. */ irp->MdlAddress = NULL; /* A completion routine is required to signal the Event. */ IoSetCompletionRoutine(irp, vbglDriverIOCtlCompletion, &Event, TRUE, TRUE, TRUE); NTSTATUS rc = IoCallDriver(pDriver->pDeviceObject, irp); if (NT_SUCCESS (rc)) { /* Wait the event to be signalled by the completion routine. */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); rc = irp->IoStatus.Status; Log(("vbglDriverIOCtl: wait completed IRQL = %d\n", KeGetCurrentIrql())); } IoFreeIrp(irp); if (rc != STATUS_SUCCESS) Log(("vbglDriverIOCtl: ntstatus=%x\n", rc)); if (NT_SUCCESS(rc)) return VINF_SUCCESS; if (rc == STATUS_INVALID_PARAMETER) return VERR_INVALID_PARAMETER; if (rc == STATUS_INVALID_BUFFER_SIZE) return VERR_OUT_OF_RANGE; return VERR_VBGL_IOCTL_FAILED; # elif defined (RT_OS_OS2) if ( pDriver->u32Session && pDriver->u32Session == g_VBoxGuestIDC.u32Session) return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL); Log(("vbglDriverIOCtl: No connection\n")); return VERR_WRONG_ORDER; # else return VBoxGuestIDCCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL); # endif } void vbglDriverClose(VBGLDRIVER *pDriver) { # ifdef RT_OS_WINDOWS Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject)); ObDereferenceObject(pDriver->pFileObject); pDriver->pFileObject = NULL; pDriver->pDeviceObject = NULL; # elif defined (RT_OS_OS2) pDriver->u32Session = 0; # else VBoxGuestIDCClose(pDriver->pvOpaque); pDriver->pvOpaque = NULL; # endif } #endif /* !VBGL_VBOXGUEST */ #endif