Authors: Simon Rastello (Bull), Adrien Kantcheff (Bull), Yves Vinter (Bull)

*** Summary of new features added in hyperv driver version 1.2.9 ***

- Added a mutex to prevent concurrent requests from being run simultaneously 
[WSMAN libray not thread-safe]
- Support of default authentication (credentials specified in 
~/.config/libvirt/auth.conf)
- Support of new types of WSMAN requests involving passing complex parameters 
(simple types, EPR, embedded objects)
  Required a new auto-generated header file to get the type of objects 
attributes (hyperv_wmi_classes_attr.generated.h)
- New functions:
        - host management (in hyperv_driver module)
                - capabilities (limited)
        - domain management (in hyperv_driver module)
                - domain creation from an XML description
                - domain destruction
                - attachment of pre-existing disk images on IDE controller
                - attachment of Synthetic network devices
                - memory and vcpu management (get and set methods)
                - autostart, shutdown, ...
        - network management (in hyperv_network_driver module)
                - list available networks
                - informations for a specified network
  Required the declaration of new classes (in hyperv_wmi_generator.input)
- Fixed several memory leak issues

*** Important note ***

The current implementation of the driver does not support the new WMI 
root/virtualization/v2 name space.
It is not compatible with the last version of Hyper-V coming with Windows 
Server 2012 R2.

*** Detail of the updates by module ***

hyperv_driver.c
+++++++++++++++

- Support of default authentication (credentials specified in 
~/.config/libvirt/auth.conf)

- Support of new libvirt functions
        .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 1.2.9 */
        .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 1.2.9 */
        .domainShutdown = hypervDomainShutdown, /* 1.2.9 */
        .domainShutdownFlags = hypervDomainShutdownFlags, /* 1.2.9 */
        .domainGetSchedulerParametersFlags = 
hypervDomainGetSchedulerParametersFlags, /* 1.2.9 */
        .domainGetSchedulerParameters = hypervDomainGetSchedulerParameters, /* 
1.2.9 */
        .domainGetSchedulerType = hypervDomainGetSchedulerType, /* 1.2.9 */
        .connectGetCapabilities = hypervConnectGetCapabilities, /* 1.2.9 */
        .connectGetVersion = hypervConnectGetVersion, /* 1.2.9 */
        .domainSetAutostart = hypervDomainSetAutostart, /* 1.2.9 */
        .domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.9 */
        .domainDefineXML = hypervDomainDefineXML, /* 1.2.9 */
        .domainSetMemory = hypervDomainSetMemory, /* 1.2.9 */
        .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.9 */
        .domainSetVcpus = hypervDomainSetVcpus, /* 1.2.9 */
        .domainSetVcpusFlags = hypervDomainSetVcpusFlags, /* 1.2.9 */
        .domainAttachDevice = hypervDomainAttachDevice, /* 1.2.9 */
        .domainAttachDeviceFlags = hypervDomainAttachDeviceFlags, /* 1.2.9 */
        .connectGetMaxVcpus = hypervConnectGetMaxVcpus, /* 1.2.9 */
        .domainCreateXML = hypervDomainCreateXML, /* 1.2.9 */
        .nodeGetFreeMemory = hypervNodeGetFreeMemory, /* 1.2.9 */
        .domainGetVcpus = hypervDomainGetVcpus, /* 1.2.9 */
        .domainUndefine = hypervDomainUndefine, /* 1.2.9 */
        .domainUndefineFlags = hypervDomainUndefineFlags, /* 1.2.9 */
        .domainGetAutostart = hypervDomainGetAutostart, /* 1.2.9 */

- Updated libvirt functions
    .connectOpen = hypervConnectOpen, /* 0.9.5 */
                Support of default authentication (credentials specified in 
~/.config/libvirt/auth.conf)

- New internal functions 
        - hypervLookupHostSystemBiosUuid
        - hypervCapsInit
        - hypervGetResourceAllocationSettingDataPATH
        - hypervGetSwitchPortPATH
        - hypervDomainAttachDisk
                Used by hypervDomainAttachDevice
                Currently support only attachments on the IDE controller 
(targets hda, hdb, hdc, hdd)  
        - hypervDomainAttachNetwork
                Used by hypervDomainAttachDevice
                Support attachment of synthetic network adapters (Legacy 
adapters are not supported)
        - integer2string

- Notes related to devices attachments
        - hypervDomainAttachDevice does not support attachment of ISO images 
(DVD drives)
        - attachment of disk drives on the iSCSI controller is not yet supported
        - devices detachment (drives or network) is not yet implemented
        - networks and disk images must have been provisioned manually
        - attached devices are not displayed in the domain XML description 
(hypervDomainGetXMLDesc)
        
hyperv_network_driver.c
+++++++++++++++++++++++

- Support of new libvirt function
        .connectNumOfNetworks = hypervConnectNumOfNetworks, /* 1.2.9 */
        .connectListNetworks = hypervConnectListNetworks, /* 1.2.9 */
        .connectNumOfDefinedNetworks = hypervConnectNumOfDefinedNetworks, /* 
1.2.9 */
        .connectListDefinedNetworks = hypervConnectListDefinedNetworks, /* 
1.2.9 */
        .networkLookupByName = hypervNetworkLookupByName, /* 1.2.9 */
        .networkGetXMLDesc = hypervNetworkGetXMLDesc, /* 1.2.9 */

hyperv_private.h
++++++++++++++++

- Added Caps, XMLOption and a Mutex in the private structure


hyperv_wmi.c
++++++++++++

- Added an internal flag to dump WSMAN requests (DUMP_REQUEST)
- Support of new types of WSMAN requests involving passing complex parameters 
(simple types, EPR, embedded objects)

- New functions
        - hypervInvokeMethod
        - hypervMsvmVirtualSwitchToNetwork
                Used by hypervNetworkLookupByName (hyperv_network_driver.c)

- New internal functions (used by hypervInvokeMethod)
        - hypervCreateXmlStruct
        - hypervGetPropType
        - hypervAddEmbeddedParam
        - hypervAddSimpleParam
        - hypervAddEprParam
        - hypervInvokeMethodXml

- Updated functions
        - hypervEnumAndPull
        - hypervInvokeMsvmComputerSystemRequestStateChange
                Added a mutex to protect against concurrent requests
                Added a call to dump WSMAN request in dump mode

                
hyperv_wmi.h
++++++++++++

- Added structures for passing new types of parameters (Simple, EPR, Embedded)
- Defined a new method to allow WSMAN requests with these different types of 
parameters (hypervInvokeMethod)


hyperv_wmi_generator.input
++++++++++++++++++++++++++

- Added new classes
        - CIM_DataFile 
        - Win32_ComputerSystemProduct
        - Msvm_VirtualSystemManagementService
        - Msvm_VirtualSystemGlobalSettingData
        - Msvm_ResourceAllocationSettingData
        - Msvm_AllocationCapabilities
        - Msvm_VirtualSwitch
        - Msvm_SwitchPort
        - Msvm_SyntheticEthernetPortSettingData
        - Msvm_VirtualSwitchManagementService
        - Win32_OperatingSystem
        - Win32_PerfFormattedData_HvStats_HyperVHypervisorVirtualProcessor
        - Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor


hyperv_wmi_generator.py
+++++++++++++++++++++++

- Takes into account the CIM_DataFile class (from the root/cimv2 WMI name space)

- Generated a new header file "hyperv_wmi_classes_attr.generated.h" for getting 
the type of objects attributes

- Added new functions for generating this new file
        - generate_tab_classes
                Generates an entry for the declaration of cimClasses types
        - generate_tabs_types
                Generates declarations of cimTypes types
        - generate_type_tab
                Generates an entry for the declaration of cimTypes types
        - print_type_header
                Generates the declaration of structures cimClasses and cimTypes
        

openwsman.h
+++++++++++

- Added functions prototypes from wsman-xml.h to handle XmlDoc

Reported-by: Yves Vinter <yves.vin...@bull.net>

---

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index aed9307..80fbb92 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -20,7 +20,15 @@
  *
  */
 
+/*
+ * This implementation does not support the new WMI root/virtualization/v2 
namespace.
+ * It is therefore not compatible with Hyper-V v3 and Windows Server 2012 R2.
+ * 
+ */
+
 #include <config.h>
+#include <string.h>
+#include <stdlib.h>
 
 #include "internal.h"
 #include "datatypes.h"
@@ -41,6 +49,7 @@
 #include "hyperv_wmi.h"
 #include "openwsman.h"
 #include "virstring.h"
+#include "virtypedparam.h"
 
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
@@ -58,12 +67,100 @@ hypervFreePrivate(hypervPrivate **priv)
         wsmc_release((*priv)->client);
     }
     
+    if ((*priv)->caps != NULL)
+        virObjectUnref((*priv)->caps);
+    if ((*priv)->xmlopt != NULL)
+        virObjectUnref((*priv)->xmlopt);
+    
+    /* Destroy the mutex */
+    pthread_mutex_destroy(&(*priv)->mutex);
+    
     hypervFreeParsedUri(&(*priv)->parsedUri);
     VIR_FREE(*priv);
 }
 
 
 
+static int
+hypervLookupHostSystemBiosUuid(hypervPrivate *priv, unsigned char *uuid)
+{
+    Win32_ComputerSystemProduct *computerSystem = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    int result = -1;
+    
+    virBufferAddLit(&query, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
+    
+    if (hypervGetWin32ComputerSystemProductList(priv, &query, &computerSystem) 
< 0) {
+        goto cleanup;
+    }
+    
+    if (computerSystem == NULL) {
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("Unable to get Win32_ComputerSystemProduct"));
+        goto cleanup;
+    }
+    
+    if (virUUIDParse(computerSystem->data->UUID, uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse UUID from string '%s'"),
+                       computerSystem->data->UUID);
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
+    return result;
+}
+
+
+
+static virCapsPtr hypervCapsInit(hypervPrivate *priv)
+{
+    virCapsPtr caps = NULL;
+    virCapsGuestPtr guest = NULL;
+    
+    caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
+    
+    if (caps == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+    //virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 });
+    
+    if (hypervLookupHostSystemBiosUuid(priv,caps->host.host_uuid) < 0) {
+        goto failure;
+    }
+    
+    /* i686 */
+    guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_I686, NULL, NULL, 0, 
NULL);
+    if (guest == NULL) {
+        goto failure;
+    }
+    if (virCapabilitiesAddGuestDomain(guest, "hyperv", NULL, NULL, 0, NULL) == 
NULL) {
+        goto failure;
+    }
+
+    /* x86_64 */
+    guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64, NULL, NULL, 
0, NULL);
+    if (guest == NULL) {
+        goto failure;
+    }
+    if (virCapabilitiesAddGuestDomain(guest, "hyperv", NULL, NULL, 0, NULL) == 
NULL) {
+        goto failure;
+    }
+
+    return caps;
+    
+ failure:
+    virObjectUnref(caps);
+    return NULL;
+}
+
+
+
 static virDrvOpenStatus
 hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int 
flags)
 {
@@ -108,12 +205,16 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
auth, unsigned int flags
         return VIR_DRV_OPEN_ERROR;
     }
     
-    /* Require auth */
-    if (auth == NULL || auth->cb == NULL) {
+    /* Uses default authentification mechanism when not provided */
+    if (auth == NULL)
+        auth = virConnectAuthPtrDefault;
+    else {
+        if (auth->cb == NULL) {
             virReportError(VIR_ERR_INVALID_ARG, "%s",
                            _("Missing or invalid auth pointer"));
             return VIR_DRV_OPEN_ERROR;
         }
+    }
     
     /* Allocate per-connection private data */
     if (VIR_ALLOC(priv) < 0)
@@ -192,7 +293,20 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
auth, unsigned int flags
         goto cleanup;
     }
     
+    /* Setup capabilities */
+    priv->caps = hypervCapsInit(priv);
+    if (priv->caps == NULL) {
+        goto cleanup;
+    }
+    
+    /* Init xmlopt to parse Domain XML */
+    priv->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL);
+    
     conn->privateData = priv;
+    
+    /* Initialize the mutex */
+    pthread_mutex_init(&priv->mutex, NULL);
+    
     priv = NULL;
     result = VIR_DRV_OPEN_SUCCESS;
     
@@ -200,6 +314,7 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
auth, unsigned int flags
     hypervFreePrivate(&priv);
     VIR_FREE(username);
     VIR_FREE(password);
+    virBufferFreeAndReset(&query);
     hypervFreeObject(priv, (hypervObject *)computerSystem);
     
     return result;
@@ -254,6 +369,7 @@ hypervConnectGetHostname(virConnectPtr conn)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
     
     return hostname;
 }
@@ -352,6 +468,7 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
     hypervFreeObject(priv, (hypervObject *)processorList);
+    virBufferFreeAndReset(&query);
     
     return result;
 }
@@ -396,6 +513,7 @@ hypervConnectListDomains(virConnectPtr conn, int *ids, int 
maxids)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+    virBufferFreeAndReset(&query);
     
     return success ? count : -1;
 }
@@ -432,6 +550,7 @@ hypervConnectNumOfDomains(virConnectPtr conn)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+    virBufferFreeAndReset(&query);
     
     return success ? count : -1;
 }
@@ -464,6 +583,7 @@ hypervDomainLookupByID(virConnectPtr conn, int id)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
     
     return domain;
 }
@@ -500,6 +620,7 @@ hypervDomainLookupByUUID(virConnectPtr conn, const unsigned 
char *uuid)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
     
     return domain;
 }
@@ -533,6 +654,7 @@ hypervDomainLookupByName(virConnectPtr conn, const char 
*name)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
     
     return domain;
 }
@@ -748,6 +870,7 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr 
info)
     hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
     hypervFreeObject(priv, (hypervObject *)processorSettingData);
     hypervFreeObject(priv, (hypervObject *)memorySettingData);
+    virBufferFreeAndReset(&query);
     
     return result;
 }
@@ -783,7 +906,10 @@ hypervDomainGetState(virDomainPtr domain, int *state, int 
*reason,
 }
 
 
-
+/* hypervDomainGetXMLDesc
+ * FIXME: 
+ *   - does not display attached devices (disk, nic)
+ */
 static char *
 hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
 {
@@ -915,6 +1041,7 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int 
flags)
     hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
     hypervFreeObject(priv, (hypervObject *)processorSettingData);
     hypervFreeObject(priv, (hypervObject *)memorySettingData);
+    virBufferFreeAndReset(&query);
     
     return xml;
 }
@@ -971,6 +1098,7 @@ hypervConnectListDefinedDomains(virConnectPtr conn, char 
**const names, int maxn
     }
     
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+    virBufferFreeAndReset(&query);
     
     return count;
 }
@@ -1007,6 +1135,7 @@ hypervConnectNumOfDefinedDomains(virConnectPtr conn)
     
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+    virBufferFreeAndReset(&query);
     
     return success ? count : -1;
 }
@@ -1346,6 +1475,7 @@ hypervConnectListAllDomains(virConnectPtr conn,
     }
     
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+    virBufferFreeAndReset(&query);
     
     return ret;
 }
