VirtualBox

Ignore:
Timestamp:
Jun 27, 2008 9:43:38 PM (17 years ago)
Author:
vboxsync
Message:

Additions/WINNT: add support for guest properties to VBoxControl

Location:
trunk/src/VBox/Additions/WINNT/VBoxControl
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxControl/Makefile.kmk

    r9664 r10008  
    3434
    3535# VBoxControl.cpp uses VBOX_SVN_REV.
    36 VBoxControl.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
     36VBoxControl.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV) VBOX_HGCM
    3737VBoxControl.cpp_DEPS = $(VBOX_SVN_REV_KMK)
    3838
  • trunk/src/VBox/Additions/WINNT/VBoxControl/VBoxControl.cpp

    r8155 r10008  
    2525#include <VBox/VBoxGuest.h>
    2626#include <VBox/version.h>
     27#include <VBox/HostServices/VBoxInfoSvc.h>
    2728
    2829void printHelp()
     
    4041           "VBoxControl   removecustommode <width> <height> <bpp>\n"
    4142           "\n"
    42            "VBoxControl   setvideomode <width> <height> <bpp> <screen>\n");
     43           "VBoxControl   setvideomode <width> <height> <bpp> <screen>\n"
     44           "\n"
     45           "VBoxControl   getguestproperty <key>\n"
     46           "\n"
     47           "VBoxControl   setguestproperty <key> [<value>] (no value to delete)\n");
    4348}
    4449
     
    779784
    780785/**
     786 * Open the VirtualBox guest device.
     787 * @returns IPRT status value
     788 * @param   hDevice  where to store the handle to the open device
     789 */
     790static int openGuestDevice(HANDLE *hDevice)
     791{
     792    if (!VALID_PTR(hDevice))
     793        return VERR_INVALID_POINTER;
     794    *hDevice = CreateFile(VBOXGUEST_DEVICE_NAME,
     795                          GENERIC_READ | GENERIC_WRITE,
     796                          FILE_SHARE_READ | FILE_SHARE_WRITE,
     797                          NULL,
     798                          OPEN_EXISTING,
     799                          FILE_ATTRIBUTE_NORMAL,
     800                          NULL);
     801    return (*hDevice != INVALID_HANDLE_VALUE) ? VINF_SUCCESS : VERR_OPEN_FAILED;
     802}
     803
     804
     805/**
     806 * Connect to an HGCM service.
     807 * @returns IPRT status code
     808 * @param   hDevice      handle to the VBox device
     809 * @param   pszService   the name of the service to connect to
     810 * @param   pu32ClientID where to store the connection handle
     811 */
     812static int hgcmConnect(HANDLE hDevice, char *pszService, uint32_t *pu32ClientID)
     813{
     814    if (!VALID_PTR(pszService) || !VALID_PTR(pu32ClientID))
     815        return VERR_INVALID_POINTER;
     816    VBoxGuestHGCMConnectInfo info;
     817    int rc = VINF_SUCCESS;
     818
     819    memset (&info, 0, sizeof (info));
     820    if (strlen(pszService) + 1 > sizeof(info.Loc.u.host.achName))
     821        return false;
     822    strcpy (info.Loc.u.host.achName, pszService);
     823    info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
     824    DWORD cbReturned;
     825    if (DeviceIoControl (hDevice,
     826                         IOCTL_VBOXGUEST_HGCM_CONNECT,
     827                         &info, sizeof (info),
     828                         &info, sizeof (info),
     829                         &cbReturned,
     830                         NULL))
     831        rc = info.result;
     832    else
     833        rc = VERR_FILE_IO_ERROR;
     834    if (RT_SUCCESS(rc))
     835        *pu32ClientID = info.u32ClientID;
     836    return rc;
     837}
     838
     839
     840/** Set a 32bit unsigned integer parameter to an HGCM request */
     841static void VbglHGCMParmUInt32Set(HGCMFunctionParameter *pParm, uint32_t u32)
     842{
     843    pParm->type = VMMDevHGCMParmType_32bit;
     844    pParm->u.value64 = 0; /* init unused bits to 0 */
     845    pParm->u.value32 = u32;
     846}
     847
     848
     849/** Get a 32bit unsigned integer returned from an HGCM request */
     850static int VbglHGCMParmUInt32Get(HGCMFunctionParameter *pParm, uint32_t *pu32)
     851{
     852    if (pParm->type == VMMDevHGCMParmType_32bit)
     853    {
     854        *pu32 = pParm->u.value32;
     855        return VINF_SUCCESS;
     856    }
     857    return VERR_INVALID_PARAMETER;
     858}
     859
     860
     861/** Set a pointer parameter to an HGCM request */
     862static void VbglHGCMParmPtrSet(HGCMFunctionParameter *pParm, void *pv, uint32_t cb)
     863{
     864    pParm->type                    = VMMDevHGCMParmType_LinAddr;
     865    pParm->u.Pointer.size          = cb;
     866    pParm->u.Pointer.u.linearAddr  = (uintptr_t)pv;
     867}
     868
     869
     870/** Make an HGCM call */
     871static int hgcmCall(HANDLE hDevice, VBoxGuestHGCMCallInfo *pMsg, size_t cbMsg)
     872{
     873    DWORD cbReturned;
     874    int rc = VERR_NOT_SUPPORTED;
     875
     876    if (DeviceIoControl (hDevice,
     877                         IOCTL_VBOXGUEST_HGCM_CALL,
     878                         pMsg, cbMsg,
     879                         pMsg, cbMsg,
     880                         &cbReturned,
     881                         NULL))
     882        rc = VINF_SUCCESS;
     883    return rc;
     884}
     885
     886
     887/**
     888 * Retrieve a property from the host/guest configuration registry
     889 * @returns  IPRT status code
     890 * @param hDevice handle to the VBox device
     891 * @param   u32ClientID     The client id returned by VbglR3ClipboardConnect().
     892 * @param   pszKey          The registry key to save to.
     893 * @param   pszValue        Where to store the value retrieved.
     894 * @param   cbValue         The size of the buffer pszValue points to.
     895 * @param   pcbActual       Where to store the required buffer size on
     896 *                          overflow or the value size on success.  A value
     897 *                          of zero means that the property does not exist.
     898 *                          Optional.
     899 */
     900static int hgcmInfoSvcGetProp(HANDLE hDevice, uint32_t u32ClientID,
     901                              char *pszKey, char *pszValue,
     902                              uint32_t cbValue, uint32_t *pcbActual)
     903{
     904    using namespace svcInfo;
     905
     906    if (!VALID_PTR(pszValue))
     907        return VERR_INVALID_POINTER;
     908    GetConfigKey Msg;
     909
     910    Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
     911    Msg.hdr.u32ClientID = u32ClientID;
     912    Msg.hdr.u32Function = GET_CONFIG_KEY;
     913    Msg.hdr.cParms = 3;
     914    VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1);
     915    VbglHGCMParmPtrSet(&Msg.value, pszValue, cbValue);
     916    VbglHGCMParmUInt32Set(&Msg.size, 0);
     917    int rc = hgcmCall(hDevice, &Msg.hdr, sizeof(Msg));
     918    if (RT_SUCCESS(rc))
     919        rc = Msg.hdr.result;
     920    uint32_t cbActual;
     921    if (RT_SUCCESS(rc))
     922        rc = VbglHGCMParmUInt32Get(&Msg.size, &cbActual);
     923    if (RT_SUCCESS(rc))
     924    {
     925        if (pcbActual != NULL)
     926            *pcbActual = cbActual;
     927        if (cbActual > cbValue)
     928            rc = VINF_BUFFER_OVERFLOW;
     929        else
     930            rc = Msg.hdr.result;
     931        if ((cbValue > 0) && (0 == cbActual))  /* No such property */
     932            pszValue[0] = 0;
     933           
     934    }
     935    return rc;
     936}
     937
     938
     939/**
     940 * Store a property from the host/guest configuration registry
     941 * @returns  IPRT status code
     942 * @param hDevice handle to the VBox device
     943 * @param   u32ClientID     The client id returned by VbglR3ClipboardConnect().
     944 * @param   pszKey          The registry key to save to.
     945 * @param   pszValue        The value to store.  If this is NULL then the key
     946 *                          will be removed.
     947 */
     948static int hgcmInfoSvcSetProp(HANDLE hDevice, uint32_t u32ClientID,
     949                              char *pszKey, char *pszValue)
     950{
     951    using namespace svcInfo;
     952
     953    if (!VALID_PTR(pszKey))
     954        return VERR_INVALID_POINTER;
     955    if (!VALID_PTR(pszValue) && (pszValue != NULL));
     956    int rc;
     957
     958    if (pszValue != NULL)
     959    {
     960        SetConfigKey Msg;
     961
     962        Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
     963        Msg.hdr.u32ClientID = u32ClientID;
     964        Msg.hdr.u32Function = SET_CONFIG_KEY;
     965        Msg.hdr.cParms = 2;
     966        VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1);
     967        VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1);
     968        rc = hgcmCall(hDevice, &Msg.hdr, sizeof(Msg));
     969        if (RT_SUCCESS(rc))
     970            rc = Msg.hdr.result;
     971    }
     972    else
     973    {
     974        DelConfigKey Msg;
     975
     976        Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
     977        Msg.hdr.u32ClientID = u32ClientID;
     978        Msg.hdr.u32Function = DEL_CONFIG_KEY;
     979        Msg.hdr.cParms = 1;
     980        VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1);
     981        rc = hgcmCall(hDevice, &Msg.hdr, sizeof(Msg));
     982        if (RT_SUCCESS(rc))
     983            rc = Msg.hdr.result;
     984    }
     985    return rc;
     986}
     987
     988
     989/** Disconnects from an HGCM service. */
     990static void hgcmDisconnect(HANDLE hDevice, uint32_t u32ClientID)
     991{
     992    if (u32ClientID == 0)
     993        return;
     994
     995    VBoxGuestHGCMDisconnectInfo info;
     996    memset (&info, 0, sizeof (info));
     997    info.u32ClientID = u32ClientID;
     998
     999    DWORD cbReturned;
     1000    DeviceIoControl (hDevice,
     1001                     IOCTL_VBOXGUEST_HGCM_DISCONNECT,
     1002                     &info, sizeof (info),
     1003                     &info, sizeof (info),
     1004                     &cbReturned,
     1005                     NULL);
     1006}
     1007
     1008
     1009/**
     1010 * Retrieves a value from the host/guest configuration registry.
     1011 * This is accessed through the "VBoxSharedInfoSvc" HGCM service.
     1012 *
     1013 * @returns IPRT status value
     1014 * @param   key  (string) the key which the value is stored under.
     1015 */
     1016static int handleGetGuestProperty(int argc, char *argv[])
     1017{
     1018    if (argc != 1)
     1019    {
     1020        printHelp();
     1021        return 1;
     1022    }
     1023    char szValue[svcInfo::KEY_MAX_VALUE_LEN];
     1024    HANDLE hDevice = INVALID_HANDLE_VALUE;
     1025    uint32_t u32ClientID = 0;
     1026    int rc = openGuestDevice(&hDevice);
     1027    if (!RT_SUCCESS(rc))
     1028        printf("Failed to open the VirtualBox device, RT error %d\n", rc);
     1029    if (RT_SUCCESS(rc))
     1030    {
     1031        rc = hgcmConnect(hDevice, "VBoxSharedInfoSvc", &u32ClientID);
     1032        if (!RT_SUCCESS(rc))
     1033            printf("Failed to connect to the host/guest registry service, RT error %d\n", rc);
     1034    }
     1035    if (RT_SUCCESS(rc))
     1036    {
     1037        rc = hgcmInfoSvcGetProp(hDevice, u32ClientID, argv[0], szValue,
     1038                                sizeof(szValue), NULL);
     1039        if (!RT_SUCCESS(rc))
     1040            printf("Failed to retrieve the property value, RT error %d\n", rc);
     1041    }
     1042    if (RT_SUCCESS(rc))
     1043    {
     1044        if (strlen(szValue) > 0)
     1045            printf("Value: %s\n", szValue);
     1046        else
     1047            printf("No value set!\n");
     1048    }
     1049    if (u32ClientID != 0)
     1050        hgcmDisconnect(hDevice, u32ClientID);
     1051    if (hDevice != INVALID_HANDLE_VALUE)
     1052        CloseHandle(hDevice);
     1053    return rc;
     1054}
     1055
     1056
     1057/**
     1058 * Writes a value to the host/guest configuration registry.
     1059 * This is accessed through the "VBoxSharedInfoSvc" HGCM service.
     1060 *
     1061 * @returns IPRT status value
     1062 * @param   key   (string) the key which the value is stored under.
     1063 * @param   value (string) the value to write.  If empty, the key will be
     1064 *                removed.
     1065 */
     1066static int handleSetGuestProperty(int argc, char *argv[])
     1067{
     1068    if (argc != 1 && argc != 2)
     1069    {
     1070        printHelp();
     1071        return 1;
     1072    }
     1073    HANDLE hDevice = INVALID_HANDLE_VALUE;
     1074    char *pszValue = NULL;
     1075    if (2 == argc)
     1076        pszValue = argv[1];
     1077    uint32_t u32ClientID = 0;
     1078    int rc = openGuestDevice(&hDevice);
     1079    if (!RT_SUCCESS(rc))
     1080        printf("Failed to open the VirtualBox device, RT error %d\n", rc);
     1081    if (RT_SUCCESS(rc))
     1082    {
     1083        rc = hgcmConnect(hDevice, "VBoxSharedInfoSvc", &u32ClientID);
     1084        if (!RT_SUCCESS(rc))
     1085            printf("Failed to connect to the host/guest registry service, RT error %d\n", rc);
     1086    }
     1087    if (RT_SUCCESS(rc))
     1088    {
     1089        rc = hgcmInfoSvcSetProp(hDevice, u32ClientID, argv[0], pszValue);
     1090        if (!RT_SUCCESS(rc))
     1091            printf("Failed to store the property value, RT error %d\n", rc);
     1092    }
     1093    if (u32ClientID != 0)
     1094        hgcmDisconnect(hDevice, u32ClientID);
     1095    if (hDevice != INVALID_HANDLE_VALUE)
     1096        CloseHandle(hDevice);
     1097    return rc;
     1098}
     1099
     1100
     1101/**
    7811102 * Main function
    7821103 */
     
    8231144        handleSetVideoMode(argc - 2, &argv[2]);
    8241145    }
     1146    else if (stricmp(argv[1], "getguestproperty") == 0)
     1147    {
     1148        int rc = handleGetGuestProperty(argc - 2, &argv[2]);
     1149        return RT_SUCCESS(rc) ? 0 : 1;
     1150    }
     1151    else if (stricmp(argv[1], "setguestproperty") == 0)
     1152    {
     1153        handleSetGuestProperty(argc - 2, &argv[2]);
     1154    }
    8251155    else
    8261156    {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette