[libvirt] [PATCH] New features implemented in hyperv libvirt driver (Bull)

Yves Vinter yves.vinter at bull.net
Fri Sep 12 16:36:51 UTC 2014


Authors: Simon Rastello (Bull), Adrien Kantcheff (Bull), Yves Vinter (Bull)
 
Summary of new added features by modules:

hyperv_driver.c
 - hypervDomainDefineXML
 - hypervDomainCreateXML
 - hypervDomainUndefine
 - hypervDomainUndefineFlags
 - hypervDomainShutdown
 - hypervDomainShutdownFlags
 - hypervDomainGetVcpus
 - hypervDomainGetVcpusFlags
 - hypervConnectGetMaxVcpus
 - hypervDomainGetMaxVcpus
 - hypervDomainSetVcpus
 - hypervDomainSetVcpusFlags
 - hypervDomainSetMemory
 - hypervDomainSetMemoryFlags
 - hypervDomainSetMaxMemory
 - hypervNodeGetFreeMemory
 - hypervDomainAttachDevice
 - hypervDomainAttachDeviceFlags
 - hypervDomainGetSchedulerParameters
 - hypervDomainGetSchedulerParametersFlags
 - hypervDomainGetSchedulerType
 - hypervConnectGetCapabilities
 - hypervConnectGetVersion
 - hypervDomainSetAutostart
 - hypervDomainGetAutostart
 
hyperv_network.c
 - hypervConnectNumOfNetworks
 - hypervConnectListNetworks
 - hypervConnectNumOfDefinedNetworks
 - hypervConnectListDefinedNetworks
 - hypervNetworkLookupByName
 - hypervNetworkGetXMLDesc
 
hyperv_private.h
 - Add mutex to protect against concurrent calls
   (the openwsman library being not thread-safe,
    as reported in issue #10 Simultaneous WsMan queries)
 - Add virDomainXMLOptionPtr to parse Domain XML
 
hyperv_wmi.h
 - Structures for passing complex arguments: 
      objects, EPR (end point references) and embedded instances
 
hyperv_wmi.c
 - Methods to invoke WMI methods with complex arguments
 
hyperv_wmi_generator.input
 - 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
 - Add CIM_DataFile class header to be generated
 - Add tab classes and types to be generated
 - Add a function to print header types
 
openwsman.h
 - Add ws_xml_create_doc function prototype
 - Add xml_parser_get_root function prototype
 

Reported-by: Yves Vinter <yves.vinter at bull.net>

---


diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index aed9307..bdf45a7 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -42,6 +42,12 @@
 #include "openwsman.h"
 #include "virstring.h"
 
+/* Bull */
+#include "virtypedparam.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
 VIR_LOG_INIT("hyperv.hyperv_driver");
@@ -58,12 +64,97 @@ hypervFreePrivate(hypervPrivate **priv)
         wsmc_release((*priv)->client);
     }
 
+	/* Bull */
+  	pthread_mutex_destroy(&(*priv)->mutex);
+
     hypervFreeParsedUri(&(*priv)->parsedUri);
     VIR_FREE(*priv);
 }
 
 
 
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+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 +199,17 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags
         return VIR_DRV_OPEN_ERROR;
     }
 
-    /* Require auth */
-    if (auth == NULL || auth->cb == NULL) {
-        virReportError(VIR_ERR_INVALID_ARG, "%s",
-                       _("Missing or invalid auth pointer"));
-        return VIR_DRV_OPEN_ERROR;
-    }
+	/* Require auth */
+	/* Bull - if auth is null, auth=virConnectAuthPtrDefault */
+    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,14 +288,28 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags
         goto cleanup;
     }
 
+	/* Bull - Setup capabilities */
+    priv->caps = hypervCapsInit(priv);
+    if (priv->caps == NULL) {
+        goto cleanup;
+    }
+
+	/* Bull - Init xmlopt to parse Domain XML */
+	priv->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL);
+	
     conn->privateData = priv;
-    priv = NULL;
+	
+	/* Bull */
+  	pthread_mutex_init(&priv->mutex, NULL);
+
+	priv = NULL;
     result = VIR_DRV_OPEN_SUCCESS;
 
  cleanup:
     hypervFreePrivate(&priv);
     VIR_FREE(username);
     VIR_FREE(password);
+	virBufferFreeAndReset(&query);
     hypervFreeObject(priv, (hypervObject *)computerSystem);
 
     return result;
@@ -254,6 +364,7 @@ hypervConnectGetHostname(virConnectPtr conn)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+	virBufferFreeAndReset(&query);
 
     return hostname;
 }
@@ -352,6 +463,7 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
     hypervFreeObject(priv, (hypervObject *)processorList);
+	virBufferFreeAndReset(&query);
 
     return result;
 }
@@ -396,6 +508,7 @@ hypervConnectListDomains(virConnectPtr conn, int *ids, int maxids)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+	virBufferFreeAndReset(&query);
 
     return success ? count : -1;
 }
@@ -432,6 +545,7 @@ hypervConnectNumOfDomains(virConnectPtr conn)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+	virBufferFreeAndReset(&query);
 
     return success ? count : -1;
 }
@@ -464,6 +578,7 @@ hypervDomainLookupByID(virConnectPtr conn, int id)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+	virBufferFreeAndReset(&query);
 
     return domain;
 }
@@ -500,6 +615,7 @@ hypervDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+	virBufferFreeAndReset(&query);
 
     return domain;
 }
@@ -533,6 +649,7 @@ hypervDomainLookupByName(virConnectPtr conn, const char *name)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystem);
+	virBufferFreeAndReset(&query);
 
     return domain;
 }
@@ -748,6 +865,7 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
     hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
     hypervFreeObject(priv, (hypervObject *)processorSettingData);
     hypervFreeObject(priv, (hypervObject *)memorySettingData);
+	virBufferFreeAndReset(&query);
 
     return result;
 }
@@ -915,6 +1033,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 +1090,7 @@ hypervConnectListDefinedDomains(virConnectPtr conn, char **const names, int maxn
     }
 
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+	virBufferFreeAndReset(&query);
 
     return count;
 }
@@ -1007,6 +1127,7 @@ hypervConnectNumOfDefinedDomains(virConnectPtr conn)
 
  cleanup:
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+	virBufferFreeAndReset(&query);
 
     return success ? count : -1;
 }
@@ -1346,6 +1467,7 @@ hypervConnectListAllDomains(virConnectPtr conn,
     }
 
     hypervFreeObject(priv, (hypervObject *)computerSystemList);
+	virBufferFreeAndReset(&query);
 
     return ret;
 }