@@ -1353,6 +1483,1778 @@ hypervConnectListAllDomains(virConnectPtr conn,
 
 
 
+static int
+hypervConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED)
+{
+    int res = -1;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_ProcessorSettingData *processorSettingData = NULL;
+    
+    /* Get Msvm_ProcessorSettingData maximum definition */
+    virBufferAddLit(&query, "SELECT * FROM Msvm_ProcessorSettingData "
+                    "WHERE InstanceID LIKE 'Microsoft:Definition%Maximum'");
+    
+    if (hypervGetMsvmProcessorSettingDataList(priv, &query, 
&processorSettingData) < 0) {
+        goto cleanup;
+    }
+    
+    if (processorSettingData == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get maximum definition of 
Msvm_ProcessorSettingData"));
+        goto cleanup;
+    }
+    
+    res = processorSettingData->data->SocketCount * 
+        processorSettingData->data->ProcessorsPerSocket;
+    
+ cleanup:
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) processorSettingData);
+    return res;
+}
+
+
+
+static int
+hypervDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
+{
+    int ret = -1;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    Msvm_ProcessorSettingData *processorSettingData = NULL;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |VIR_DOMAIN_VCPU_CONFIG 
|VIR_DOMAIN_VCPU_MAXIMUM, -1);
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    /* Get Msvm_ComputerSystem */
+    if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    
+    // If @flags includes VIR_DOMAIN_VCPU_LIVE, 
+    // this will query a running domain (which will fail if domain is not 
active)
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
+        if (computerSystem->data->EnabledState != 
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED) {
+            virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not 
active"));
+            goto cleanup;
+        }
+    }
+    
+    // If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum virtual 
CPU limit is queried
+    if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
+        ret = hypervConnectGetMaxVcpus(domain->conn, NULL);
+        goto cleanup;
+    }
+    
+    /* Get Msvm_VirtualSystemSettingData */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);              
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    if (virtualSystemSettingData == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for 
domain %s"),
+                       "Msvm_VirtualSystemSettingData", 
computerSystem->data->ElementName);
+        goto cleanup;
+    }
+    
+    /* Get Msvm_ProcessorSettingData */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_ProcessorSettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    if (hypervGetMsvmProcessorSettingDataList(priv, &query,
+                                              &processorSettingData) < 0) {
+        goto cleanup;
+    }
+    if (processorSettingData == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for 
domain %s"),
+                       "Msvm_ProcessorSettingData", 
computerSystem->data->ElementName);
+        goto cleanup;
+    }
+    
+    ret = processorSettingData->data->VirtualQuantity;
+    
+ cleanup:
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    hypervFreeObject(priv, (hypervObject *)processorSettingData);
+    return ret;
+}
+
+
+
+static int
+hypervDomainGetMaxVcpus(virDomainPtr dom)
+{
+    // If the guest is inactive, this is basically the same as 
virConnectGetMaxVcpus()
+    return (hypervDomainIsActive(dom)) ?
+        hypervDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE 
|VIR_DOMAIN_VCPU_MAXIMUM))
+        : hypervConnectGetMaxVcpus(dom->conn, NULL);
+}
+
+
+
+static int
+hypervDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
+{
+    int result = -1;
+    hypervPrivate *priv = domain->conn->privateData;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    bool in_transition = false;
+    
+    virCheckFlags(0, -1);
+    
+    if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    
+    if (!hypervIsMsvmComputerSystemActive(computerSystem, &in_transition) ||
+        in_transition) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("Domain is not active or is in state transition"));
+        goto cleanup;
+    }
+    
+    result = hypervInvokeMsvmComputerSystemRequestStateChange
+        (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_DISABLED);
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    return result;
+}
+
+
+
+static int hypervDomainShutdown(virDomainPtr dom)
+{
+    return hypervDomainShutdownFlags(dom, 0);
+}
+
+
+
+static int
+hypervDomainGetSchedulerParametersFlags(virDomainPtr dom, virTypedParameterPtr 
params,
+                                        int *nparams, unsigned int flags)
+{
+    hypervPrivate *priv = dom->conn->privateData;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    Msvm_ProcessorSettingData *processorSettingData = NULL;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    int ret = -1;
+    int saved_nparams = 0;
+    
+    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |VIR_DOMAIN_AFFECT_CONFIG 
|VIR_TYPED_PARAM_STRING_OKAY, -1);
+    
+    /* We don't return strings, and thus trivially support this flag.  */
+    flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
+    
+    virUUIDFormat(dom->uuid, uuid_string);
+    
+    /* Get Msvm_ComputerSystem */
+    if (hypervMsvmComputerSystemFromDomain(dom, &computerSystem) < 0) { goto 
cleanup;}
+    
+    /* Get Msvm_VirtualSystemSettingData */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);
+    
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, 
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    
+    if (virtualSystemSettingData == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not lookup %s for domain %s"),
+                       "Msvm_VirtualSystemSettingData",
+                       computerSystem->data->ElementName);
+        goto cleanup;
+    }
+    
+    /* Get Msvm_ProcessorSettingData */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_ProcessorSettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    
+    if (hypervGetMsvmProcessorSettingDataList(priv, &query,
+                                              &processorSettingData) < 0) { 
+        goto cleanup;
+    }
+    
+    if (processorSettingData == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for 
domain %s"),
+                       
"Msvm_ProcessorSettingData",computerSystem->data->ElementName);
+        goto cleanup;
+    }
+    
+    if (virTypedParameterAssign(&params[0], VIR_DOMAIN_SCHEDULER_LIMIT,
+                                VIR_TYPED_PARAM_LLONG, 
processorSettingData->data->Limit) < 0)
+        goto cleanup;
+    saved_nparams++;
+    
+    if (*nparams > saved_nparams) {
+        if 
(virTypedParameterAssign(&params[1],VIR_DOMAIN_SCHEDULER_RESERVATION,
+                                    VIR_TYPED_PARAM_LLONG, 
processorSettingData->data->Reservation) < 0)
+            goto cleanup;
+        saved_nparams++;
+    }
+    
+    if (*nparams > saved_nparams) {
+        if (virTypedParameterAssign(&params[2],VIR_DOMAIN_SCHEDULER_WEIGHT,
+                                    VIR_TYPED_PARAM_UINT, 
processorSettingData->data->Weight) < 0)
+            goto cleanup;
+        saved_nparams++;
+    }
+    
+    *nparams = saved_nparams;
+    
+    ret = 0;   
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    hypervFreeObject(priv, (hypervObject *)processorSettingData);
+    virBufferFreeAndReset(&query);
+    return ret;
+}
+
+
+
+static int 
+hypervDomainGetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr 
params, int *nparams)
+{
+    return hypervDomainGetSchedulerParametersFlags(dom, params, nparams, 
VIR_DOMAIN_AFFECT_CURRENT);
+}
+
+
+
+static char* 
+hypervDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED, int 
*nparams)
+{
+    char *type = strdup("allocation");
+    
+    if (type == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+    
+    if (nparams != NULL) {
+        *nparams = 3; /* reservation, limit, weight */
+    }
+    
+    return type;
+}
+
+
+
+static char*
+hypervConnectGetCapabilities(virConnectPtr conn)
+{
+    hypervPrivate *priv = conn->privateData;
+    char *xml = virCapabilitiesFormatXML(priv->caps);
+    
+    if (xml == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+    
+    return xml;
+}
+
+
+static int
+hypervConnectGetVersion(virConnectPtr conn, unsigned long *version)
+{
+    int ret = -1;
+    hypervPrivate *priv = conn->privateData;
+    CIM_DataFile  *datafile = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    char * p;
+    
+    virBufferAddLit(&query, " Select * from CIM_DataFile where 
Name='c:\\\\windows\\\\system32\\\\vmms.exe' ");
+    
+    if (hypervGetCIMDataFileList(priv, &query, &datafile) < 0) {goto cleanup;}
+    
+    // check the result of convertion 
+    if (datafile == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not lookup %s for domain %s"),
+                       "Msvm_VirtualSystemSettingData",
+                       datafile->data->Version);
+        goto cleanup;
+    }
+    
+    /* Delete release number and last digit of build number 1.1.111x.xxxx */
+    p = strrchr(datafile->data->Version,'.');
+    if (p == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse version number from '%s'"),
+                       datafile->data->Version);
+        goto cleanup;
+    }
+    p--;
+    *p = '\0';
+    
+    /*Parse Version String to Long*/
+    if (virParseVersionString(datafile->data->Version,
+                              version, true) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse version number from '%s'"),
+                       datafile->data->Version);
+        goto cleanup;
+    }
+    
+    ret = 0;   
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)datafile);
+    virBufferFreeAndReset(&query);
+    return ret;
+}
+
+
+
+static unsigned long long
+hypervNodeGetFreeMemory(virConnectPtr conn)
+{
+    unsigned long long res = 0;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Win32_OperatingSystem *operatingSystem = NULL;
+    
+    /* Get Win32_OperatingSystem */
+    virBufferAddLit(&query, WIN32_OPERATINGSYSTEM_WQL_SELECT);
+    
+    if (hypervGetWin32OperatingSystemList(priv, &query, &operatingSystem) < 0) 
{
+        goto cleanup;
+    }
+    
+    if (operatingSystem == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get Win32_OperatingSystem"));
+        goto cleanup;
+    }
+    
+    // return free memory in bytes
+    res = operatingSystem->data->FreePhysicalMemory * 1024;
+    
+ cleanup:
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) operatingSystem);
+    return res;
+}
+
+
+
+static int
+hypervDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, 
+                     unsigned char *cpumaps, int maplen)
+{
+    int count = 0, i;
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor 
+        *hypervVirtualProcessor = NULL;
+    
+    //FIXME: no information stored in cpumaps
+    if (cpumaps == NULL) {
+        cpumaps = (unsigned char *) calloc(maxinfo, maplen);
+    }
+    
+    /* Loop for each vCPU */
+    for (i = 0; i < maxinfo; i++) {
+        
+        /* Get vCPU stats */
+        hypervFreeObject(priv, (hypervObject *)hypervVirtualProcessor);
+        hypervVirtualProcessor = NULL;
+        virBufferFreeAndReset(&query);
+        virBufferAddLit(&query, 
+                       
WIN32_PERFRAWDATA_HVSTATS_HYPERVHYPERVISORVIRTUALPROCESSOR_WQL_SELECT);
+        // Attribute Name format : <domain_name>:Hv VP <vCPU_number>
+        virBufferAsprintf(&query, "where Name = \"%s:Hv VP %d\"", 
domain->name, i);
+        
+        if 
(hypervGetWin32PerfRawDataHvStatsHyperVHypervisorVirtualProcessorList(
+                priv, &query, &hypervVirtualProcessor) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not get stats on vCPU #%d"), i);
+            continue;
+        }
+        
+        /* Fill structure info */
+        info[i].number = i;
+        if (hypervVirtualProcessor == NULL) {
+            info[i].state = VIR_VCPU_OFFLINE;
+            info[i].cpuTime = 0LLU;
+            info[i].cpu = -1;
+        } else {
+            info[i].state = VIR_VCPU_RUNNING;
+            info[i].cpuTime = 
hypervVirtualProcessor->data->PercentTotalRunTime;
+            info[i].cpu = i;
+        }
+        
+        count++;
+    }
+    
+    hypervFreeObject(priv, (hypervObject *)hypervVirtualProcessor);
+    virBufferFreeAndReset(&query);
+    return count;
+}
+
+
+
+static int
+hypervDomainSetAutostart(virDomainPtr domain, int autostart)
+{
+    int res = -1;
+    invokeXmlParam *params = NULL;
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    virBuffer queryVssd = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    properties_t *tab_props = NULL;
+    eprParam eprparam; 
+    embeddedParam embeddedparam;
+    int nb_params;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    /* PREPARE EPR PARAM */
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+    eprparam.query = &query;
+    eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    /* PREPARE EMBEDDED PARAM */
+    virBufferAsprintf(&queryVssd,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);
+    
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &queryVssd,
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    
+    embeddedparam.nbProps = 2;
+    tab_props = (properties_t *) malloc(embeddedparam.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "AutomaticStartupAction"; 
+    (*tab_props).val = autostart ? "2" : "0";
+    (*(tab_props+1)).name = "InstanceID"; 
+    (*(tab_props+1)).val = virtualSystemSettingData->data->InstanceID; 
+    
+    embeddedparam.instanceName =  "Msvm_VirtualSystemGlobalSettingData";
+    embeddedparam.prop_t = tab_props;
+    
+    /* CREATE invokeXmlParam tab */
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "ComputerSystem";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam;
+    (*(params+1)).name = "SystemSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;       
+    (*(params+1)).param = &embeddedparam;
+    
+    res = hypervInvokeMethod(priv, params, nb_params, "ModifyVirtualSystem",
+                             MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector);
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    VIR_FREE(tab_props);
+    VIR_FREE(params);
+    virBufferFreeAndReset(&query);
+    virBufferFreeAndReset(&queryVssd);
+    return res;
+}
+
+
+
+static int
+hypervDomainGetAutostart(virDomainPtr domain, int *autostart)
+{
+    int res = -1;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSystemGlobalSettingData *vsgsd = NULL;
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    virBufferAddLit(&query, MSVM_VIRTUALSYSTEMGLOBALSETTINGDATA_WQL_SELECT);
+    virBufferAsprintf(&query, "where SystemName = \"%s\"", uuid_string);
+    
+    if (hypervGetMsvmVirtualSystemGlobalSettingDataList(priv,
+                                                        &query, &vsgsd) < 0) {
+        goto cleanup;
+    }
+    
+    *autostart = vsgsd->data->AutomaticStartupAction;
+    res = 0;
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)vsgsd);
+    virBufferFreeAndReset(&query);
+    return res;
+}
+
+
+/* Convert an integer value into a string */
+static char *integer2string(unsigned long value)
+{
+    int sz;
+    char *ret;
+
+    sz = snprintf (NULL, 0, "%lu", value);
+    ret = (char *) malloc ((sz+1)*sizeof(char));
+    if (ret != NULL)
+        sprintf(ret, "%lu", value);
+
+    return ret;
+}
+
+
+static int
+hypervDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
+{
+    int res = -1;
+    invokeXmlParam *params = NULL;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    properties_t *tab_props = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    virBuffer query2 = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    Msvm_MemorySettingData *memorySettingData = NULL;
+    eprParam eprparam; 
+    embeddedParam embeddedparam;
+    int nb_params;
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    unsigned long memory_mb = memory/1024;
+    char *memory_str = NULL;
+
+    // Memory value must be a multiple of 2 MB; round up it accordingly if 
necessary
+    if (memory_mb % 2) memory_mb++;
+
+    // Convert the memory value as a string value
+    memory_str = integer2string(memory_mb);
+
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    VIR_DEBUG("memory=%sMb, uuid=%s", memory_str, uuid_string);
+    
+    // PREPARE EPR PARAM
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+    eprparam.query = &query;
+    eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE EMBEDDED PARAM 1 
+    /* Get Msvm_VirtualSystemSettingData */
+    virBufferAsprintf(&query2,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);
+    
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query2,
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    
+    /* Get Msvm_MemorySettingData */
+    virBufferFreeAndReset(&query2);
+    virBufferAsprintf(&query2,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_MemorySettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    
+    if (hypervGetMsvmMemorySettingDataList(priv, &query2,
+                                           &memorySettingData) < 0) {
+        goto cleanup;
+    }
+    
+    embeddedparam.nbProps = 2;
+    tab_props = (properties_t *) malloc(embeddedparam.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "Limit"; 
+    (*tab_props).val = memory_str; 
+    (*(tab_props+1)).name = "InstanceID"; 
+    (*(tab_props+1)).val = memorySettingData->data->InstanceID;
+    embeddedparam.instanceName =  "Msvm_MemorySettingData";
+    embeddedparam.prop_t = tab_props;
+    embeddedparam.nbProps = 2;
+    
+    // CREATE invokeXmlParam
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    
+    (*params).name = "ComputerSystem";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;       
+    (*(params+1)).param = &embeddedparam;
+    
+    res = hypervInvokeMethod(priv, params, nb_params, 
"ModifyVirtualSystemResources",
+                             MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector);
+    
+ cleanup:
+    VIR_FREE(tab_props);
+    VIR_FREE(params);
+    VIR_FREE(memory_str);
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    hypervFreeObject(priv, (hypervObject *)memorySettingData);
+    virBufferFreeAndReset(&query);
+    virBufferFreeAndReset(&query2);
+    return res;
+}
+
+
+
+/* 
+ * Create the attribute __PATH for the RASD object. The attribute is build 
like this:
+ *   
\\<host_name>\root\virtualization:Msvm_ResourceAllocationSettingData.InstanceID="<rasdInstanceID>"
+ * where backslashes in rasdInstanceID are doubled
+ */
+static int
+hypervGetResourceAllocationSettingDataPATH(virDomainPtr domain, char 
*rasdInstanceID, char **__path)
+{
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    char *strTemp = NULL;
+    int ret = -1, i = 0, j = 0, n = 0;
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    /* Get host name */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_HostedDependency "
+                      "ResultClass = Msvm_ComputerSystem",
+                      uuid_string);
+    if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    if (computerSystem == NULL) {
+        virReportError(VIR_ERR_NO_DOMAIN, _("No domain with UUID %s"), 
uuid_string);
+        goto cleanup;
+    }
+    
+    /* Count the number of backslash character */
+    strTemp = strchr(rasdInstanceID, '\\');
+    while (strTemp != NULL) {
+        n++;
+        strTemp = strchr(++strTemp, '\\');
+    }
+    /* Double the blackslashes */
+    strTemp = (char *) malloc(strlen(rasdInstanceID) + (n+1)*sizeof(char));
+    while (rasdInstanceID[i] != '\0') {
+        strTemp[j] = rasdInstanceID[i];
+        if (rasdInstanceID[i] == '\\') {
+            j++;
+            strTemp[j] = '\\';
+        }
+        i++;
+        j++;
+    }
+    strTemp[j] = '\0';
+
+    /* Create the attribute __PATH */
+    //FIXME: ret is allocated with 255 characters (static value)
+    *__path = (char *) malloc(sizeof(*__path) * 255);
+    sprintf(*__path, "\\\\");
+    strcat(*__path, computerSystem->data->ElementName);
+    strcat(*__path, 
"\\root\\virtualization:Msvm_ResourceAllocationSettingData.InstanceID=\"");
+    strcat(*__path, strTemp);
+    strcat(*__path, "\"");
+    
+    ret = 0;
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
+    free(strTemp);
+    return ret;
+}
+
+
+
+/* 
+ * Create the attribute __PATH for the SwitchPort object. The attribute is 
build like this:
+ *   
\\<host_name>\root\virtualization:Msvm_SwitchPort.CreationClassName="Msvm_SwitchPort",
+ *   Name="<switchPortName>",SystemCreationClassName="Msvm_VirtualSwitch",
+ *   SystemName="<virtualSwitchSystemName>"
+ */
+static int
+hypervGetSwitchPortPATH(virDomainPtr domain, char *switchPortName,
+                        char *virtualSwitchSystemName, char **__path)
+{
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    char *strTemp = NULL;
+    int ret = -1;
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    /* Get host name */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_HostedDependency "
+                      "ResultClass = Msvm_ComputerSystem",
+                      uuid_string);
+    if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    if (computerSystem == NULL) {
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("No domain with UUID %s"), uuid_string);
+        goto cleanup;
+    }
+    
+    
+    /* Create the attribute __PATH */
+    //FIXME: ret is allocated with 511 characters (static value)
+    *__path = (char *) malloc(sizeof(*__path) * 511);
+    sprintf(*__path,
+            
"\\\\%s\\root\\virtualization:Msvm_SwitchPort.CreationClassName=\"Msvm_SwitchPort\","
+            
"Name=\"%s\",SystemCreationClassName=\"Msvm_VirtualSwitch\",SystemName=\"%s\"",
+            computerSystem->data->ElementName, switchPortName, 
virtualSwitchSystemName);
+    
+    ret = 0;
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
+    free(strTemp);
+    return ret;
+}
+
+
+
+/*
+ * Memory size in KiB
+ */
+static int
+hypervDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory, 
+                           unsigned int flags ATTRIBUTE_UNUSED)
+{
+    int res = -1, nb_params;
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    invokeXmlParam *params = NULL;
+    properties_t *tab_props = NULL;
+    eprParam eprparam; 
+    embeddedParam embeddedparam;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    Msvm_MemorySettingData *memorySettingData = NULL;
+    unsigned long memory_mb = memory/1024;
+    char *memory_str = NULL;
+
+    // Memory value must be a multiple of 2 MB; round up it accordingly if 
necessary
+    if (memory_mb % 2) memory_mb++;
+
+    // Convert the memory value as a string value
+    memory_str = integer2string(memory_mb);
+        
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    VIR_DEBUG("memory=%sMb, uuid=%s", memory_str, uuid_string);
+    
+    /* Get Msvm_VirtualSystemSettingData */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    
+    /* Get Msvm_MemorySettingData */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_MemorySettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    if (hypervGetMsvmMemorySettingDataList(priv, &query,
+                                           &memorySettingData) < 0) {
+        goto cleanup;
+    }
+    
+    // PREPARE EPR PARAM
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+    eprparam.query = &query;
+    eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE EMBEDDED PARAM
+    embeddedparam.nbProps = 2;
+    tab_props = (properties_t *) malloc(embeddedparam.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "VirtualQuantity"; 
+    (*tab_props).val = memory_str; 
+    (*(tab_props+1)).name = "InstanceID"; 
+    (*(tab_props+1)).val = memorySettingData->data->InstanceID;
+    embeddedparam.instanceName =  "Msvm_MemorySettingData";
+    embeddedparam.prop_t = tab_props;
+    
+    // CREATE invokeXmlParam
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "ComputerSystem";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;       
+    (*(params+1)).param = &embeddedparam;
+    
+    if (hypervInvokeMethod(priv, params, nb_params, 
"ModifyVirtualSystemResources",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not set domain 
memory"));
+        goto cleanup;
+    }
+    
+    res = 0;
+    
+ cleanup:
+    VIR_FREE(tab_props);
+    VIR_FREE(params);
+    VIR_FREE(memory_str);
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    hypervFreeObject(priv, (hypervObject *)memorySettingData);
+    virBufferFreeAndReset(&query);
+    return res;
+}
+
+
+static int
+hypervDomainSetMemory(virDomainPtr domain, unsigned long memory)
+{
+    return hypervDomainSetMemoryFlags(domain, memory, 0);
+}
+
+
+static int
+hypervDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
+                          unsigned int flags ATTRIBUTE_UNUSED)
+{
+    int res = -1;      
+    invokeXmlParam *params = NULL;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    properties_t *tab_props = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    Msvm_ProcessorSettingData *processorSettingData = NULL;
+    eprParam eprparam; 
+    embeddedParam embeddedparam;
+    int nb_params;
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char *nvcpus_str = NULL;
+
+    // Convert nvcpus as a string value
+    nvcpus_str = integer2string(nvcpus);
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    VIR_DEBUG("nvcpus=%s, uuid=%s", nvcpus_str, uuid_string);
+    
+    /* Get Msvm_VirtualSystemSettingData */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);
+    
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    
+    /* Get Msvm_ProcessorSettingData */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_ProcessorSettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    
+    if (hypervGetMsvmProcessorSettingDataList(priv, &query,
+                                              &processorSettingData) < 0) {
+        goto cleanup;
+    }
+    
+    if (processorSettingData == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not lookup Msvm_ProcessorSettingData for 
domain %s"),
+                       virtualSystemSettingData->data->ElementName);
+        goto cleanup;
+    }
+    
+    // PREPARE EPR PARAM
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+    eprparam.query = &query;
+    eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE EMBEDDED PARAM
+    embeddedparam.nbProps = 2;
+    tab_props = (properties_t *) malloc(embeddedparam.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "VirtualQuantity"; 
+    (*tab_props).val = nvcpus_str; 
+    (*(tab_props+1)).name = "InstanceID"; 
+    (*(tab_props+1)).val = processorSettingData->data->InstanceID;
+    embeddedparam.instanceName =  "Msvm_ProcessorSettingData";
+    embeddedparam.prop_t = tab_props;
+    
+    // CREATE invokeXmlParam
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "ComputerSystem";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;       
+    (*(params+1)).param = &embeddedparam;
+    
+    if (hypervInvokeMethod(priv, params, nb_params, 
"ModifyVirtualSystemResources",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not set domain 
vcpus"));
+        goto cleanup;
+    }
+    
+    res = 0;
+    
+ cleanup:
+    VIR_FREE(tab_props);
+    VIR_FREE(params);
+    VIR_FREE(nvcpus_str);
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    hypervFreeObject(priv, (hypervObject *)processorSettingData);
+    virBufferFreeAndReset(&query);
+    return res;
+}
+
+
+
+static int
+hypervDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
+{
+    return hypervDomainSetVcpusFlags(domain, nvcpus, 0);
+}
+
+
+/* hypervDomainAttachDisk
+ * FIXME:
+ *   - added ressources must me removed in case of error
+ *   - allow attaching disks on iSCSI (implemented only on IDE)
+ *   - allow attaching ISO images (on DVD devices)
+ *   - implement corresponding detach function
+ */
+static int
+hypervDomainAttachDisk(virDomainPtr domain, virDomainDiskDefPtr disk)
+{
+    int ret = -1, nb_params;
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    char *ideRasdPath = NULL, *newDiskDrivePath = NULL;
+    char *ideControler = NULL, *ideControlerAddr = NULL;
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+    Msvm_ResourceAllocationSettingData *resourceAllocationSettingData = NULL;
+    Msvm_ResourceAllocationSettingData *resourceAllocationSettingData2 = NULL;
+    Msvm_ResourceAllocationSettingData *resourceAllocationSettingData3 = NULL;
+    Msvm_ResourceAllocationSettingData *resourceAllocationSettingData4 = NULL;
+    Msvm_ResourceAllocationSettingData *ideRasd = NULL;  /* Part of 
resourceAllocationSettingData -> do not disallocate */
+    Msvm_ResourceAllocationSettingData *diskRasd = NULL;  /* Part of 
resourceAllocationSettingData2 -> do not disallocate */
+    Msvm_ResourceAllocationSettingData *newDiskDrive = NULL;  /* Part of 
resourceAllocationSettingData3 -> do not disallocate */
+    Msvm_AllocationCapabilities *allocationCapabilities  = NULL;
+    Msvm_AllocationCapabilities *allocationCapabilities2  = NULL;
+    invokeXmlParam *params = NULL;
+    properties_t *tab_props = NULL;
+    eprParam eprparam1, eprparam2; 
+    embeddedParam embeddedparam1, embeddedparam2;
+    
+    /* Initialization */
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    // Set IDE Controler 0 or 1 and address 0 or 1
+    ideControler = (char *) malloc(2*sizeof(char));
+    ideControlerAddr = (char *) malloc(2*sizeof(char));
+    if (strcmp(disk->dst, "hda") == 0) {
+        sprintf(ideControler, "%d", 0);
+        sprintf(ideControlerAddr, "%d", 0);
+    } else if (strcmp(disk->dst, "hdb") == 0) {
+        sprintf(ideControler, "%d", 0);
+        sprintf(ideControlerAddr, "%d", 1);
+    } else if (strcmp(disk->dst, "hdc") == 0) {
+        sprintf(ideControler, "%d", 1);
+        sprintf(ideControlerAddr, "%d", 0);
+    } else if (strcmp(disk->dst, "hdd") == 0) {
+        sprintf(ideControler, "%d", 1);
+        sprintf(ideControlerAddr, "%d", 1);
+    } else {
+        // IDE Controler 0 and address 0 by default
+        sprintf(ideControler, "%d", 0);
+        sprintf(ideControlerAddr, "%d", 0);
+    }
+    
+    VIR_DEBUG("src=%s, dst=IDE Controller %s:%s, uuid=%s",
+              disk->src->path, ideControler, ideControlerAddr, uuid_string);
+    
+    /* Get the current VM settings object */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineState "
+                      "ResultClass = Msvm_VirtualSystemSettingData",
+                      uuid_string);
+    if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
+                                                  &virtualSystemSettingData) < 
0) {
+        goto cleanup;
+    }
+    
+    /* Get the settings for IDE Controller on the VM */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_ResourceAllocationSettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
+                                                       
&resourceAllocationSettingData) < 0) {
+        goto cleanup;
+    }
+    ideRasd = resourceAllocationSettingData;
+    while (ideRasd != NULL) {
+        if (ideRasd->data->ResourceType == 5 &&
+            strcmp(ideRasd->data->Address, ideControler) == 0) {
+            // IDE Controller 0 or 1
+            break;
+        }
+        ideRasd = ideRasd->next;
+    }
+    if (ideRasd == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not find IDE Controller %s"), ideControler);
+        goto cleanup;
+    }
+    
+    /* Get the settings for 'Microsoft Synthetic Disk Drive' */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_ALLOCATIONCAPABILITIES_WQL_SELECT);
+    virBufferAddLit(&query, "WHERE ResourceSubType = 'Microsoft Synthetic Disk 
Drive'");
+    if (hypervGetMsvmAllocationCapabilitiesList(priv, &query,
+                                                &allocationCapabilities) < 0) {
+        goto cleanup;
+    }
+    
+    /* Get default values for 'Microsoft Synthetic Disk Drive' */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_AllocationCapabilities.InstanceID=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineCapabilities "
+                      "ResultClass = Msvm_ResourceAllocationSettingData",
+                      allocationCapabilities->data->InstanceID);
+    if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
+                                                       
&resourceAllocationSettingData2) < 0) {
+        goto cleanup;
+    }
+    diskRasd = resourceAllocationSettingData2;
+    while (diskRasd != NULL) {
+        if (strstr(diskRasd->data->InstanceID, "Default") != NULL) {
+            // Default values
+            break;
+        }
+        diskRasd = diskRasd->next;
+    }
+    if (diskRasd == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not get default values for 'Microsoft 
Synthetic Disk Drive'"));
+        goto cleanup;
+    }
+    
+    /* Create the attribute _PATH for the RASD object */
+    if (hypervGetResourceAllocationSettingDataPATH(domain, 
+                                                   ideRasd->data->InstanceID, 
&ideRasdPath) < 0) {
+        goto cleanup;
+    }
+    
+    /* Add default disk drive */
+    // PREPARE EPR PARAM
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+    eprparam1.query = &query;
+    eprparam1.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE EMBEDDED PARAM 1 
+    embeddedparam1.nbProps = 4;
+    tab_props = (properties_t *) malloc(embeddedparam1.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "Parent";
+    (*tab_props).val = ideRasdPath;
+    (*(tab_props+1)).name = "Address";
+    (*(tab_props+1)).val = ideControlerAddr;
+    (*(tab_props+2)).name = "ResourceType";
+    (*(tab_props+2)).val = "22";
+    (*(tab_props+3)).name = "ResourceSubType";
+    (*(tab_props+3)).val = diskRasd->data->ResourceSubType;
+    embeddedparam1.instanceName =  
MSVM_RESOURCEALLOCATIONSETTINGDATA_CLASSNAME;
+    embeddedparam1.prop_t = tab_props;
+    
+    // CREATE invokeXmlParam tab
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "TargetSystem";
+    (*params).type = EPR_PARAM;
+    (*params).param = &eprparam1;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;
+    (*(params+1)).param = &embeddedparam1;
+    
+    if (hypervInvokeMethod(priv, params, nb_params,    
"AddVirtualSystemResources",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not add default 
disk drive"));
+        goto cleanup;
+    }
+    
+    /* Get the instance of the new default drive disk */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+                      "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+                      "ResultClass = Msvm_ResourceAllocationSettingData",
+                      virtualSystemSettingData->data->InstanceID);
+    if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
+                                                       
&resourceAllocationSettingData3) < 0) {
+        goto cleanup;
+    }
+    newDiskDrive = resourceAllocationSettingData3;
+    while (newDiskDrive != NULL) {
+        if (newDiskDrive->data->ResourceType == 22 &&
+            strcmp(newDiskDrive->data->ResourceSubType, "Microsoft Synthetic 
Disk Drive") == 0 &&
+            strcmp(newDiskDrive->data->Parent, ideRasdPath) == 0 &&
+            strcmp(newDiskDrive->data->Address, ideControlerAddr) == 0) {
+            break;
+        }
+        newDiskDrive = newDiskDrive->next;
+    }
+    if (newDiskDrive == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not find 'Microsoft Synthetic Disk Drive'"));
+        goto cleanup;
+    }
+    
+    /* Get the settings for 'Microsoft Virtual Hard Disk' */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_ALLOCATIONCAPABILITIES_WQL_SELECT);
+    virBufferAddLit(&query, "WHERE ResourceSubType = 'Microsoft Virtual Hard 
Disk'");
+    if (hypervGetMsvmAllocationCapabilitiesList(priv, &query,
+                                                &allocationCapabilities2) < 0) 
{
+        goto cleanup;
+    }
+    
+    /* Get default values for 'Microsoft Virtual Hard Drive' */
+    virBufferFreeAndReset(&query);
+    virBufferAsprintf(&query,
+                      "associators of "
+                      "{Msvm_AllocationCapabilities.InstanceID=\"%s\"} "
+                      "where AssocClass = Msvm_SettingsDefineCapabilities "
+                      "ResultClass = Msvm_ResourceAllocationSettingData",
+                      allocationCapabilities2->data->InstanceID);
+    if (hypervGetMsvmResourceAllocationSettingDataList(priv, &query,
+                                                       
&resourceAllocationSettingData4) < 0) {
+        goto cleanup;
+    }
+    diskRasd = resourceAllocationSettingData4;
+    while (diskRasd != NULL) {
+        if (strstr(diskRasd->data->InstanceID, "Default") != NULL) {
+            // Default values
+            break;
+        }
+        diskRasd = diskRasd->next;
+    }
+    if (diskRasd == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not get default values for 'Microsoft Virtual 
Hard Drive'"));
+        goto cleanup;
+    }
+    
+    /* Create the attribute _PATH for the RASD object */
+    if (hypervGetResourceAllocationSettingDataPATH(domain, 
+                                                   
newDiskDrive->data->InstanceID, &newDiskDrivePath) < 0) {
+        goto cleanup;
+    }
+    
+    /* Add the new VHD */
+    // PREPARE EPR PARAM 2
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+    eprparam2.query = &query;
+    eprparam2.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE EMBEDDED PARAM 2
+    VIR_FREE(tab_props);
+    embeddedparam2.nbProps = 4;
+    tab_props = (properties_t *) malloc(embeddedparam2.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "Parent";
+    (*tab_props).val = newDiskDrivePath;
+    (*(tab_props+1)).name = "Connection";
+    (*(tab_props+1)).val = disk->src->path;
+    (*(tab_props+2)).name = "ResourceType";
+    (*(tab_props+2)).val = "21";
+    (*(tab_props+3)).name = "ResourceSubType";
+    (*(tab_props+3)).val = diskRasd->data->ResourceSubType;
+    embeddedparam2.instanceName =  
MSVM_RESOURCEALLOCATIONSETTINGDATA_CLASSNAME;
+    embeddedparam2.prop_t = tab_props;
+    
+    // CREATE invokeXmlParam tab
+    VIR_FREE(params);
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "TargetSystem";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam2;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;       
+    (*(params+1)).param = &embeddedparam2;
+    
+    if (hypervInvokeMethod(priv, params, nb_params, 
"AddVirtualSystemResources",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not attach hard disk drive"));
+        goto cleanup;
+    }
+    
+    ret = 0;
+    
+ cleanup:
+    if (ideRasdPath != NULL) VIR_FREE(ideRasdPath);
+    if (newDiskDrivePath != NULL) VIR_FREE(newDiskDrivePath);
+    if (ideControler != NULL) VIR_FREE(ideControler);
+    if (ideControlerAddr != NULL) VIR_FREE(ideControlerAddr);
+    if (tab_props != NULL) VIR_FREE(tab_props);
+    if (params != NULL) VIR_FREE(params);
+    hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+    hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData);
+    hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData2);
+    hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData3);
+    hypervFreeObject(priv, (hypervObject *)resourceAllocationSettingData4);
+    hypervFreeObject(priv, (hypervObject *)allocationCapabilities);
+    hypervFreeObject(priv, (hypervObject *)allocationCapabilities2);
+    virBufferFreeAndReset(&query);
+    
+    return ret;
+}
+
+
+
+/* hypervDomainAttachNetwork
+ * FIXME:
+ *   - implement corresponding detach function
+ */
+static int
+hypervDomainAttachNetwork(virDomainPtr domain, virDomainNetDefPtr net)
+{
+    int ret = -1, nb_params;
+    const char *selector1 = 
"CreationClassName=Msvm_VirtualSwitchManagementService";
+    const char *selector2 = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char uuid_string[VIR_UUID_STRING_BUFLEN], 
guid_string[VIR_UUID_STRING_BUFLEN];
+    unsigned char guid[VIR_UUID_BUFLEN];
+    char *virtualSystemIdentifiers = NULL, *switchPortPATH = NULL;
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    eprParam eprparam1, eprparam2;
+    simpleParam simpleparam1, simpleparam2, simpleparam3;
+    embeddedParam embeddedparam;
+    properties_t *tab_props = NULL;
+    invokeXmlParam *params = NULL;
+    Msvm_SwitchPort *switchPort = NULL;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    /* Initialization */
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    VIR_DEBUG("network=%s, uuid=%s", net->data.network.name, uuid_string);
+    
+    /* Create virtual switch port */
+    // PREPARE EPR PARAM 1
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where ElementName = \"%s\"", 
net->data.network.name);
+    eprparam1.query = &query;
+    eprparam1.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE SIMPLE PARAMS
+    virUUIDGenerate(guid);
+    virUUIDFormat(guid, guid_string);
+    simpleparam1.value = guid_string;
+    simpleparam2.value = "Dynamic Ethernet Switch Port";
+    simpleparam3.value = "";
+    
+    // CREATE invokeXmlParam tab
+    nb_params = 4;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "VirtualSwitch";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam1;
+    (*(params+1)).name = "Name";
+    (*(params+1)).type = SIMPLE_PARAM; 
+    (*(params+1)).param = &simpleparam1;
+    (*(params+2)).name = "FriendlyName";
+    (*(params+2)).type = SIMPLE_PARAM; 
+    (*(params+2)).param = &simpleparam2;
+    (*(params+3)).name = "ScopeOfResidence";
+    (*(params+3)).type = SIMPLE_PARAM; 
+    (*(params+3)).param = &simpleparam3;
+    
+    if (hypervInvokeMethod(priv, params, nb_params,    "CreateSwitchPort",
+                           MSVM_VIRTUALSWITCHMANAGEMENTSERVICE_RESOURCE_URI, 
selector1) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not create port for virtual switch '%s'"), 
net->data.network.name);
+        goto cleanup;
+    }
+    
+    /* Get a reference of the switch port created previously */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_SWITCHPORT_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", guid_string);
+    if (hypervGetMsvmSwitchPortList(priv, &query, &switchPort) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Method hypervGetMsvmSwitchPortList failed with 
query=%s"), query.e);
+        goto cleanup;
+    }
+    if (switchPort == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get switch port with Name=%s"), 
guid_string);
+        goto cleanup;
+    }
+    
+    /* Get a reference of the given virtual switch */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where ElementName = \"%s\"", 
net->data.network.name);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitch) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Method hypervGetMsvmVirtualSwitchList failed with 
query=%s"), query.e);
+        goto cleanup;
+    }
+    if (virtualSwitch == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get virtual switch '%s'"), 
net->data.network.name);
+        goto cleanup;
+    }
+    
+    /* Add the synthetic ethernet port to the VM */
+    // PREPARE EPR PARAM 2
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+    eprparam2.query = &query;
+    eprparam2.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // PREPARE EMBEDDED PARAM
+    virUUIDGenerate(guid);
+    virUUIDFormat(guid, guid_string);
+    virtualSystemIdentifiers = (char *) malloc((strlen(guid_string)+3) * 
sizeof(char));
+    sprintf(virtualSystemIdentifiers, "{%s}", guid_string);
+    hypervGetSwitchPortPATH(domain, switchPort->data->Name,
+                            virtualSwitch->data->Name, &switchPortPATH);
+    embeddedparam.nbProps = 5;
+    tab_props = (properties_t *) malloc(embeddedparam.nbProps * 
sizeof(properties_t));
+    (*tab_props).name = "Connection";
+    (*tab_props).val = switchPortPATH;
+    (*(tab_props+1)).name = "ElementName";
+    (*(tab_props+1)).val = "Network Adapter";
+    (*(tab_props+2)).name = "VirtualSystemIdentifiers";
+    (*(tab_props+2)).val = virtualSystemIdentifiers;
+    (*(tab_props+3)).name = "ResourceType";
+    (*(tab_props+3)).val = "10";
+    (*(tab_props+4)).name = "ResourceSubType";
+    (*(tab_props+4)).val = "Microsoft Synthetic Ethernet Port";
+    embeddedparam.instanceName =  
MSVM_SYNTHETICETHERNETPORTSETTINGDATA_CLASSNAME;
+    embeddedparam.prop_t = tab_props;
+    
+    // CREATE invokeXmlParam tab
+    VIR_FREE(params);
+    nb_params = 2;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "TargetSystem";
+    (*params).type = EPR_PARAM;        
+    (*params).param = &eprparam2;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;       
+    (*(params+1)).param = &embeddedparam;
+    
+    if (hypervInvokeMethod(priv, params, nb_params, 
"AddVirtualSystemResources",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector2) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not attach the network"));
+        goto cleanup;
+    }
+    
+    ret = 0;
+    
+ cleanup:
+    if (virtualSystemIdentifiers != NULL) VIR_FREE(virtualSystemIdentifiers);
+    if (switchPortPATH != NULL) VIR_FREE(switchPortPATH);
+    if (tab_props!= NULL) VIR_FREE(tab_props);
+    if (params != NULL) VIR_FREE(params);
+    hypervFreeObject(priv, (hypervObject *)switchPort);
+    hypervFreeObject(priv, (hypervObject *)virtualSwitch);
+    virBufferFreeAndReset(&query);
+
+    return ret;
+}
+
+
+static int
+hypervDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
+                              unsigned int flags ATTRIBUTE_UNUSED)
+{
+    int ret = -1;
+    hypervPrivate *priv = domain->conn->privateData;
+    virDomainDefPtr def = NULL;
+    virDomainDeviceDefPtr dev = NULL;
+    char *xmlDomain = NULL;
+    
+    // Get domain definition
+    if ((xmlDomain = hypervDomainGetXMLDesc(domain, 0)) == NULL) {
+        goto cleanup;
+    }
+    if ((def = virDomainDefParseString(xmlDomain, priv->caps, priv->xmlopt, 
+                                       1 << VIR_DOMAIN_VIRT_HYPERV, 
VIR_DOMAIN_XML_INACTIVE)) == NULL) {
+        goto cleanup;
+    }
+    
+    // Get domain device definition
+    if ((dev = virDomainDeviceDefParse(xml, def, priv->caps,
+                                       priv->xmlopt, VIR_DOMAIN_XML_INACTIVE)) 
== NULL) {
+        goto cleanup;
+    }
+    
+    switch (dev->type) {
+        /* Device = disk */
+    case VIR_DOMAIN_DEVICE_DISK:
+        if (hypervDomainAttachDisk(domain, dev->data.disk) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not attach disk"));
+            goto cleanup;
+        }
+        VIR_DEBUG("Disk attached");
+        break;
+        
+        /* Device = network */
+    case VIR_DOMAIN_DEVICE_NET:
+        if (hypervDomainAttachNetwork(domain, dev->data.net) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not attach network"));
+            goto cleanup;
+        }
+        VIR_DEBUG("Network attached");
+        break;
+        
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Device attachment of type %d is not implemented"), 
dev->type);
+        goto cleanup;
+    }
+    
+    ret = 0;
+    
+ cleanup:
+    virDomainDefFree(def);
+    virDomainDeviceDefFree(dev);
+    if (xmlDomain != NULL) VIR_FREE(xmlDomain);
+
+    return ret;
+}
+
+
+
+static int
+hypervDomainAttachDevice(virDomainPtr domain, const char *xml)
+{
+    return hypervDomainAttachDeviceFlags(domain, xml, 0);
+}
+
+
+
+static virDomainPtr
+hypervDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+    hypervPrivate *priv = conn->privateData;
+    virDomainDefPtr def = NULL;
+    virDomainPtr domain = NULL;
+    invokeXmlParam *params = NULL;
+    properties_t *tab_props = NULL;
+    embeddedParam embeddedparam;
+    int nb_params, i;
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    
+    // Parsing XML
+    if ((def = virDomainDefParseString(xml, priv->caps, priv->xmlopt,
+                                       1 << VIR_DOMAIN_VIRT_HYPERV, 
VIR_DOMAIN_XML_INACTIVE)) == NULL) {
+        goto cleanup;
+    }
+    
+    /* Create the VM if not exists */
+    if (!(def->uuid != NULL &&
+          (domain = hypervDomainLookupByUUID(conn, def->uuid)) != NULL)) {
+        
+        // PREPARE EMBEDDED PARAM
+        /* Edit only VM name */
+        //FIXME: cannot edit VM UUID
+        embeddedparam.nbProps = 1;
+        tab_props = (properties_t *) malloc(embeddedparam.nbProps * 
sizeof(properties_t));
+        (*tab_props).name = "ElementName";
+        (*tab_props).val = def->name;
+        embeddedparam.instanceName = "Msvm_VirtualSystemGlobalSettingData";
+        embeddedparam.prop_t = tab_props;
+        
+        // CREATE invokeXmlParam
+        nb_params = 1;
+        params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+        (*params).name = "SystemSettingData";
+        (*params).type = EMBEDDED_PARAM;       
+        (*params).param = &embeddedparam;
+        
+        /* Create VM */
+        if (hypervInvokeMethod(priv, params, nb_params, "DefineVirtualSystem",
+                               
MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, selector) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not create new domain %s"), def->name);
+            goto cleanup;
+        }
+        
+        // Get domain pointer
+        domain = hypervDomainLookupByName(conn, def->name);
+        
+        VIR_DEBUG("Domain created: name=%s, uuid=%s", 
+                  domain->name, virUUIDFormat(domain->uuid, uuid_string));
+    }
+    
+    /* Set VM maximum memory */
+    if (def->mem.max_balloon > 0) {
+        if (hypervDomainSetMaxMemory(domain, def->mem.max_balloon) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not set VM maximum memory"));
+        }
+    }
+    
+    /* Set VM memory */
+    if (def->mem.cur_balloon > 0) {
+        if (hypervDomainSetMemory(domain, def->mem.cur_balloon) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not set VM memory"));
+        }
+    }
+    
+    /* Set VM vcpus */
+    if (def->vcpus > 0) {
+        if (hypervDomainSetVcpus(domain, def->vcpus) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not set VM vCPUs"));
+        }
+    }
+    
+    /* Attach networks */
+    for (i = 0; i < def->nnets; i++) {
+        if (hypervDomainAttachNetwork(domain, def->nets[i]) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not attach network"));
+        }
+    }
+    
+    /* Attach disks */
+    for (i = 0; i < def->ndisks; i++) {
+        if (hypervDomainAttachDisk(domain, def->disks[i]) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not attach disk"));
+        }
+    }
+    
+ cleanup:
+    virDomainDefFree(def);
+    if (tab_props != NULL) VIR_FREE(tab_props);
+    if (params != NULL) VIR_FREE(params);
+
+    return domain;
+}
+
+
+
+static virDomainPtr
+hypervDomainCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int 
flags)
+{
+    virDomainPtr domain;
+    
+    virCheckFlags(VIR_DOMAIN_NONE |VIR_DOMAIN_START_PAUSED 
|VIR_DOMAIN_START_AUTODESTROY, NULL);
+    
+    // Create new domain
+    domain = hypervDomainDefineXML(conn, xmlDesc);
+    if (domain == NULL)
+        return NULL;
+
+    // Start domain
+    if (hypervInvokeMsvmComputerSystemRequestStateChange(domain,
+                                                         
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not start the domain %s"), domain->name);
+        return domain;
+    }
+    
+    // If the VIR_DOMAIN_START_PAUSED flag is set,
+    // the guest domain will be started, but its CPUs will remain paused
+    if (flags & VIR_DOMAIN_START_PAUSED) {
+        if (hypervDomainSuspend(domain) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not pause the domain %s"), domain->name);
+        }
+    }
+    
+    // If the VIR_DOMAIN_START_AUTODESTROY flag is set, 
+    // the guest domain will be automatically destroyed 
+    // when the virConnectPtr object is finally released
+    if (flags & VIR_DOMAIN_START_AUTODESTROY) {
+        //FIXME: wait till virConnectPtr is released
+        if (hypervDomainDestroy(domain) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not destroy the domain %s"), domain->name);
+        }
+    }
+    
+    return domain;
+}
+
+
+
+static int
+hypervDomainUndefineFlags(virDomainPtr domain, unsigned int flags 
ATTRIBUTE_UNUSED)
+{
+    int result = -1, nb_params;
+    const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;    
+    invokeXmlParam *params = NULL;
+    eprParam eprparam; 
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    
+    virCheckFlags(0, -1);
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    
+    /* Shutdown the VM if not disabled */
+    if (computerSystem->data->EnabledState != 
+        MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED) {
+        if (hypervDomainShutdown(domain) < 0) {
+            goto cleanup;
+        }
+    }
+    
+    /* Deleting the VM */
+    
+    // PREPARE EPR PARAM
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+    eprparam.query = &query;
+    eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    // CREATE invokeXmlParam tab
+    nb_params = 1;
+    params = (invokeXmlParam *) malloc(nb_params * sizeof(invokeXmlParam));
+    (*params).name = "ComputerSystem";
+    (*params).type = EPR_PARAM;
+    (*params).param = &eprparam;
+    
+    // DESTROY VM
+    if (hypervInvokeMethod(priv, params, nb_params,    "DestroyVirtualSystem",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not delete 
domain"));
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup:
+    if (params != NULL) VIR_FREE(params);
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    virBufferFreeAndReset(&query);
+
+    return result;
+}
+
+
+
+static int
+hypervDomainUndefine(virDomainPtr domain)
+{
+    return hypervDomainUndefineFlags(domain, 0);
+}
+
+
 
 static virDriver hypervDriver = {
     .no = VIR_DRV_HYPERV,
@@ -1389,6 +3291,31 @@ static virDriver hypervDriver = {
     .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
     .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
     .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
+    .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 1.2.9 */
+    .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 1.2.9 */
+    .domainShutdown = hypervDomainShutdown, /* 1.2.9 */
+    .domainShutdownFlags = hypervDomainShutdownFlags, /* 1.2.9 */
+    .domainGetSchedulerParametersFlags = 
hypervDomainGetSchedulerParametersFlags, /* 1.2.9 */
+    .domainGetSchedulerParameters = hypervDomainGetSchedulerParameters, /* 
1.2.9 */
+    .domainGetSchedulerType = hypervDomainGetSchedulerType, /* 1.2.9 */
+    .connectGetCapabilities = hypervConnectGetCapabilities, /* 1.2.9 */
+    .connectGetVersion = hypervConnectGetVersion, /* 1.2.9 */
+    .domainSetAutostart = hypervDomainSetAutostart, /* 1.2.9 */
+    .domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.9 */
+    .domainDefineXML = hypervDomainDefineXML, /* 1.2.9 */
+    .domainSetMemory = hypervDomainSetMemory, /* 1.2.9 */
+    .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.9 */
+    .domainSetVcpus = hypervDomainSetVcpus, /* 1.2.9 */
+    .domainSetVcpusFlags = hypervDomainSetVcpusFlags, /* 1.2.9 */
+    .domainAttachDevice = hypervDomainAttachDevice, /* 1.2.9 */
+    .domainAttachDeviceFlags = hypervDomainAttachDeviceFlags, /* 1.2.9 */
+    .connectGetMaxVcpus = hypervConnectGetMaxVcpus, /* 1.2.9 */
+    .domainCreateXML = hypervDomainCreateXML, /* 1.2.9 */
+    .nodeGetFreeMemory = hypervNodeGetFreeMemory, /* 1.2.9 */
+    .domainGetVcpus = hypervDomainGetVcpus, /* 1.2.9 */
+    .domainUndefine = hypervDomainUndefine, /* 1.2.9 */
+    .domainUndefineFlags = hypervDomainUndefineFlags, /* 1.2.9 */
+    .domainGetAutostart = hypervDomainGetAutostart, /* 1.2.9 */
 };
 
 
diff --git a/src/hyperv/hyperv_network_driver.c 
b/src/hyperv/hyperv_network_driver.c
index 6f54f44..ad24431 100644
--- a/src/hyperv/hyperv_network_driver.c
+++ b/src/hyperv/hyperv_network_driver.c
@@ -28,6 +28,9 @@
 #include "viralloc.h"
 #include "viruuid.h"
 #include "hyperv_network_driver.h"
+#include "virstring.h"
+#include "hyperv_wmi.h"
+#include "network_conf.h"
 
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
@@ -60,11 +63,246 @@ hypervNetworkClose(virConnectPtr conn)
 }
 
 
+static int
+hypervConnectNumOfNetworks(virConnectPtr conn)
+{
+    int ret = -1, count = 0;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSwitch *virtualSwitchList = NULL;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where HealthState = %d", 5);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+        goto cleanup;
+    }
+    
+    for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+         virtualSwitch = virtualSwitch->next) {
+        count++;
+    }
+    
+    ret = count;
+    
+ cleanup:
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+    return ret;
+}
+
+
+static int
+hypervConnectListNetworks(virConnectPtr conn, char **const names, int maxnames)
+{
+    int i, count = 0;
+    bool success = false;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSwitch *virtualSwitchList = NULL;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    if (maxnames <= 0) {
+        return 0;
+    }
+    
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where HealthState = %d", 5);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+        goto cleanup;
+    }
+    
+    for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+         virtualSwitch = virtualSwitch->next) {
+        if (VIR_STRDUP(names[count], virtualSwitch->data->ElementName) < 0) {
+            goto cleanup;
+        }
+        count++;
+        if (count >= maxnames) {
+            break;
+        }
+    }
+    
+    success = true;
+    
+ cleanup:
+    if (!success) {
+        for (i = 0; i < count; ++i) {
+            VIR_FREE(names[i]);
+        }
+        count = -1;
+    }
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+    return count;
+}
+
+
+static int
+hypervConnectNumOfDefinedNetworks(virConnectPtr conn)
+{
+    int ret = -1, count = 0;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSwitch *virtualSwitchList = NULL;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where HealthState <> %d", 5);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+        goto cleanup;
+    }
+    
+    for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+         virtualSwitch = virtualSwitch->next) {
+        count++;
+    }
+    
+    ret = count;
+    
+ cleanup:
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+    return ret;
+}
+
+
+static int
+hypervConnectListDefinedNetworks(virConnectPtr conn, char **const names, int 
maxnames)
+{
+    int i, count = 0;
+    bool success = false;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSwitch *virtualSwitchList = NULL;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    if (maxnames <= 0) {
+        return 0;
+    }
+    
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where HealthState <> %d", 5);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+        goto cleanup;
+    }
+    
+    for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+         virtualSwitch = virtualSwitch->next) {
+        if (VIR_STRDUP(names[count], virtualSwitch->data->ElementName) < 0) {
+            goto cleanup;
+        }
+        count++;
+        if (count >= maxnames) {
+            break;
+        }
+    }
+    
+    success = true;
+    
+ cleanup:
+    if (!success) {
+        for (i = 0; i < count; ++i) {
+            VIR_FREE(names[i]);
+        }
+        count = -1;
+    }
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+    return count;
+}
+
+
+static virNetworkPtr
+hypervNetworkLookupByName(virConnectPtr conn, const char *name)
+{
+    virNetworkPtr network = NULL;
+    hypervPrivate *priv = conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where Description = \"%s\" and ElementName = 
\"%s\"",
+                      "Microsoft Virtual Switch", name);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitch) < 0) {
+        goto cleanup;
+    }
+    if (virtualSwitch == NULL) {
+        virReportError(VIR_ERR_NO_NETWORK,
+                       _("No network found with name %s"), name);
+        goto cleanup;
+    }
+    
+    hypervMsvmVirtualSwitchToNetwork(conn, virtualSwitch, &network);
+    
+ cleanup:
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *) virtualSwitch);
+    return network;
+}
+
+
+static char *
+hypervNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags)
+{
+    char *xml = NULL;
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = network->conn->privateData;
+    virNetworkDefPtr def = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    /* Flags checked by virNetworkDefFormat */
+    
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+    
+    virUUIDFormat(network->uuid, uuid_string);
+    
+    /* Get Msvm_VirtualSwitch */
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitch) < 0) {
+        goto cleanup;
+    }
+    if (virtualSwitch == NULL) {
+        virReportError(VIR_ERR_NO_NETWORK,
+                       _("No network found with UUID %s"), uuid_string);
+        goto cleanup;
+    }
+    
+    /* Fill struct */
+    if (virUUIDParse(virtualSwitch->data->Name, def->uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse UUID from string '%s'"),
+                       virtualSwitch->data->Name);
+        return NULL;
+    }
+    
+    if (VIR_STRDUP(def->name, virtualSwitch->data->ElementName) < 0)
+        goto cleanup;
+    
+    xml = virNetworkDefFormat(def, flags);
+    
+ cleanup:
+    virNetworkDefFree(def);
+    virBufferFreeAndReset(&query);
+    hypervFreeObject(priv, (hypervObject *)virtualSwitch);
+    return xml;
+}
 
 static virNetworkDriver hypervNetworkDriver = {
     .name = "Hyper-V",
     .networkOpen = hypervNetworkOpen, /* 0.9.5 */
     .networkClose = hypervNetworkClose, /* 0.9.5 */
+    .connectNumOfNetworks = hypervConnectNumOfNetworks, /* 1.2.9 */
+    .connectListNetworks = hypervConnectListNetworks, /* 1.2.9 */
+    .connectNumOfDefinedNetworks = hypervConnectNumOfDefinedNetworks, /* 1.2.9 
*/
+    .connectListDefinedNetworks = hypervConnectListDefinedNetworks, /* 1.2.9 */
+    .networkLookupByName = hypervNetworkLookupByName, /* 1.2.9 */
+    .networkGetXMLDesc = hypervNetworkGetXMLDesc, /* 1.2.9 */
 };
 
 
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index 574bb5f..7c28053 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -27,12 +27,21 @@
 # include "virerror.h"
 # include "hyperv_util.h"
 # include "openwsman.h"
