[libvirt] [PATCH v4 4/5] hyperv: support virDomainSendKey
Matthias Bolte
matthias.bolte at googlemail.com
Sun May 28 16:38:45 UTC 2017
2017-05-19 22:58 GMT+02:00 Sri Ramanujam <sramanujam at datto.com>:
> This commit adds support for virDomainSendKey. It also serves as an
> example of how to use the new method invocation APIs with a single
> "simple" type parameter.
> ---
> src/hyperv/hyperv_driver.c | 107 ++++++++++++++++++++++++++++++++++
> src/hyperv/hyperv_wmi.c | 7 +++
> src/hyperv/hyperv_wmi.h | 3 +-
> src/hyperv/hyperv_wmi_generator.input | 86 +++++++++++++++++++++++++++
> 4 files changed, 202 insertions(+), 1 deletion(-)
>
> diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
> index 0ca5971..a01515a 100644
> --- a/src/hyperv/hyperv_driver.c
> +++ b/src/hyperv/hyperv_driver.c
> @@ -35,6 +35,8 @@
> #include "hyperv_wmi.h"
> #include "openwsman.h"
> #include "virstring.h"
> +#include "virkeycode.h"
> +#include "intprops.h"
>
> #define VIR_FROM_THIS VIR_FROM_HYPERV
>
> @@ -1373,6 +1375,110 @@ hypervConnectListAllDomains(virConnectPtr conn,
> #undef MATCH
>
>
> +static int
> +hypervDomainSendKey(virDomainPtr domain, unsigned int codeset,
> + unsigned int holdtime, unsigned int *keycodes, int nkeycodes,
> + unsigned int flags)
> +{
> + int result = -1;
> + size_t i = 0;
> + int keycode = 0;
> + int *translatedKeycodes = NULL;
> + hypervPrivate *priv = domain->conn->privateData;
> + char uuid_string[VIR_UUID_STRING_BUFLEN];
> + char *selector = NULL;
> + Msvm_ComputerSystem *computerSystem = NULL;
> + Msvm_Keyboard *keyboard = NULL;
> + virBuffer query = VIR_BUFFER_INITIALIZER;
> + hypervInvokeParamsListPtr params = NULL;
> + char keycodeStr[INT_BUFSIZE_BOUND(int)];
> +
> + virCheckFlags(0, -1);
> +
> + virUUIDFormat(domain->uuid, uuid_string);
> +
> + if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0)
> + goto cleanup;
> +
> + virBufferAsprintf(&query,
> + "associators of "
> + "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
> + "Name=\"%s\"} "
> + "where ResultClass = Msvm_Keyboard",
> + uuid_string);
> +
> + if (hypervGetMsvmKeyboardList(priv, &query, &keyboard) < 0)
> + goto cleanup;
> +
> + if (VIR_ALLOC_N(translatedKeycodes, nkeycodes) < 0)
> + goto cleanup;
> +
> + /* translate keycodes to win32 and generate keyup scancodes. */
> + for (i = 0; i < nkeycodes; i++) {
> + if (codeset != VIR_KEYCODE_SET_WIN32) {
> + keycode = virKeycodeValueTranslate(codeset, VIR_KEYCODE_SET_WIN32,
> + keycodes[i]);
> +
> + if (keycode < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Could not translate keycode"));
> + goto cleanup;
> + }
> + translatedKeycodes[i] = keycode;
> + }
> + }
> +
> + if (virAsprintf(&selector,
> + "CreationClassName=Msvm_Keyboard&DeviceID=%s&"
> + "SystemCreationClassName=Msvm_ComputerSystem&"
> + "SystemName=%s", keyboard->data.common->DeviceID, uuid_string) < 0)
> + goto cleanup;
> +
> + /* press the keys */
> + for (i = 0; i < nkeycodes; i++) {
> + snprintf(keycodeStr, sizeof(keycodeStr), "%d", translatedKeycodes[i]);
> +
> + params = hypervCreateInvokeParamsList(priv, "PressKey", selector,
> + Msvm_Keyboard_WmiInfo);
Shouldn't you check for params == NULL here?
> + if (hypervAddSimpleParam(params, "keyCode", keycodeStr) < 0)
> + goto cleanup;
> +
> + if (hypervInvokeMethod(priv, params, NULL) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not press key %d"),
> + translatedKeycodes[i]);
> + goto cleanup;
> + }
> + }
> +
> + /* simulate holdtime by sleeping */
> + if (holdtime > 0)
> + usleep(holdtime * 1000);
> +
> + /* release the keys */
> + for (i = 0; i < nkeycodes; i++) {
> + snprintf(keycodeStr, sizeof(keycodeStr), "%d", translatedKeycodes[i]);
> + params = hypervCreateInvokeParamsList(priv, "ReleaseKey", selector,
> + Msvm_Keyboard_WmiInfo);
Shouldn't you check for params == NULL here?
> + if (hypervAddSimpleParam(params, "keyCode", keycodeStr) < 0)
> + goto cleanup;
> +
> + if (hypervInvokeMethod(priv, params, NULL) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not release key %s"),
> + keycodeStr);
> + goto cleanup;
> + }
> + }
> +
> + result = 0;
> +
> + cleanup:
> + VIR_FREE(translatedKeycodes);
> + VIR_FREE(selector);
> + hypervFreeObject(priv, (hypervObject *) keyboard);
> + hypervFreeObject(priv, (hypervObject *) computerSystem);
> + virBufferFreeAndReset(&query);
> + return result;
> +}
>
>
> static virHypervisorDriver hypervHypervisorDriver = {
> @@ -1408,6 +1514,7 @@ static virHypervisorDriver hypervHypervisorDriver = {
> .domainManagedSave = hypervDomainManagedSave, /* 0.9.5 */
> .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
> .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
> + .domainSendKey = hypervDomainSendKey, /* TODO: version */
> .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
> };
>
> diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
> index b847d17..2165838 100644
> --- a/src/hyperv/hyperv_wmi.c
> +++ b/src/hyperv/hyperv_wmi.c
> @@ -1326,6 +1326,13 @@ hypervGetMsvmMemorySettingDataList(hypervPrivate *priv, virBufferPtr query,
> (hypervObject **) list);
> }
>
> +int hypervGetMsvmKeyboardList(hypervPrivate *priv, virBufferPtr query,
> + Msvm_Keyboard **list)
> +{
> + return hypervGetWmiClassList(priv, Msvm_Keyboard_WmiInfo, query,
> + (hypervObject **) list);
> +}
> +
>
>
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
> index f39f79f..eb6f43d 100644
> --- a/src/hyperv/hyperv_wmi.h
> +++ b/src/hyperv/hyperv_wmi.h
> @@ -217,7 +217,8 @@ int hypervGetMsvmProcessorSettingDataList(hypervPrivate *priv,
> int hypervGetMsvmMemorySettingDataList(hypervPrivate *priv, virBufferPtr query,
> Msvm_MemorySettingData **list);
>
> -
> +int hypervGetMsvmKeyboardList(hypervPrivate *priv, virBufferPtr query,
> + Msvm_Keyboard **list);
>
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> * Msvm_ComputerSystem
> diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
> index d7f819e..4ccda04 100644
> --- a/src/hyperv/hyperv_wmi_generator.input
> +++ b/src/hyperv/hyperv_wmi_generator.input
> @@ -956,3 +956,89 @@ class Msvm_VirtualHardDiskSettingData
> uint32 PhysicalSectorSize
> string VirtualDiskId
> end
> +
> +class Msvm_Keyboard
> + string Caption
> + string Description
> + string ElementName
> + datetime InstallDate
> + string Name
> + uint16 OperationalStatus[]
> + string StatusDescriptions[]
> + string Status
> + uint16 HealthState
> + uint16 EnabledState
> + string OtherEnabledState
> + uint16 RequestedState
> + uint16 EnabledDefault
> + datetime TimeOfLastStateChange
> + string SystemCreationClassName
> + string SystemName
> + string CreationClassName
> + string DeviceID
> + boolean PowerManagementSupported
> + uint16 PowerManagementCapabilities[]
> + uint16 Availability
> + uint16 StatusInfo
> + uint32 LastErrorCode
> + string ErrorDescription
> + boolean ErrorCleared
> + string OtherIdentifyingInfo[]
> + uint64 PowerOnHours
> + uint64 TotalPowerOnHours
> + string IdentifyingDescriptions[]
> + uint16 AdditionalAvailability[]
> + uint64 MaxQuiesceTime
> + uint16 LocationIndicator
> + boolean IsLocked
> + string Layout
> + uint16 NumberOfFunctionKeys
> + uint16 Password
> +end
> +
> +
> +class v2/Msvm_Keyboard
> + string InstanceID
> + string Caption
> + string Description
> + string ElementName
> + datetime InstallDate
> + string Name
> + uint16 OperationalStatus[]
> + string StatusDescriptions[]
> + string Status
> + uint16 HealthState
> + uint16 CommunicationStatus
> + uint16 DetailedStatus
> + uint16 OperatingStatus
> + uint16 PrimaryStatus
> + uint16 EnabledState
> + string OtherEnabledState
> + uint16 RequestedState
> + uint16 EnabledDefault
> + datetime TimeOfLastStateChange
> + uint16 AvailableRequestedStates[]
> + uint16 TransitioningToState
> + string SystemCreationClassName
> + string SystemName
> + string CreationClassName
> + string DeviceID
> + boolean PowerManagementSupported
> + uint16 PowerManagementCapabilities[]
> + uint16 Availability
> + uint16 StatusInfo
> + uint32 LastErrorCode
> + string ErrorDescription
> + boolean ErrorCleared
> + string OtherIdentifyingInfo[]
> + uint64 PowerOnHours
> + uint64 TotalPowerOnHours
> + string IdentifyingDescriptions[]
> + uint16 AdditionalAvailability[]
> + uint64 MaxQuiesceTime
> + boolean IsLocked
> + string Layout
> + uint16 NumberOfFunctionKeys
> + uint16 Password
> + boolean UnicodeSupported
> +end
> --
> 2.9.4
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
--
Matthias Bolte
http://photron.blogspot.com
More information about the libvir-list
mailing list