@@ -1353,6 +1475,1767 @@ hypervConnectListAllDomains(virConnectPtr conn,
 
 
 
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+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);
+}
+
+
+
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+static int hypervDomainShutdown(virDomainPtr dom)
+{
+    return hypervDomainShutdownFlags(dom, 0);
+}
+
+
+
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+static int 
+hypervDomainGetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr params, int *nparams)
+{
+    return hypervDomainGetSchedulerParametersFlags(dom, params, nparams, VIR_DOMAIN_AFFECT_CURRENT);
+}
+
+
+
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+static char*
+hypervConnectGetCapabilities(virConnectPtr conn)
+{
+    hypervPrivate *priv = conn->privateData;
+    char *xml = virCapabilitiesFormatXML(priv->caps);
+
+    if (xml == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return xml;
+}
+
+
+/* Bull */
+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,'.');
+	datafile->data->Version[p-datafile->data->Version-1] = '\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);
+	//VIR_FREE(p);
+	virBufferFreeAndReset(&query);
+	return ret;
+}
+
+
+
+/* Bull */
+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;
+}
+
+
+
+/* Bull */
+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;
+	hypervPrivate *priv = domain->conn->privateData;
+	virBuffer query = VIR_BUFFER_INITIALIZER;
+	virBuffer queryVssd = VIR_BUFFER_INITIALIZER;
+	Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+	properties_t *tab_props;
+	eprParam eprparam; 
+	embeddedParam embeddedparam;
+	int nb_params;
+	char uuid_string[VIR_UUID_STRING_BUFLEN];
+	const char *selector = "CreationClassName=Msvm_VirtualSystemManagementService";
+	// Convert autostart integer to string
+	const int n = snprintf(NULL, 0, "%u", autostart);
+	char autostart_str[n+1];
+	sprintf(autostart_str, "%u", autostart);
+	
+	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 ? "1" : "2";; 
+	(*tab_props).val = autostart_str; 
+	(*(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;
+}
+
+
+
+static int
+hypervDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
+{
+	int res = -1;
+	invokeXmlParam *params;
+	char uuid_string[VIR_UUID_STRING_BUFLEN];
+	hypervPrivate *priv = domain->conn->privateData;
+	properties_t *tab_props;
+	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";
+	// Convert memory to string in Mb
+	const unsigned long memoryMb = memory/1024;
+	const int n = snprintf(NULL, 0, "%lu", memoryMb);
+	char memory_str[n+1];
+	sprintf(memory_str, "%lu", memoryMb);
+
+	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);
+	hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+	hypervFreeObject(priv, (hypervObject *)memorySettingData);
+	virBufferFreeAndReset(&query);
+	virBufferFreeAndReset(&query2);
+	return res;
+}
+
+
+
+/* Bull */
+/* 
+ * 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;
+    }
+
+	/* Double the blackslashes */
+	//FIXME: normally there are only 2 backslashes in rasdInstanceID
+        /* Count the number of backslash character */
+        strTemp = strchr(rasdInstanceID, '\\');
+        while (strTemp != NULL) {
+            n++;
+            strTemp = strchr(++strTemp, '\\');
+        }
+	strTemp = (char *) malloc(strlen(rasdInstanceID) + (n * sizeof(char)) + 1);
+	while (rasdInstanceID[i] != '\0') {
+		strTemp[j] = rasdInstanceID[i];
+		if (rasdInstanceID[i] == '\\') {
+			j++;
+			strTemp[j] = '\\';
+		}
+		i++;
+		j++;
+	}
+
+	/* 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;
+}
+
+
+
+/* Bull */
+/* 
+ * 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;
+}
+
+
+
+/* Bull */
+/*
+ * 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;
+	properties_t *tab_props;
+	eprParam eprparam; 
+	embeddedParam embeddedparam;
+	virBuffer query = VIR_BUFFER_INITIALIZER;
+	Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+	Msvm_MemorySettingData *memorySettingData = NULL;
+	// Convert memory to string in Mb
+	const unsigned long memoryMb = memory/1024;
+	const int n = snprintf(NULL, 0, "%lu", memoryMb);
+	char memory_str[n+1];
+	sprintf(memory_str, "%lu", memoryMb);
+
+	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);
+	hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+	hypervFreeObject(priv, (hypervObject *)memorySettingData);
+	virBufferFreeAndReset(&query);
+	return res;
+}
+
+
+/* Bull */
+static int
+hypervDomainSetMemory(virDomainPtr domain, unsigned long memory)
+{
+	return hypervDomainSetMemoryFlags(domain, memory, 0);
+}
+
+
+/* Bull */
+static int
+hypervDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
+		unsigned int flags ATTRIBUTE_UNUSED)
+{
+	int res = -1;	
+	invokeXmlParam *params;
+	char uuid_string[VIR_UUID_STRING_BUFLEN];
+	hypervPrivate *priv = domain->conn->privateData;
+	properties_t *tab_props;
+	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";
+	// Convert nvcpus to string
+	const int n = snprintf(NULL, 0, "%u", nvcpus);
+	char nvcpus_str[n+1];
+	sprintf(nvcpus_str, "%u", 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);
+	hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+	hypervFreeObject(priv, (hypervObject *)processorSettingData);
+	virBufferFreeAndReset(&query);
+	return res;
+}
+
+
+
+/* Bull */
+static int
+hypervDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
+{
+	return hypervDomainSetVcpusFlags(domain, nvcpus, 0);
+}
+
+
+
+/* Bull */
+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, *ideControlerAddr;
+	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;
+	Msvm_ResourceAllocationSettingData *diskRasd = NULL;
+	Msvm_ResourceAllocationSettingData *newDiskDrive = NULL;
+	Msvm_AllocationCapabilities *allocationCapabilities  = NULL;
+	Msvm_AllocationCapabilities *allocationCapabilities2  = NULL;
+	invokeXmlParam *params;
+	properties_t *tab_props;
+	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(sizeof(char)+1);
+	ideControlerAddr = (char *) malloc(sizeof(char)+1);
+	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) {
+			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:
+	free(ideRasdPath);
+	free(newDiskDrivePath);
+	virBufferFreeAndReset(&query);
+	if (!tab_props)
+		VIR_FREE(tab_props);
+	if (!params)
+		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);
+
+	return ret;
+}
+
+
+
+/* Bull */
+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;
+	invokeXmlParam *params;
+	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(sizeof(char) * (strlen(guid_string) + 3));
+	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:
+	free(virtualSystemIdentifiers);
+	free(switchPortPATH);
+	virBufferFreeAndReset(&query);
+	if (!tab_props)
+		VIR_FREE(tab_props);
+	if (!params)
+		VIR_FREE(params);
+	hypervFreeObject(priv, (hypervObject *)switchPort);
+	hypervFreeObject(priv, (hypervObject *)virtualSwitch);
+	return ret;
+}
+
+
+
+/* Bull */
+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:
+	free(xmlDomain);
+	return ret;
+}
+
+
+
+/* Bull */
+static int
+hypervDomainAttachDevice(virDomainPtr domain, const char *xml)
+{
+    return hypervDomainAttachDeviceFlags(domain, xml, 0);
+}
+
+
+
+/* Bull */
+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:
+	if (tab_props != NULL)
+		VIR_FREE(tab_props);
+	if (params != NULL)
+		VIR_FREE(params);
+	return domain;
+}
+
+
+
+/* Bull */
+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);
+
+	// 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;
+}
+
+
+
+/* Bull */
+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;
+	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:
+	virBufferFreeAndReset(&query);
+	if (!params)
+		VIR_FREE(params);
+    hypervFreeObject(priv, (hypervObject *)computerSystem);
+    return result;
+}
+
+
+
+/* Bull */
+static int
+hypervDomainUndefine(virDomainPtr domain)
+{
+	return hypervDomainUndefineFlags(domain, 0);
+}
+
+
 
 static virDriver hypervDriver = {
     .no = VIR_DRV_HYPERV,
@@ -1389,6 +3272,33 @@ static virDriver hypervDriver = {
     .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
     .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
     .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
+	
+    /* Bull */
+    .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..dd89207 100644
--- a/src/hyperv/hyperv_network_driver.c
+++ b/src/hyperv/hyperv_network_driver.c
@@ -29,6 +29,11 @@
 #include "viruuid.h"
 #include "hyperv_network_driver.h"
 
+/* Bull */
+#include "virstring.h"
+#include "hyperv_wmi.h"
+#include "network_conf.h"
+
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
 
@@ -60,11 +65,254 @@ hypervNetworkClose(virConnectPtr conn)
 }
 
 
+/* Bull */
+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;
+}
+
+
+/* Bull */
+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;
+}
+
+
+/* Bull */
+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;
+}
+
+
+/* Bull */
+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;
+}
+
+
+/* Bull */
+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;
+}
+
+
+/* Bull */
+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 */
+
+    /* Bull */
+    .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..c543f1a 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -28,11 +28,26 @@
 # include "hyperv_util.h"
 # include "openwsman.h"
 