+# include "capabilities.h"
+# include "domain_conf.h"
+
+#ifndef WIN32
+# include <pthread.h>
+#endif
 
 typedef struct _hypervPrivate hypervPrivate;
 
 struct _hypervPrivate {
     hypervParsedUri *parsedUri;
     WsManClient *client;
+    virCapsPtr caps;
+    virDomainXMLOptionPtr xmlopt; /* to parse Domain XML */ 
+    pthread_mutex_t mutex; /* to protect against concurrent calls (openwsman 
library not thread-safe) */ 
 };
 
 #endif /* __HYPERV_PRIVATE_H__ */
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index acb705c..e84e208 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -33,16 +33,752 @@
 #include "hyperv_wmi.h"
 #include "virstring.h"
 
+# include <wsman-xml-api.h>
+# include <wsman-client.h>
+# include <wsman-client-transport.h>
+# include <wsman-soap.h>
+# include <libxml/tree.h>
+# include "hyperv_wmi_classes_attr.generated.h"
+
 #define WS_SERIALIZER_FREE_MEM_WORKS 0
 
-#define ROOT_CIMV2 \
-    "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/*";
+#define VIR_FROM_THIS VIR_FROM_HYPERV
 
-#define ROOT_VIRTUALIZATION \
-    "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/*";
+/* Flag to dump WSMAN requests */
+#define DUMP_REQUEST 0
 
