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);
+ 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);
+ 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@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
2017-05-19 22:58 GMT+02:00 Sri Ramanujam <sramanujam@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@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list -- Matthias Bolte http://photron.blogspot.com -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.