+/* Bull */
+# include "capabilities.h"
+#include "domain_conf.h"
+
+/* Bull - Add mutex to protect against concurrent calls 
+   (OpenWsMan client API is not thread-safe) */
+#ifndef WIN32
+# include <pthread.h>
+#endif
+
 typedef struct _hypervPrivate hypervPrivate;
 
 struct _hypervPrivate {
     hypervParsedUri *parsedUri;
     WsManClient *client;
+
+	/* Bull */
+	pthread_mutex_t mutex;
+	virCapsPtr caps;
+    virDomainXMLOptionPtr xmlopt; /* to parse Domain XML */ 
 };
 
 #endif /* __HYPERV_PRIVATE_H__ */
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index acb705c..c0ea00b 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -1,3 +1,4 @@
+
 /*
  * hyperv_wmi.c: general WMI over WSMAN related functions and structures for
  *               managing Microsoft Hyper-V hosts
@@ -33,16 +34,704 @@
 #include "hyperv_wmi.h"
 #include "virstring.h"
 
+/* Bull */
+# 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/*"
+/* Bull */
+/* #define DUMP_REQUEST 1 */
 
-#define VIR_FROM_THIS VIR_FROM_HYPERV
+/* Bull */
+/* 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;
+}
+
+
+/* Bull */
+/* 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;
+}
+
+
+/* Bull */
+/* 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;
+	int len = 0;
+	int	i = 0;
+	char* type = NULL;
+	bool isArray = false;
+	char* typeTmp = NULL;
+	int n = 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
+			n = strlen(type) - 2;
+			typeTmp = (char *) malloc(sizeof(char) * (n+1));
+			strncpy(typeTmp, type, n);
+			type = (char *) malloc(sizeof(char) * (n+1));
+			strcpy(type, typeTmp);
+			free(typeTmp);
+		} 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);
+	//VIR_FREE((char*)type);
+	if (xmlBufferNode != NULL){
+		xmlBufferFree(xmlBufferNode);
+	}
+
+	return result;
+}
+
+
+/* Bull */
+/* 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;
+}
+	
+
+/* Bull */
+/* 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;
+
+	/* Request options and filter */
+	options = wsmc_options_init();
+	
+	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);
+
+	return result;
+}
+
+
+/* Bull */
+/* 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;
+        Msvm_ConcreteJob *concreteJob = NULL;
+        bool completed = false;
+	bool locked;
+	
+	options = wsmc_options_init();
+	
+	wsmc_add_selectors_from_str(options, selector);
+	
+#ifdef DUMP_REQUEST
+	wsmc_set_action_option(options, FLAG_DUMP_REQUEST);
+#endif
+
+	/* 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);
+	
+	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;
+        }
+		
+        /* Unlock mutex */
+        /* 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);
+    }
+    ws_xml_destroy_doc(response);
+    VIR_FREE(returnValue);
+    VIR_FREE(instanceID);
+    VIR_FREE(xpath_expr_string);
+    hypervFreeObject(priv, (hypervObject *)concreteJob);
+
+    if (locked == true) pthread_mutex_unlock(&priv->mutex);
+    
+    return result;
+}
+
+
+/* Bull */
+/* 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 +817,13 @@ hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root,
         return -1;
     }
 
-    if (virBufferCheckError(query) < 0)
+    if (virBufferError(query)) {
+        virReportOOMError();
         return -1;
+    }
+	
+	/* Bull - Lock mutex */
+	pthread_mutex_lock(&priv->mutex);
 
     serializerContext = wsmc_get_serialization_context(priv->client);
 