-#define VIR_FROM_THIS VIR_FROM_HYPERV
+/*
+  CAUTION: Special note regarding multi-threading 
+  The openwsman library is not thread-safe (as reported in issue #10 
"Simultaneous WsMan queries")
+  It has not been designed to allow to share the same connection for 
concurrent calls to wsmc_action_xxxx fonctions.
+  This implementation of this hyperv libvirt driver shares the same connection 
for all these calls. 
+  Therefore, we have used a mutex to protect all functions that make usage of 
the wsmc_action_xxxx fonctions.
+*/
+
+
+/*
+ * Prototypes of internals functions
+ */
+
+const char * 
+hypervGetPropType(const char * className, const char *attrName);
+
+int 
+hypervCreateXmlStruct(const char *methodName, const char *classURI, WsXmlDocH 
*xmlDocRoot, WsXmlNodeH *xmlNodeMethod);
+
+int 
+hypervAddEmbeddedParam(properties_t *prop_t, int nbProps, const char 
*paramName, const char *instanceName, const char *classURI, WsXmlNodeH 
*parentNode);
+
+int 
+hypervAddSimpleParam(const char *paramName, const char* value, const char 
*classURI, WsXmlNodeH *parentNode);
+
+int 
+hypervAddEprParam(const char *paramName, virBufferPtr query, const char *root, 
const char *classURI, WsXmlNodeH *parentNode, WsXmlDocH doc, hypervPrivate 
*priv);
+
+int 
+hypervInvokeMethodXml(hypervPrivate *priv, WsXmlDocH xmlDocRoot, const char 
*methodName, const char *ressourceURI, const char *selector);
+
+
+
+/* Create XML structure */
+int 
+hypervCreateXmlStruct(const char *methodName, const char *classURI, 
+                      WsXmlDocH *xmlDocRoot, WsXmlNodeH *xmlNodeMethod)
+{
+    
+    virBuffer method_buff = VIR_BUFFER_INITIALIZER;
+    char *methodNameInput = NULL;
+    
+    virBufferAsprintf(&method_buff, "%s_INPUT", methodName);
+    methodNameInput = virBufferContentAndReset(&method_buff);
+    
+    if (methodNameInput == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not create Xml Doc"));
+        goto cleanup;
+    }
+    
+    *xmlDocRoot = ws_xml_create_doc(NULL, methodNameInput);
+    if (*xmlDocRoot == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not create Xml Doc with given parameter 
xmlDocRoot"));
+        goto cleanup;
+    }
+    
+    *xmlNodeMethod = xml_parser_get_root(*xmlDocRoot);
+    if (*xmlNodeMethod == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not get xmlDocRoot root node"));
+        goto cleanup;
+    }
+    
+    //add namespace to xmlNodeMethode
+    ws_xml_set_ns(*xmlNodeMethod, classURI, "p");
+    
+    VIR_FREE(methodNameInput);
+    return 0;
+    
+ cleanup: 
+    
+    VIR_FREE(methodNameInput);
+    if (*xmlDocRoot != NULL) {
+        ws_xml_destroy_doc(*xmlDocRoot);
+        *xmlDocRoot = NULL;
+    }
+    return -1;
+}
+
+
+/* Get attribute type of a given attribute */
+const char * 
+hypervGetPropType(const char * className, const char *attrName)
+{
+    const char * res = NULL;
+    int i,y;
+    
+    i = 0;
+    while ( cimClasses[i].name[0] != '\0') {
+        if(strcmp(cimClasses[i].name,className ) == 0){
+            y = 0;
+            while ( cimClasses[i].cimTypesPtr[y].name[0] != '\0') {
+                if(strcmp(cimClasses[i].cimTypesPtr[y].name,attrName ) == 0){
+                    res = cimClasses[i].cimTypesPtr[y].type;
+                    break;
+                }
+                y++;
+            }
+            break;
+        }
+        i++;
+    }
+    return res;
+}
+
+
+/* Adding an Embedded Instance node to a parent node given in parameter */
+int 
+hypervAddEmbeddedParam(properties_t *prop_t, int nbProps, const char 
*paramName, 
+                       const char *instanceName, const char *classURI, 
WsXmlNodeH *parentNode)
+{
+    
+    int result = -1;
+    WsXmlNodeH xmlNodeInstance = NULL;
+    WsXmlNodeH xmlNodeProperty = NULL;
+    WsXmlNodeH xmlNodeParam = NULL;
+    WsXmlNodeH xmlNodeArray = NULL;
+    WsXmlDocH xmlDocTemp = NULL;
+    WsXmlDocH xmlDocCdata = NULL;
+    xmlBufferPtr xmlBufferNode = NULL;
+    const xmlChar *xmlCharCdataContent = NULL;
+    xmlNodePtr xmlNodeCdata = NULL;
+    char* type = NULL;  /* Must not be freed */
+    char* typeCopy = NULL;
+    bool isArray = false;
+    int len = 0;
+    int        i = 0;
+    
+    /* Add child to given parent node*/
+    xmlNodeParam = ws_xml_add_child(*parentNode, classURI, paramName, NULL);
+    if (xmlNodeParam == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not add child node to xmlNodeParam"));
+        goto cleanup;
+    }
+    
+    /* Create temp Xml doc */
+    /* INSTANCE node */
+    xmlDocTemp = ws_xml_create_doc(NULL, "INSTANCE");
+    if (xmlDocTemp == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not create temporary Xml doc"));
+        goto cleanup;
+    }
+    
+    xmlNodeInstance = xml_parser_get_root(xmlDocTemp);
+    if (xmlNodeInstance == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not get root of temporary Xml doc"));
+        goto cleanup;
+    }
+    
+    /* Add CLASSNAME node to INSTANCE node */
+    if (ws_xml_add_node_attr(xmlNodeInstance, NULL, "CLASSNAME", instanceName) 
== NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not add attribute to node "));
+        goto cleanup;
+    }
+    
+    /* Property nodes */
+    while (i < nbProps) {
+        
+        if (prop_t[i].name == NULL && prop_t[i].val == NULL ) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s",
+                           _("Could not get properties from array "));
+            goto cleanup;
+        }
+        
+        type = (char *) hypervGetPropType(instanceName,prop_t[i].name);
+        if (type == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s",
+                           _("Could not get properties from array "));
+            goto cleanup;
+        }
+        
+        /* Check if the attribute is an array or not */
+        if (strstr(type, "[]") != NULL) {
+            // The attribute is an array
+            isArray = true;
+            // Remove "[]" from the type; must be done on a copy
+            if (typeCopy != NULL) VIR_FREE(typeCopy);
+            typeCopy = strndup(type, strlen(type)-2);
+            type = typeCopy;
+        } else {
+            isArray = false;
+        }
+        
+        xmlNodeProperty = ws_xml_add_child(xmlNodeInstance, NULL,
+                                           
(isArray)?"PROPERTY.ARRAY":"PROPERTY", NULL);
+        if (xmlNodeProperty == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s",
+                           _("Could not add child to node"));
+            goto cleanup;
+        }
+        
+        if (ws_xml_add_node_attr(xmlNodeProperty, NULL, "NAME", 
prop_t[i].name) == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s",
+                           _("Could not add attribute to node"));
+            goto cleanup;
+        }
+        
+        if (ws_xml_add_node_attr(xmlNodeProperty, NULL, "TYPE", type) == NULL) 
{
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s",
+                           _("Could not add attribute to node"));
+            goto cleanup;
+        }
+        
+        /* Add the node VALUE.ARRAY if the attribute is an array */
+        if (isArray) {
+            xmlNodeArray = ws_xml_add_child(xmlNodeProperty, NULL, 
"VALUE.ARRAY", NULL);
+            if (xmlNodeArray == NULL) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s",
+                               _("Could not add child to node"));
+                goto cleanup;
+            }
+        }
+        
+        if (ws_xml_add_child((isArray)?xmlNodeArray:xmlNodeProperty, NULL, 
"VALUE",prop_t[i].val) == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s",
+                           _("Could not add child to node"));
+            goto cleanup;
+        }
+        
+        xmlNodeArray = NULL;
+        xmlNodeProperty = NULL;
+        i++;
+    }
+    
+    /* Create CDATA node */
+    xmlBufferNode = xmlBufferCreate();
+    if (xmlNodeDump(xmlBufferNode,(xmlDocPtr)xmlDocTemp->parserDoc , 
(xmlNodePtr) xmlNodeInstance, 0, 0) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not get root of temporary Xml doc"));
+        goto cleanup;
+    }
+    
+    len = xmlBufferLength(xmlBufferNode);
+    xmlCharCdataContent = xmlBufferContent(xmlBufferNode);
+    xmlNodeCdata = xmlNewCDataBlock ((xmlDocPtr)xmlDocCdata, 
xmlCharCdataContent, len );
+    if (xmlNodeCdata == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not get root of temporary Xml doc"));
+        goto cleanup;
+    }
+    /*adding CDATA node child to the root node of the main doc given*/
+    if (xmlAddChild((xmlNodePtr)xmlNodeParam, xmlNodeCdata ) == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not get root of temporary Xml doc"));
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup: 
+    ws_xml_destroy_doc(xmlDocCdata);
+    ws_xml_destroy_doc(xmlDocTemp);
+    if (typeCopy != NULL) VIR_FREE(typeCopy);
+    if (xmlBufferNode != NULL) xmlBufferFree(xmlBufferNode);
+    
+    return result;
+}
+
+
+/* Adding an Simple param node to a parent node given in parameter */
+int 
+hypervAddSimpleParam(const char *paramName, const char* value, 
+                     const char *classURI, WsXmlNodeH *parentNode)
+{
+    
+    int result = -1;
+    WsXmlNodeH xmlNodeParam = NULL;
+    
+    xmlNodeParam = ws_xml_add_child(*parentNode, classURI, paramName, value);
+    if (xmlNodeParam == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not create simple param"));
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup: 
+    return result;
+}
+
+
+/* Adding EPR param node to a parent node given in parameter */
+int 
+hypervAddEprParam(const char *paramName, virBufferPtr query, const char *root, 
+                  const char *classURI, WsXmlNodeH *parentNode, WsXmlDocH doc, 
hypervPrivate *priv)
+{
+    
+    int result = -1;
+    WsXmlNodeH xmlNodeParam = NULL;
+    WsXmlNodeH xmlNodTemp = NULL;
+    WsXmlNodeH xmlNodeAdr = NULL;
+    WsXmlNodeH xmlNodeRef = NULL;
+    WsXmlDocH xmlDocResponse = NULL;
+    WsXmlNsH ns = NULL;
+    client_opt_t *options = NULL;
+    filter_t *filter = NULL;
+    char *enumContext = NULL;
+    char *query_string;
+    xmlNodePtr xmlNodeAdrPtr = NULL;
+    xmlNodePtr xmlNodeRefPtr = NULL;
+    xmlDocPtr docPtr = (xmlDocPtr) doc->parserDoc;
+    
+    /* Protection against concurrent calls (the openwsman library is not 
thread-safe) */
+    pthread_mutex_lock(&priv->mutex);
+    
+    /* Request options and filter */
+    options = wsmc_options_init();
+
+    if (options == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not initialize options"));
+        goto cleanup;
+    }
+    
+#if DUMP_REQUEST
+    wsmc_set_action_option(options, FLAG_DUMP_REQUEST);
+#endif
+
+    wsmc_set_action_option(options, FLAG_ENUMERATION_ENUM_EPR);
+    
+    query_string = virBufferContentAndReset(query);
+    filter = filter_create_simple(WSM_WQL_FILTER_DIALECT,query_string);
+    if (filter == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not create filter"));
+        goto cleanup;
+    }
+    
+    /* Invoke enumerate action*/
+    xmlDocResponse = wsmc_action_enumerate(priv->client,root, options, filter);
+    
+    /* Check return value */
+    if (hyperyVerifyResponse(priv->client, xmlDocResponse, "enumeration") < 0) 
{
+        goto cleanup;
+    }
+    
+    /* Get enumerate conext*/
+    enumContext = wsmc_get_enum_context(xmlDocResponse);
+    
+    ws_xml_destroy_doc(xmlDocResponse);
+    
+    
+    /* Invoke pull action*/
+    xmlDocResponse = wsmc_action_pull(priv->client, classURI, options, filter, 
enumContext);
+    
+    /* Check return value */
+    if (hyperyVerifyResponse(priv->client, xmlDocResponse, "pull") < 0) {
+        goto cleanup;
+    }
+    
+    /* Extract EPR nodes childs */
+    xmlNodTemp = ws_xml_get_soap_body(xmlDocResponse);
+    if (xmlNodTemp == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not lookup SOAP body"));
+        goto cleanup;
+    }
+    
+    xmlNodTemp = ws_xml_get_child(xmlNodTemp, 0, XML_NS_ENUMERATION, 
WSENUM_PULL_RESP);
+    if (xmlNodTemp == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not lookup pull response"));
+        goto cleanup;
+    }
+    
+    xmlNodTemp = ws_xml_get_child(xmlNodTemp, 0, XML_NS_ENUMERATION, 
WSENUM_ITEMS);
+    if (xmlNodTemp == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not lookup pull response items"));
+        goto cleanup;
+    }
+    
+    xmlNodTemp = ws_xml_get_child(xmlNodTemp, 0, XML_NS_ADDRESSING, WSA_EPR);
+    if (xmlNodTemp == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not lookup pull response item EPR"));
+        goto cleanup;
+    }
+    
+    xmlNodeAdr = ws_xml_get_child(xmlNodTemp, 0, XML_NS_ADDRESSING, 
WSA_ADDRESS);
+    if (xmlNodeAdr == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not lookup pull response item ADDRESS"));
+        goto cleanup;
+    }
+    xmlNodeAdrPtr = xmlDocCopyNode((xmlNodePtr) xmlNodeAdr, docPtr, 1);
+    if (xmlNodeAdrPtr == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not copy item ADDRESS"));
+        goto cleanup;
+    }
+    
+    xmlNodeRef = ws_xml_get_child(xmlNodTemp, 0, XML_NS_ADDRESSING, 
WSA_REFERENCE_PARAMETERS);
+    if (xmlNodeRef == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not lookup pull response item REFERENCE 
PARAMETERS"));
+        goto cleanup;
+    }
+    xmlNodeRefPtr = xmlDocCopyNode((xmlNodePtr) xmlNodeRef, docPtr, 1);
+    if (xmlNodeRefPtr == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not copy item REFERENCE PARAMETERS"));
+        goto cleanup;
+    }
+    
+    /* Build XmlDoc with adding previous EPR nodes childs */
+    xmlNodeParam = ws_xml_add_child(*parentNode, classURI, paramName, NULL);
+    if (xmlNodeParam == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not add child node to xmlNodeParam"));
+        goto cleanup;
+    }
+    
+/*
+  The folowing line has been commented because of a memory corruption issue 
reported in the openwsman library
+  [ issue #43 - xml_parser_ns_add: alloc item size, not pointer size ]
+  xmlNodeSetLang((xmlNodePtr) xmlNodeParam, BAD_CAST "en-US");
+*/
+    ns = ws_xml_ns_add(xmlNodeParam, 
"http://schemas.xmlsoap.org/ws/2004/08/addressing";, "a");
+    if (ns == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not set namespace adressing to xmlNodeParam"));
+        goto cleanup;
+    }
+    
+    ns = NULL;
+    ns = ws_xml_ns_add(xmlNodeParam, 
"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd";, "w");
+    if (ns == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not set namespace wsman to xmlNodeParam"));
+        goto cleanup;
+    }
+    
+    if (xmlAddChild( (xmlNodePtr)*parentNode,(xmlNodePtr) xmlNodeParam) == 
NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not add child to xml parent node"));
+        goto cleanup;
+    }
+    
+    if (xmlAddChild( (xmlNodePtr)xmlNodeParam, xmlNodeAdrPtr) == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not add child to xml parent node"));
+        goto cleanup;
+    }
+    
+    if (xmlAddChild( (xmlNodePtr)xmlNodeParam, xmlNodeRefPtr) == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not add child to xml parent node"));
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup: 
+    if (options != NULL) {
+        wsmc_options_destroy(options);
+    }
+    if (filter != NULL) {
+        filter_destroy(filter);
+    }
+    ws_xml_destroy_doc(xmlDocResponse);
+    VIR_FREE(enumContext);
+    VIR_FREE(query_string);
     
+    /* Unlock the mutex */
+    pthread_mutex_unlock(&priv->mutex);
+    
+    return result;
+}
+
+
+/* Call wsmc_action_invoke() function of OpenWsman API with XML tree given in 
parameters*/
+int 
+hypervInvokeMethodXml(hypervPrivate *priv,WsXmlDocH xmlDocRoot,
+                      const char *methodName, const char *ressourceURI, const 
char *selector)
+{
+    
+    int result = -1;
+    int returnCode;
+    char *instanceID = NULL;
+    char *xpath_expr_string = NULL;
+    char *returnValue = NULL;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    virBuffer xpath_expr_buff = VIR_BUFFER_INITIALIZER;
+    client_opt_t *options = NULL;
+    WsXmlDocH response = NULL;
+    Msvm_ConcreteJob *concreteJob = NULL;
+    bool completed = false;
+    bool locked;
+    
+    /* Protection against concurrent calls (the openwsman library is not 
thread-safe) */
+    pthread_mutex_lock(&priv->mutex);
+    locked = true;
+    
+    options = wsmc_options_init();
+
+    if (options == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not initialize options"));
+        goto cleanup;
+    }
+    
+#if DUMP_REQUEST
+    wsmc_set_action_option(options, FLAG_DUMP_REQUEST);
+#endif
+    
+    wsmc_add_selectors_from_str(options, selector);
+    
+    /* Invoke action */
+    response = 
wsmc_action_invoke(priv->client,ressourceURI,options,methodName,xmlDocRoot);
+    
+    virBufferAsprintf(&xpath_expr_buff, 
"/s:Envelope/s:Body/p:%s_OUTPUT/p:ReturnValue", methodName);
+    xpath_expr_string = virBufferContentAndReset(&xpath_expr_buff);
+    
+    if (xpath_expr_string == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not lookup %s for %s invocation"),
+                       "ReturnValue", "RequestStateChange");
+        goto cleanup;
+    }
+    
+    /* Check return value */
+    returnValue = ws_xml_get_xpath_value(response, xpath_expr_string);
+    
+    VIR_FREE(xpath_expr_string);
+    xpath_expr_string = NULL;
+    
+    if (returnValue == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not lookup %s for %s invocation"),
+                       "ReturnValue", "RequestStateChange");
+        goto cleanup;
+    }
+    
+    if (virStrToLong_i(returnValue, NULL, 10, &returnCode) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse return code from '%s'"), 
returnValue);
+        goto cleanup;
+    }
+    
+    if (returnCode == CIM_RETURNCODE_TRANSITION_STARTED) {
+        
+        virBufferAsprintf(&xpath_expr_buff, 
"/s:Envelope/s:Body/p:%s_OUTPUT/p:Job/a:ReferenceParameters/w:SelectorSet/w:Selector[@Name='InstanceID']",
 methodName);
+        xpath_expr_string = virBufferContentAndReset(&xpath_expr_buff);
+        
+        if (xpath_expr_string == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not lookup %s for %s invocation"),
+                           "InstanceID", "RequestStateChange");
+            goto cleanup;
+        }
+        
+        /* Get concrete job object */
+        instanceID = ws_xml_get_xpath_value(response, xpath_expr_string);
+        
+        if (instanceID == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not lookup %s for %s invocation"),
+                           "InstanceID", "RequestStateChange");
+            goto cleanup;
+        }
+        
+        /* hypervGetMsvmConcreteJobList calls hypervEnumAndPull which also 
tries to lock priv->mutex */
+        pthread_mutex_unlock(&priv->mutex);
+        locked = false;
+        
+        /* FIXME: Poll every 100ms until the job completes or fails. There
+         *        seems to be no other way than polling. */
+        while (!completed) {
+            virBufferAddLit(&query, MSVM_CONCRETEJOB_WQL_SELECT);
+            virBufferAsprintf(&query, "where InstanceID = \"%s\"", instanceID);
+            
+            if (hypervGetMsvmConcreteJobList(priv, &query, &concreteJob) < 0) {
+                goto cleanup;
+            }
+            
+            if (concreteJob == NULL) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("Could not lookup %s for %s invocation"),
+                               "Msvm_ConcreteJob", "RequestStateChange");
+                goto cleanup;
+            }
+            
+            switch (concreteJob->data->JobState) {
+            case MSVM_CONCRETEJOB_JOBSTATE_NEW:
+            case MSVM_CONCRETEJOB_JOBSTATE_STARTING:
+            case MSVM_CONCRETEJOB_JOBSTATE_RUNNING:
+            case MSVM_CONCRETEJOB_JOBSTATE_SHUTTING_DOWN:
+                hypervFreeObject(priv, (hypervObject *)concreteJob);
+                concreteJob = NULL;
+                
+                usleep(100 * 1000);
+                continue;
+                
+            case MSVM_CONCRETEJOB_JOBSTATE_COMPLETED:
+                completed = true;
+                break;
+                
+            case MSVM_CONCRETEJOB_JOBSTATE_TERMINATED:
+            case MSVM_CONCRETEJOB_JOBSTATE_KILLED:
+            case MSVM_CONCRETEJOB_JOBSTATE_EXCEPTION:
+            case MSVM_CONCRETEJOB_JOBSTATE_SERVICE:
+                goto cleanup;
+                
+            default:
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("Concrete job for %s invocation is in unknown 
state"),
+                               "RequestStateChange");
+                goto cleanup;
+            }
+        }
+    } else if (returnCode != CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Invocation of %s returned an error: %s (%d)"),
+                       "RequestStateChange", 
hypervReturnCodeToString(returnCode),
+                       returnCode);
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup: 
+    if (options != NULL)
+        wsmc_options_destroy(options);
+    if (response != NULL)
+        ws_xml_destroy_doc(response);
+    VIR_FREE(returnValue);
+    VIR_FREE(instanceID);
+    VIR_FREE(xpath_expr_string);
+    hypervFreeObject(priv, (hypervObject *)concreteJob);
+    virBufferFreeAndReset(&query);
+    virBufferFreeAndReset(&xpath_expr_buff);
+    
+    /* Unlock the mutex if needed */
+    if (locked == true) pthread_mutex_unlock(&priv->mutex);
+    
+    return result;
+}
+
+
+/* Generate a XML tree with all param_t given in parameters */
+int 
+hypervInvokeMethod(hypervPrivate *priv, invokeXmlParam *param_t, int 
nbParameters, 
+                   const char* methodName, const char* providerURI, const char 
*selector)
+{
+    
+    int res = -1;
+    WsXmlDocH doc = NULL;
+    WsXmlNodeH methodNode = NULL;
+    eprParam *epr;
+    embeddedParam *embedded;
+    simpleParam *simple;
+    int i =0;
+    
+    if (hypervCreateXmlStruct(methodName,providerURI,&doc,&methodNode) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Could not create xml base structure"));
+        goto cleanup;
+    }
+    
+    while ( i < nbParameters) {
+        switch (param_t[i].type){
+        case EPR_PARAM:
+            epr = (eprParam*)param_t[i].param;
+            if (hypervAddEprParam(param_t[i].name, 
epr->query,epr->wmiProviderURI,providerURI,&methodNode,doc,priv) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s",
+                               _("Could not add EPR param to xml base 
structure "));
+                goto cleanup;
+            }
+            break;
+        case EMBEDDED_PARAM:
+            embedded = (embeddedParam*)param_t[i].param;
+            if 
(hypervAddEmbeddedParam(embedded->prop_t,embedded->nbProps,param_t[i].name,embedded->instanceName,providerURI,&methodNode)
 < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s",
+                               _("Could not add embedded instance param to xml 
base structure "));
+                goto cleanup;
+            }
+            break;
+        case SIMPLE_PARAM:  
+            simple = (simpleParam*)param_t[i].param;
+            if 
(hypervAddSimpleParam(param_t[i].name,simple->value,providerURI,&methodNode) < 
0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s",
+                               _("Could not add embedded instance param to xml 
base structure "));
+                goto cleanup;
+            }
+            break;
+        }
+        i++;
+    }
+    
+    if (hypervInvokeMethodXml(priv,doc,methodName,providerURI,selector) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s",
+                       _("Error during invocation action"));
+        goto cleanup;
+    }
+    
+    res = 0;
+    
+ cleanup:
+    if (doc != NULL)
+        ws_xml_destroy_doc(doc);
+    
+    return res;
+}
 
 
 int
@@ -128,8 +864,13 @@ hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, 
const char *root,
         return -1;
     }
     
-    if (virBufferCheckError(query) < 0)
+    if (virBufferError(query)) {
+        virReportOOMError();
         return -1;
+    }
+    
+    /* Protection against concurrent calls (the openwsman library is not 
thread-safe) */
+    pthread_mutex_lock(&priv->mutex);
     
     serializerContext = wsmc_get_serialization_context(priv->client);
     
@@ -141,6 +882,10 @@ hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, 
const char *root,
         goto cleanup;
     }
     
