SysHlp.cpp revision a1acf53599841ef2a93775055b0c2242ab719562
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel/** @file
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel *
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * VBoxGuestLib - A support library for VirtualBox guest additions:
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * Physical memory heap
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel */
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel/*
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * Copyright (C) 2006-2007 innotek GmbH
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel *
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * This file is part of VirtualBox Open Source Edition (OSE), as
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * available from http://www.virtualbox.org. This file is free software;
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * you can redistribute it and/or modify it under the terms of the GNU
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * General Public License as published by the Free Software Foundation,
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * distribution. VirtualBox OSE is distributed in the hope that it will
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel * be useful, but WITHOUT ANY WARRANTY of any kind.
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller *
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller * If you received this file as part of a commercial VirtualBox
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller * distribution, then only the terms of your commercial VirtualBox
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller * license agreement apply instead of the previous paragraph.
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller */
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller#define LOG_GROUP LOG_GROUP_HGCM
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller#include <VBox/log.h>
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller#include <VBox/VBoxGuestLib.h>
194cdefb77cf5217ac87c29c6412db51bd6b8c8dBrendan Mmiller#include "SysHlp.h"
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel#include <iprt/assert.h>
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmillerint vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size)
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller{
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel int rc = VINF_SUCCESS;
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel#ifdef __WIN__
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel PMDL pMdl = IoAllocateMdl (pv, u32Size, FALSE, FALSE, NULL);
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel if (pMdl == NULL)
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel {
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel rc = VERR_NOT_SUPPORTED;
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel }
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller else
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller {
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller __try {
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller MmProbeAndLockPages (pMdl,
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller KernelMode,
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller IoModifyAccess);
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller *ppvCtx = pMdl;
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller } __except(EXCEPTION_EXECUTE_HANDLER) {
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller IoFreeMdl (pMdl);
0b90cf39da4c7ba2b843ffd3512d84d009b5dff0Brendan Mmiller rc = VERR_INVALID_PARAMETER;
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller }
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller }
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller#else
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller NOREF(ppvCtx);
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller NOREF(pv);
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller NOREF(u32Size);
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller#endif /* __WIN__ */
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel return rc;
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel}
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feaselvoid vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size)
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel{
94dade725a55de70aec65a84bc4949882e5277b1Jake Feasel NOREF(pv);
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel NOREF(u32Size);
0c3f79f75f596c8d6700b2de830000f754bb28a9Phill Cunnington
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel#ifdef __WIN__
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel PMDL pMdl = (PMDL)pvCtx;
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel if (pMdl != NULL)
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel {
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel MmUnlockPages (pMdl);
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel IoFreeMdl (pMdl);
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel }
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel#else
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel NOREF(pvCtx);
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel#endif /* __WIN__ */
0942ced8a2cc0c0f5fb5015ec53f81d5360ee79cJake Feasel}
b4260bb3e2303240ecf6c7e4e5639439c3f98889Brendan Mmiller
#ifndef VBGL_VBOXGUEST
#if defined (__LINUX__) && !defined (__KERNEL__)
# include <unistd.h>
# include <errno.h>
# include <sys/fcntl.h>
# include <sys/ioctl.h>
#endif
#ifndef __WIN__
# ifdef __cplusplus
extern "C" {
# endif
extern DECLVBGL(void *) vboxadd_cmc_open (void);
extern DECLVBGL(void) vboxadd_cmc_close (void *);
extern DECLVBGL(int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
# ifdef __cplusplus
}
# endif
#endif
int vbglDriverOpen (VBGLDRIVER *pDriver)
{
#ifdef __WIN__
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 (__LINUX__)
void *opaque;
opaque = (void *) vboxadd_cmc_open ();
if (!opaque)
{
return VERR_NOT_IMPLEMENTED;
}
pDriver->opaque = opaque;
return VINF_SUCCESS;
#elif defined (__OS2__)
return VERR_NOT_IMPLEMENTED;
#else
# error "Port me"
#endif
}
int vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
{
#ifdef __WIN__
IO_STATUS_BLOCK ioStatusBlock;
KEVENT Event;
KeInitializeEvent (&Event, NotificationEvent, FALSE);
PIRP irp = IoBuildDeviceIoControlRequest (u32Function,
pDriver->pDeviceObject,
pvData,
cbData,
pvData,
cbData,
FALSE, /* external */
&Event,
&ioStatusBlock);
if (irp == NULL)
{
Log(("vbglDriverIOCtl: IoBuildDeviceIoControlRequest failed\n"));
return VERR_NO_MEMORY;
}
NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
if (rc == STATUS_PENDING)
{
Log(("vbglDriverIOCtl: STATUS_PENDING\n"));
rc = KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
rc = ioStatusBlock.Status;
}
if (!NT_SUCCESS(rc))
Log(("vbglDriverIOCtl: IoCallDriver failed with ntstatus=%x\n", rc));
return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
#elif defined (__LINUX__)
return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
#elif defined (__OS2__)
return VERR_NOT_IMPLEMENTED;
#else
# error "Port me"
#endif
}
void vbglDriverClose (VBGLDRIVER *pDriver)
{
#ifdef __WIN__
Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
ObDereferenceObject (pDriver->pFileObject);
#elif defined (__LINUX__)
vboxadd_cmc_close (pDriver->opaque);
#elif defined (__OS2__)
#else
# error "Port me"
#endif
}
#endif /* !VBGL_VBOXGUEST */