@@ -258,6 +952,9 @@ hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root,
     ws_xml_destroy_doc(response);
     VIR_FREE(enumContext);
     hypervFreeObject(priv, head);
+		
+	/* Bull - Unlock mutex */
+  	pthread_mutex_unlock(&priv->mutex);
 
     return result;
 }
@@ -403,8 +1100,13 @@ hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
     virBuffer query = VIR_BUFFER_INITIALIZER;
     Msvm_ConcreteJob *concreteJob = NULL;
     bool completed = false;
-
+	bool locked; /* Bull */
+	
     virUUIDFormat(domain->uuid, uuid_string);
+	
+	/* Bull - Lock mutex */
+  	pthread_mutex_lock(&priv->mutex);
+	locked = true;
 
     if (virAsprintf(&selector, "Name=%s&CreationClassName=Msvm_ComputerSystem",
                     uuid_string) < 0 ||
@@ -456,6 +1158,11 @@ hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
                            "InstanceID", "RequestStateChange");
             goto cleanup;
         }
+		
+		/* Bull - Unlock mutex */
+		/* 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. */
@@ -527,6 +1234,9 @@ hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
     VIR_FREE(instanceID);
     hypervFreeObject(priv, (hypervObject *)concreteJob);
 
+	/* Bull - Unlock mutex */
+  	if (locked == true) pthread_mutex_unlock(&priv->mutex);
+
     return result;
 }
 