+#if DUMP_REQUEST
+    wsmc_set_action_option(options, FLAG_DUMP_REQUEST);
+#endif
+
     query_string = virBufferContentAndReset(query);
     filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string);
     
@@ -259,6 +1004,9 @@ hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, 
const char *root,
     VIR_FREE(enumContext);
     hypervFreeObject(priv, head);
     
+    /* Unlock the mutex */
+    pthread_mutex_unlock(&priv->mutex);
+    
     return result;
 }
 
@@ -403,9 +1151,14 @@ 
hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
     virBuffer query = VIR_BUFFER_INITIALIZER;
     Msvm_ConcreteJob *concreteJob = NULL;
     bool completed = false;
+    bool locked;
     
     virUUIDFormat(domain->uuid, uuid_string);
     
+    /* Protection against concurrent calls (the openwsman library is not 
thread-safe) */
+    pthread_mutex_lock(&priv->mutex);
+    locked = true;
+    
     if (virAsprintf(&selector, "Name=%s&CreationClassName=Msvm_ComputerSystem",
                     uuid_string) < 0 ||
         virAsprintf(&properties, "RequestedState=%d", requestedState) < 0)
@@ -419,6 +1172,10 @@ 
hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
         goto cleanup;
     }
     
+#if DUMP_REQUEST
+    wsmc_set_action_option(options, FLAG_DUMP_REQUEST);
+#endif
+    
     wsmc_add_selectors_from_str(options, selector);
     wsmc_add_prop_from_str(options, properties);
     