@@ -676,5 +1386,32 @@ hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
 }
 
 
+/* Bull */
+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..9a4f920 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -24,11 +24,76 @@
 #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"
 
+/* Bull */
+#define EPR_PARAM 0
+#define SIMPLE_PARAM 1
+#define EMBEDDED_PARAM 2
+
+
+/* Bull */
+
+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 
+hypervCreateXmlStruct(const char *methodName,const char *classURI,WsXmlDocH *xmlDocRoot, WsXmlNodeH *xmlNodeMethod);
+
+const char * 
+hypervGetPropType(const char * className, const char *attrName);
+
+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);
+
+int
+hypervInvokeMethod(hypervPrivate *priv, invokeXmlParam *parameters, int nbParameters,const char* methodName, const char* providerURI, const char *selector);
 
 
 typedef struct _hypervObject hypervObject;
@@ -53,7 +118,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 +179,15 @@ int hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
                                        Msvm_ComputerSystem **computerSystem);
 
 
+/* Bull */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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..dcaf090 100755
--- a/src/hyperv/hyperv_wmi_generator.py
+++ b/src/hyperv/hyperv_wmi_generator.py
@@ -68,7 +68,8 @@ class Class:
         header += "\n"
         header += "#define %s_RESOURCE_URI \\\n" % name_upper
 
-        if self.name.startswith("Win32_"):
+		#Bull
+        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 +114,8 @@ class Class:
                   % (self.name.replace("_", ""), self.name)
         source += "{\n"
 
-        if self.name.startswith("Win32_"):
+		#Bull
+        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 +151,34 @@ class Class:
 
         return source
 
-
+	#Bull
+    def generate_tab_classes(self):
+        tab_class = "	{(\"%s" % self.name
+        tab_class += "\"),cimTypes_%s" % self.name
+        tab_class += "}"
+
+        return tab_class
+
+	#Bull
+    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 +210,16 @@ class Property:
             return "    SER_NS_%s(%s_RESOURCE_URI, \"%s\", 1),\n" \
                    % (Property.typemap[self.type], class_name.upper(), self.name)
 
-
+	#Bull
+    def generate_type_tab(self):
+        tab_class = "	{(\"%s" % self.name
+        tab_class += "\"),(\"%s" % self.type
+        #Adrien
+        #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 +268,20 @@ def parse_class(block):
 
     return Class(name=name, properties=properties)
 
-
+#Bull
+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:
@@ -253,6 +296,9 @@ def main():
     classes_typedef = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.typedef"))
     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"))
+	
+	#Bull
+    classes_test_header = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes_attr.generated.h"))
 
     # parse input file
     number = 0
@@ -294,6 +340,10 @@ def main():
     classes_typedef.write(notice)
     classes_header.write(notice)
     classes_source.write(notice)
+	
+	#Bull
+    classes_test_header.write(notice)
+    classes_test_header.write(print_type_header())	
 
     names = classes_by_name.keys()
     names.sort()
@@ -304,8 +354,17 @@ def main():
         classes_typedef.write(classes_by_name[name].generate_classes_typedef())
         classes_header.write(classes_by_name[name].generate_classes_header())
         classes_source.write(classes_by_name[name].generate_classes_source())
-
-
+	
+	#Bull
+    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);




More information about the libvir-list mailing list