@@ -457,6 +1214,10 @@ 
hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
             goto cleanup;
         }
         
+        /* hypervGetMsvmConcreteJobList calls hypervEnumAndPull which also 
tries to lock priv->mutex */
+        pthread_mutex_unlock(&priv->mutex);
+        locked = false;
+        
         /* FIXME: Poll every 100ms until the job completes or fails. There
          *        seems to be no other way than polling. */
         while (!completed) {
@@ -527,12 +1288,15 @@ 
hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
     VIR_FREE(instanceID);
     hypervFreeObject(priv, (hypervObject *)concreteJob);
     
+    /* Unlock the mutex if needed */
+    if (locked == true) pthread_mutex_unlock(&priv->mutex);
+    
     return result;
 }
 
 int
 hypervMsvmComputerSystemEnabledStateToDomainState
-  (Msvm_ComputerSystem *computerSystem)
+(Msvm_ComputerSystem *computerSystem)
 {
     switch (computerSystem->data->EnabledState) {
     case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN:
@@ -676,5 +1440,31 @@ hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
 }
 
 
+int
+hypervMsvmVirtualSwitchToNetwork(virConnectPtr conn,
+                                 Msvm_VirtualSwitch *virtualSwitch, 
virNetworkPtr *network)
+{
+    unsigned char uuid[VIR_UUID_BUFLEN];
+    
+    if (network == NULL || *network != NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+        return -1;
+    }
+    
+    if (virUUIDParse(virtualSwitch->data->Name, uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse UUID from string '%s'"),
+                       virtualSwitch->data->Name);
+        return -1;
+    }
+    
+    *network = virGetNetwork(conn, virtualSwitch->data->ElementName, uuid);
+    
+    if (*network == NULL) {
+        return -1;
+    }
+    
+    return 0;
+}
 
 #include "hyperv_wmi.generated.c"
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
index 5fbbbac..f4ac319 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -24,11 +24,61 @@
 #ifndef __HYPERV_WMI_H__
 # define __HYPERV_WMI_H__
 
+#define ROOT_CIMV2 \
+    "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/*";
+
+#define ROOT_VIRTUALIZATION \
+    "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/*";
+
 # include "virbuffer.h"
 # include "hyperv_private.h"
 # include "hyperv_wmi_classes.h"
 # include "openwsman.h"
 
+/*
+ *  Type of parameters for hypervInvokeMethod function
+ */
+
+enum _PARAM_Type {
+    EPR_PARAM = 0,
+    SIMPLE_PARAM = 1,
+    EMBEDDED_PARAM = 2,
+};
+
+typedef struct _invokeXmlParam invokeXmlParam;
+struct _invokeXmlParam{
+        const char *name;
+        int type;
+       void *param;
+};
+
+typedef struct _eprParam eprParam;
+struct _eprParam{
+        virBufferPtr query;
+       const char *wmiProviderURI;
+};
+
+typedef struct _simpleParam simpleParam;
+struct _simpleParam{
+       const char *value;
+};
+
+typedef struct _properties_t properties_t;
+struct _properties_t{
+        const char *name;
+        const char *val;
+};
+
+typedef struct _embeddedParam embeddedParam;
+struct _embeddedParam{
+       const char *instanceName;
+       properties_t *prop_t;
+       int nbProps;
+};
+
+
+int
+hypervInvokeMethod(hypervPrivate *priv, invokeXmlParam *parameters, int 
nbParameters,const char* methodName, const char* providerURI, const char 
*selector);
 
 
 typedef struct _hypervObject hypervObject;
@@ -53,7 +103,7 @@ int hypervEnumAndPull(hypervPrivate *priv, virBufferPtr 
query,
                       const char *resourceUri, const char *className,
                       hypervObject **list);
 
-void hypervFreeObject(hypervPrivate *priv, hypervObject *object);
+void hypervFreeObject(hypervPrivate *priv ATTRIBUTE_UNUSED, hypervObject 
*object);
 
 
 
@@ -114,6 +164,13 @@ int hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
                                        Msvm_ComputerSystem **computerSystem);
 
 
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_VirtualSwitch
+ */
+
+int hypervMsvmVirtualSwitchToNetwork(virConnectPtr conn,
+               Msvm_VirtualSwitch *virtualSwitch, virNetworkPtr *network);
+
 
 # include "hyperv_wmi.generated.h"
 
diff --git a/src/hyperv/hyperv_wmi_generator.input 
b/src/hyperv/hyperv_wmi_generator.input
index 97f9dff..7f828d3 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -12,8 +12,8 @@
 #     ...
 # end
 #
-# Allowed values for <type> are: boolean, string, datetime, int8, int16,
-# int32, int64, uint8, uint16, uint32 and uint64
+# Allowed values for <type> are: boolean, string, datetime, sint8, sint16,
+# sint32, sint64, uint8, uint16, uint32 and uint64
 #
 # The property <name> can be followed by [] to define a dynamic array.
 #
@@ -72,8 +72,8 @@ class Msvm_ConcreteJob
     datetime ElapsedTime
     uint32   JobRunTimes
     uint8    RunMonth
-    int8     RunDay
-    int8     RunDayOfWeek
+    sint8    RunDay
+    sint8    RunDayOfWeek
     datetime RunStartInterval
     uint16   LocalOrUtcTime
     datetime UntilTime
@@ -196,7 +196,7 @@ class Win32_ComputerSystem
     string   Caption
     uint16   ChassisBootupState
     string   CreationClassName
-    int16    CurrentTimeZone
+    sint16   CurrentTimeZone
     boolean  DaylightInEffect
     string   Description
     string   DNSHostName
@@ -219,7 +219,7 @@ class Win32_ComputerSystem
     uint8    OEMLogoBitmap[]
     string   OEMStringArray[]
     boolean  PartOfDomain
-    int64    PauseAfterReset
+    sint64   PauseAfterReset
     uint16   PCSystemType
     uint16   PowerManagementCapabilities[]
     boolean  PowerManagementSupported
@@ -229,8 +229,8 @@ class Win32_ComputerSystem
     string   PrimaryOwnerContact
     string   PrimaryOwnerName
     uint16   ResetCapability
-    int16    ResetCount
-    int16    ResetLimit
+    sint16   ResetCount
+    sint16   ResetLimit
     string   Roles[]
     string   Status
     string   SupportContactDescription[]
@@ -296,3 +296,517 @@ class Win32_Processor
     string   Version
     uint32   VoltageCaps
 end
+
+
+class CIM_DataFile 
+       uint32   AccessMask
+       boolean  Archive
+       string   Caption
+       boolean  Compressed
+       string   CompressionMethod
+       string   CreationClassName
+       datetime CreationDate
+       string   CSCreationClassName
+       string   CSName
+       string   Description
+       string   Drive
+       string   EightDotThreeFileName
+       boolean  Encrypted
+       string   EncryptionMethod
+       string   Extension
+       string   FileName
+       uint64   FileSize
+       string   FileType
+       string   FSCreationClassName
+       string   FSName
+       boolean  Hidden
+       datetime InstallDate
+       uint64   InUseCount
+       datetime LastAccessed
+       datetime LastModified
+       string   Manufacturer
+       string   Name
+       string   Path
+       boolean  Readable
+       string   Status
+       boolean  System
+       string   Version
+       boolean  Writeable
+end
+
+
+class Win32_ComputerSystemProduct
+       string  Caption
+       string  Description
+       string  IdentifyingNumber
+       string  Name
+       string  SKUNumber
+       string  UUID
+       string  Vendor
+       string  Version
+end
+
+class Msvm_VirtualSystemManagementService
+       string   Caption 
+       string   Description 
+       string   ElementName
+       datetime InstallDate
+       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   Name
+       string   PrimaryOwnerName
+       string   PrimaryOwnerContact
+       string   StartMode
+       boolean  Started
+end
+
+class Msvm_VirtualSystemGlobalSettingData 
+       string   Caption 
+       string   Description
+       string   ElementName
+       string   InstanceID
+       string   SystemName
+       uint16   SettingType
+       uint16   VirtualSystemType
+       string   OtherVirtualSystemType
+       boolean  AutoActivate
+       datetime CreationTime
+       string   ExternalDataRoot
+       string   SnapshotDataRoot
+       uint16   AutomaticStartupAction
+       datetime AutomaticStartupActionDelay
+       uint16   AutomaticShutdownAction
+       uint16   AutomaticRecoveryAction
+       string   AdditionalRecoveryInformation
+       string   ScopeOfResidence
+       uint32   DebugChannelId
+       boolean  AllowFullSCSICommandSet
+       string   Version
+end
+
+class Msvm_ResourceAllocationSettingData
+       string  Caption
+       string  Description
+       string  InstanceID
+       string  ElementName
+       uint16  ResourceType
+       string  OtherResourceType
+       string  ResourceSubType
+       string  PoolID
+       uint16  ConsumerVisibility
+       string  HostResource[]
+       string  AllocationUnits
+       uint64  VirtualQuantity
+       uint64  Reservation
+       uint64  Limit
+       uint32  Weight
+       boolean AutomaticAllocation
+       boolean AutomaticDeallocation
+       string  Parent
+       string  Connection[]
+       string  Address
+       uint16  MappingBehavior
+       string  VirtualSystemIdentifiers[]
+end
+
+class Msvm_AllocationCapabilities
+       string Caption
+       string Description
+       string ElementName
+       string InstanceID
+       string OtherResourceType
+       uint16 RequestTypesSupported
+       string ResourceSubType
+       uint16 ResourceType
+       uint16 SharingMode
+       uint16 SupportedAddStates[]
+       uint16 SupportedRemoveStates[]
+end
+
+class Msvm_VirtualSwitch
+       string Caption
+       string Description
+       string ElementName
+       datetime InstallDate
+       uint16 OperationalStatus[]
+       string StatusDescriptions[]
+       string Status
+       uint16 HealthState
+       uint16 EnabledState
+       string OtherEnabledState
+       uint16 RequestedState
+       uint16 EnabledDefault
+       datetime TimeOfLastStateChange
+       string CreationClassName
+       string Name
+       string PrimaryOwnerContact
+       string PrimaryOwnerName
+       string Roles[]
+       string NameFormat
+       string OtherIdentifyingInfo[]
+       string IdentifyingDescriptions[]
+       uint16 Dedicated[]
+       string OtherDedicatedDescriptions[]
+       uint16 ResetCapability
+       uint16 PowerManagementCapabilities[]
+       string ScopeOfResidence
+       uint32 NumLearnableAddresses
+       uint32 MaxVMQOffloads
+       uint32 MaxChimneyOffloads
+end
+
+class Msvm_SwitchPort
+       string Caption
+       string ElementName
+       datetime InstallDate
+       string StatusDescriptions[]
+       string Status
+       uint16 HealthState
+       string OtherEnabledState
+       uint16 RequestedState
+       uint16 EnabledDefault
+       string SystemCreationClassName
+       string SystemName
+       string CreationClassName
+       string Description
+       uint16 OperationalStatus[]
+       uint16 EnabledState
+       datetime TimeOfLastStateChange
+       string Name
+       string NameFormat
+       uint16 ProtocolType
+       uint16 ProtocolIFType
+       string OtherTypeDescription
+       boolean BroadcastResetSupported
+       uint16 PortNumber
+       string ScopeOfResidence
+       uint32 VMQOffloadWeight
+       uint32 ChimneyOffloadWeight
+       uint32 VMQOffloadUsage
+       uint32 ChimneyOffloadUsage
+       uint32 VMQOffloadLimit
+       uint32 ChimneyOffloadLimit
+       boolean AllowMacSpoofing
+end
+
+class Msvm_SyntheticEthernetPortSettingData
+       string Caption
+       string Description
+       string InstanceID
+       string ElementName
+       uint16 ResourceType
+       string OtherResourceType
+       string ResourceSubType
+       string PoolID
+       uint16 ConsumerVisibility
+       string HostResource[]
+       string AllocationUnits
+       uint64 VirtualQuantity
+       uint64 Reservation
+       uint64 Limit
+       uint32 Weight
+       boolean AutomaticAllocation
+       boolean AutomaticDeallocation
+       string Parent
+       string Connection[]
+       string Address
+       uint16 MappingBehavior
+       string VirtualSystemIdentifiers[]
+       boolean StaticMacAddress
+end
+
+class Msvm_VirtualSwitchManagementService
+       string Caption
+       string Description
+       string ElementName
+       datetime InstallDate
+       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 Name
+       string PrimaryOwnerName
+       string PrimaryOwnerContact
+       string StartMode
+       boolean Started
+end
+
+class Win32_OperatingSystem
+       string   BootDevice
+       string   BuildNumber
+       string   BuildType
+       string   Caption
+       string   CodeSet
+       string   CountryCode
+       string   CreationClassName
+       string   CSCreationClassName
+       string   CSDVersion
+       string   CSName
+       sint16   CurrentTimeZone
+       boolean  DataExecutionPrevention_Available
+       boolean  DataExecutionPrevention_32BitApplications
+       boolean  DataExecutionPrevention_Drivers
+       uint8    DataExecutionPrevention_SupportPolicy
+       boolean  Debug
+       string   Description
+       boolean  Distributed
+       uint32   EncryptionLevel
+       uint8    ForegroundApplicationBoost
+       uint64   FreePhysicalMemory
+       uint64   FreeSpaceInPagingFiles
+       uint64   FreeVirtualMemory
+       datetime InstallDate
+       uint32   LargeSystemCache
+       datetime LastBootUpTime
+       datetime LocalDateTime
+       string   Locale
+       string   Manufacturer
+       uint32   MaxNumberOfProcesses
+       uint64   MaxProcessMemorySize
+       string   MUILanguages[]
+       string   Name
+       uint32   NumberOfLicensedUsers
+       uint32   NumberOfProcesses
+       uint32   NumberOfUsers
+       uint32   OperatingSystemSKU
+       string   Organization
+       string   OSArchitecture
+       uint32   OSLanguage
+       uint32   OSProductSuite
+       uint16   OSType
+       string   OtherTypeDescription
+       boolean  PAEEnabled
+       string   PlusProductID
+       string   PlusVersionNumber
+       boolean  PortableOperatingSystem
+       boolean  Primary
+       uint32   ProductType
+       string   RegisteredUser
+       string   SerialNumber
+       uint16   ServicePackMajorVersion
+       uint16   ServicePackMinorVersion
+       uint64   SizeStoredInPagingFiles
+       string   Status
+       uint32   SuiteMask
+       string   SystemDevice
+       string   SystemDirectory
+       string   SystemDrive
+       uint64   TotalSwapSpaceSize
+       uint64   TotalVirtualMemorySize
+       uint64   TotalVisibleMemorySize
+       string   Version
+       string   WindowsDirectory
+end
+
+class Win32_PerfFormattedData_HvStats_HyperVHypervisorVirtualProcessor
+       uint64   AddressDomainFlushesPersec
+       uint64   AddressSpaceEvictionsPersec
+       uint64   AddressSpaceFlushesPersec
+       uint64   AddressSpaceSwitchesPersec
+       uint64   APICEOIAccessesPersec
+       uint64   APICIPIsSentPersec
+       uint64   APICMMIOAccessesPersec
+       uint64   APICSelfIPIsSentPersec
+       uint64   APICTPRAccessesPersec
+       string   Caption
+       uint64   ControlRegisterAccessesCost
+       uint64   ControlRegisterAccessesPersec
+       uint64   CPUIDInstructionsCost
+       uint64   CPUIDInstructionsPersec
+       uint64   CPUWaitTimePerDispatch
+       uint64   DebugRegisterAccessesCost
+       uint64   DebugRegisterAccessesPersec
+       string   Description
+       uint64   EmulatedInstructionsCost
+       uint64   EmulatedInstructionsPersec
+       uint64   ExternalInterruptsCost
+       uint64   ExternalInterruptsPersec
+       uint64   Frequency_Object
+       uint64   Frequency_PerfTime
+       uint64   Frequency_Sys100NS
+       uint64   GlobalGVARangeFlushesPersec
+       uint64   GPASpaceHypercallsPersec
+       uint64   GuestPageTableMapsPersec
+       uint64   HardwareInterruptsPersec
+       uint64   HLTInstructionsCost
+       uint64   HLTInstructionsPersec
+       uint64   HypercallsCost
+       uint64   HypercallsPersec
+       uint64   IOInstructionsCost
+       uint64   IOInstructionsPersec
+       uint64   IOInterceptMessagesPersec
+       uint64   LargePageTLBFillsPersec
+       uint64   LocalFlushedGVARangesPersec
+       uint64   LogicalProcessorDispatchesPersec
+       uint64   LogicalProcessorHypercallsPersec
+       uint64   LogicalProcessorMigrationsPersec
+       uint64   LongSpinWaitHypercallsPersec
+       uint64   MemoryInterceptMessagesPersec
+       uint64   MSRAccessesCost
+       uint64   MSRAccessesPersec
+       uint64   MWAITInstructionsCost
+       uint64   MWAITInstructionsPersec
+       string   Name
+       uint64   NestedPageFaultInterceptsCost
+       uint64   NestedPageFaultInterceptsPersec
+       uint64   OtherHypercallsPersec
+       uint64   OtherInterceptsCost
+       uint64   OtherInterceptsPersec
+       uint64   OtherMessagesPersec
+       uint64   PageFaultInterceptsCost
+       uint64   PageFaultInterceptsPersec
+       uint64   PageInvalidationsCost
+       uint64   PageInvalidationsPersec
+       uint64   PageTableAllocationsPersec
+       uint64   PageTableEvictionsPersec
+       uint64   PageTableReclamationsPersec
+       uint64   PageTableResetsPersec
+       uint64   PageTableValidationsPersec
+       uint64   PageTableWriteInterceptsPersec
+       uint64   PendingInterruptsCost
+       uint64   PendingInterruptsPersec
+       uint64   PercentGuestRunTime
+       uint64   PercentHypervisorRunTime
+       uint64   PercentRemoteRunTime
+       uint64   PercentTotalRunTime
+       uint64   ReflectedGuestPageFaultsPersec
+       uint64   SmallPageTLBFillsPersec
+       uint64   SyntheticInterruptHypercallsPersec
+       uint64   SyntheticInterruptsPersec
+       uint64   Timestamp_Object
+       uint64   Timestamp_PerfTime
+       uint64   Timestamp_Sys100NS
+       uint64   TotalInterceptsCost
+       uint64   TotalInterceptsPersec
+       uint64   TotalMessagesPersec
+       uint64   VirtualInterruptHypercallsPersec
+       uint64   VirtualInterruptsPersec
+       uint64   VirtualMMUHypercallsPersec
+       uint64   VirtualProcessorHypercallsPersec
+end
+
+class Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
+       uint64   AddressDomainFlushesPersec
+       uint64   AddressSpaceEvictionsPersec
+       uint64   AddressSpaceFlushesPersec
+       uint64   AddressSpaceSwitchesPersec
+       uint64   APICEOIAccessesPersec
+       uint64   APICIPIsSentPersec
+       uint64   APICMMIOAccessesPersec
+       uint64   APICSelfIPIsSentPersec
+       uint64   APICTPRAccessesPersec
+       string   Caption
+       uint64   ControlRegisterAccessesCost
+       uint64   ControlRegisterAccessesCost_Base
+       uint64   ControlRegisterAccessesPersec
+       uint64   CPUIDInstructionsCost
+       uint64   CPUIDInstructionsCost_Base
+       uint64   CPUIDInstructionsPersec
+       uint64   CPUWaitTimePerDispatch
+       uint64   CPUWaitTimePerDispatch_Base
+       uint64   DebugRegisterAccessesCost
+       uint64   DebugRegisterAccessesCost_Base
+       uint64   DebugRegisterAccessesPersec
+       string   Description
+       uint64   EmulatedInstructionsCost
+       uint64   EmulatedInstructionsCost_Base
+       uint64   EmulatedInstructionsPersec
+       uint64   ExternalInterruptsCost
+       uint64   ExternalInterruptsCost_Base
+       uint64   ExternalInterruptsPersec
+       uint64   Frequency_Object
+       uint64   Frequency_PerfTime
+       uint64   Frequency_Sys100NS
+       uint64   GlobalGVARangeFlushesPersec
+       uint64   GPASpaceHypercallsPersec
+       uint64   GuestPageTableMapsPersec
+       uint64   HardwareInterruptsPersec
+       uint64   HLTInstructionsCost
+       uint64   HLTInstructionsCost_Base
+       uint64   HLTInstructionsPersec
+       uint64   HypercallsCost
+       uint64   HypercallsCost_Base
+       uint64   HypercallsPersec
+       uint64   IOInstructionsCost
+       uint64   IOInstructionsCost_Base
+       uint64   IOInstructionsPersec
+       uint64   IOInterceptMessagesPersec
+       uint64   LargePageTLBFillsPersec
+       uint64   LocalFlushedGVARangesPersec
+       uint64   LogicalProcessorDispatchesPersec
+       uint64   LogicalProcessorHypercallsPersec
+       uint64   LogicalProcessorMigrationsPersec
+       uint64   LongSpinWaitHypercallsPersec
+       uint64   MemoryInterceptMessagesPersec
+       uint64   MSRAccessesCost
+       uint64   MSRAccessesCost_Base
+       uint64   MSRAccessesPersec
+       uint64   MWAITInstructionsCost
+       uint64   MWAITInstructionsCost_Base
+       uint64   MWAITInstructionsPersec
+       string   Name
+       uint64   NestedPageFaultInterceptsCost
+       uint64   NestedPageFaultInterceptsCost_Base
+       uint64   NestedPageFaultInterceptsPersec
+       uint64   OtherHypercallsPersec
+       uint64   OtherInterceptsCost
+       uint64   OtherInterceptsCost_Base
+       uint64   OtherInterceptsPersec
+       uint64   OtherMessagesPersec
+       uint64   PageFaultInterceptsCost
+       uint64   PageFaultInterceptsCost_Base
+       uint64   PageFaultInterceptsPersec
+       uint64   PageInvalidationsCost
+       uint64   PageInvalidationsCost_Base
+       uint64   PageInvalidationsPersec
+       uint64   PageTableAllocationsPersec
+       uint64   PageTableEvictionsPersec
+       uint64   PageTableReclamationsPersec
+       uint64   PageTableResetsPersec
+       uint64   PageTableValidationsPersec
+       uint64   PageTableWriteInterceptsPersec
+       uint64   PendingInterruptsCost
+       uint64   PendingInterruptsCost_Base
+       uint64   PendingInterruptsPersec
+       uint64   PercentGuestRunTime
+       uint64   PercentGuestRunTime_Base
+       uint64   PercentHypervisorRunTime
+       uint64   PercentHypervisorRunTime_Base
+       uint64   PercentRemoteRunTime
+       uint64   PercentRemoteRunTime_Base
+       uint64   PercentTotalRunTime
+       uint64   PercentTotalRunTime_Base
+       uint64   ReflectedGuestPageFaultsPersec
+       uint64   SmallPageTLBFillsPersec
+       uint64   SyntheticInterruptHypercallsPersec
+       uint64   SyntheticInterruptsPersec
+       uint64   Timestamp_Object
+       uint64   Timestamp_PerfTime
+       uint64   Timestamp_Sys100NS
+       uint64   TotalInterceptsCost
+       uint64   TotalInterceptsCost_Base
+       uint64   TotalInterceptsPersec
+       uint64   TotalMessagesPersec
+       uint64   VirtualInterruptHypercallsPersec
+       uint64   VirtualInterruptsPersec
+       uint64   VirtualMMUHypercallsPersec
+       uint64   VirtualProcessorHypercallsPersec
+end
\ No newline at end of file
diff --git a/src/hyperv/hyperv_wmi_generator.py 
b/src/hyperv/hyperv_wmi_generator.py
index f767d54..a785df2 100755
--- a/src/hyperv/hyperv_wmi_generator.py
+++ b/src/hyperv/hyperv_wmi_generator.py
@@ -68,7 +68,7 @@ class Class:
         header += "\n"
         header += "#define %s_RESOURCE_URI \\\n" % name_upper
 
-        if self.name.startswith("Win32_"):
+        if self.name.startswith("Win32_") or 
self.name.startswith("CIM_DataFile"):
             header += "    
\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/%s\"\n"; % self.name
         else:
             header += "    
\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/%s\"\n"; % 
self.name
@@ -113,7 +113,7 @@ class Class:
                   % (self.name.replace("_", ""), self.name)
         source += "{\n"
 
-        if self.name.startswith("Win32_"):
+        if self.name.startswith("Win32_") or 
self.name.startswith("CIM_DataFile"):
             source += "    return hypervEnumAndPull(priv, query, ROOT_CIMV2,\n"
         else:
             source += "    return hypervEnumAndPull(priv, query, 
ROOT_VIRTUALIZATION,\n"
@@ -149,15 +149,32 @@ class Class:
 
         return source
 
+    def generate_tab_classes(self):
+        tab_class = "  {(\"%s" % self.name
+        tab_class += "\"),cimTypes_%s" % self.name
+        tab_class += "}"
+
+        return tab_class
+
+    def generate_tabs_types(self):
+        tab_types = "CimTypes cimTypes_%s[] = {\n" % self.name
+        for property in self.properties[:-1]:
+            tab_types += property.generate_type_tab()
+            tab_types += ",\n"
+        property = self.properties[len(self.properties)-1]
+        tab_types += property.generate_type_tab()
+        tab_types += ",\n\t{(\"\\0\"),(\"\\0\")}\n};\n"
+
+        return tab_types
                
 class Property:
     typemap = {"boolean"  : "BOOL",
                "string"   : "STR",
                "datetime" : "STR",
-               "int8"     : "INT8",
-               "int16"    : "INT16",
-               "int32"    : "INT32",
-               "int64"    : "INT64",
+               "sint8"    : "INT8",
+               "sint16"   : "INT16",
+               "sint32"   : "INT32",
+               "sint64"   : "INT64",
                "uint8"    : "UINT8",
                "uint16"   : "UINT16",
                "uint32"   : "UINT32",
@@ -189,7 +206,14 @@ class Property:
             return "    SER_NS_%s(%s_RESOURCE_URI, \"%s\", 1),\n" \
                    % (Property.typemap[self.type], class_name.upper(), 
self.name)
 
-
+    def generate_type_tab(self):
+        tab_class = "  {(\"%s" % self.name
+        tab_class += "\"),(\"%s" % self.type
+        #If the attribute is an array, "[]" is added at the end of the type
+        if self.is_array:
+            tab_class += "[]"
+        tab_class += "\")}"
+        return tab_class
 
 def open_and_print(filename):
     if filename.startswith("./"):
@@ -238,7 +262,19 @@ def parse_class(block):
 
     return Class(name=name, properties=properties)
 
+def print_type_header():
+    header_types = "struct cimTypes{\n"
+    header_types += "  const char *name;\n"    
+    header_types += "  const char *type;\n"    
+    header_types += "};\n"     
+    header_types += "typedef struct cimTypes CimTypes;\n\n"    
+    header_types += "struct cimClasses{\n"     
+    header_types += "  const char *name;\n"
+    header_types += "  CimTypes *cimTypesPtr;\n"       
+    header_types += "};\n"     
+    header_types += "typedef struct cimClasses CimClasses;\n\n"
 
+    return header_types
 
 def main():
     if "srcdir" in os.environ:
@@ -254,6 +290,8 @@ def main():
     classes_header = open_and_print(os.path.join(output_dirname, 
"hyperv_wmi_classes.generated.h"))
     classes_source = open_and_print(os.path.join(output_dirname, 
"hyperv_wmi_classes.generated.c"))
        
+    classes_test_header = open_and_print(os.path.join(output_dirname, 
"hyperv_wmi_classes_attr.generated.h"))
+
     # parse input file
     number = 0
     classes_by_name = {}
@@ -295,6 +333,9 @@ def main():
     classes_header.write(notice)
     classes_source.write(notice)
        
+    classes_test_header.write(notice)
+    classes_test_header.write(print_type_header())     
+
     names = classes_by_name.keys()
     names.sort()
 
@@ -305,7 +346,15 @@ def main():
         classes_header.write(classes_by_name[name].generate_classes_header())
         classes_source.write(classes_by_name[name].generate_classes_source())
        
-
+    for name in names:
+        classes_test_header.write(classes_by_name[name].generate_tabs_types())
+    classes_test_header.write("CimClasses cimClasses[] = {\n")
+    for name in names[:-1]:
+        classes_test_header.write(classes_by_name[name].generate_tab_classes())
+        classes_test_header.write(",\n")
+    last_name = names[len(names)-1]
+    
classes_test_header.write(classes_by_name[last_name].generate_tab_classes())
+    classes_test_header.write(",\n\t{(\"\\0\"),NULL}\n};")
 
 if __name__ == "__main__":
     main()
diff --git a/src/hyperv/openwsman.h b/src/hyperv/openwsman.h
index f66ed86..49b3e39 100644
--- a/src/hyperv/openwsman.h
+++ b/src/hyperv/openwsman.h
@@ -44,3 +44,7 @@
 # endif
 
 #endif /* __OPENWSMAN_H__ */
+
+/*wsman-xml.h*/
+WsXmlDocH ws_xml_create_doc( const char *rootNsUri, const char *rootName);
+WsXmlNodeH xml_parser_get_root(WsXmlDocH doc);

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to