}
+#define MATCH(FLAG) (flags & (FLAG))
+static int
+hypervListAllDomains(virConnectPtr conn,
+ virDomainPtr **domains,
+ unsigned int flags)
+{
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystemList = NULL;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ size_t ndoms;
+ virDomainPtr domain;
+ virDomainPtr *doms = NULL;
+ int count = 0;
+ int ret = -1;
+ int i;
+
+ virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
+
+ /* check for filter combinations that return no results:
+ * persistent: all hyperv guests are persistent
+ * snapshot: the driver does not support snapshot management
+ * autostart: the driver does not support autostarting guests
+ */
+ if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
+ !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) &&
+ !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) &&
+ !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT))) {
+ if (domains &&
+ VIR_ALLOC_N(*domains, 1) < 0)
+ goto no_memory;
+
+ ret = 0;
+ goto cleanup;
+ }
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+
+ /* construct query with filter depending on flags */
+ if (!(flags & VIR_CONNECT_LIST_DOMAINS_ACTIVE &&
+ flags & VIR_CONNECT_LIST_DOMAINS_INACTIVE)) {
+ if (flags & VIR_CONNECT_LIST_DOMAINS_ACTIVE) {
+ virBufferAddLit(&query, "and ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_ACTIVE);
+ }
+ if (flags & VIR_CONNECT_LIST_DOMAINS_INACTIVE) {
+ virBufferAddLit(&query, "and ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_INACTIVE);
+ }
+ }
+
+ if (hypervGetMsvmComputerSystemList(priv, &query,
+ &computerSystemList) < 0)
+ goto cleanup;
+
+ if (domains) {
+ if (VIR_ALLOC_N(doms, 1) < 0)
+ goto no_memory;
+ ndoms = 1;
+ }
+
+ for (computerSystem = computerSystemList; computerSystem != NULL;
+ computerSystem = computerSystem->next) {
+
+ /* filter by domain state */
+ if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE)) {
+ int st = hypervMsvmComputerSystemEnabledStateToDomainState(computerSystem);
+ if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
+ st == VIR_DOMAIN_RUNNING) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
+ st == VIR_DOMAIN_PAUSED) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
+ st == VIR_DOMAIN_SHUTOFF) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
+ (st != VIR_DOMAIN_RUNNING &&
+ st != VIR_DOMAIN_PAUSED &&
+ st != VIR_DOMAIN_SHUTOFF))))
+ continue;
+ }
+
+ /* managed save filter */
+ if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE)) {
+ bool mansave = computerSystem->data->EnabledState ==
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED;
+
+ if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && mansave) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) && !mansave)))
+ continue;
+ }
+
+ if (!doms) {
+ count++;
+ continue;
+ }
+
+ if (VIR_RESIZE_N(doms, ndoms, count, 2) < 0)
+ goto no_memory;
+
+ if (hypervMsvmComputerSystemToDomain(conn, computerSystem,
+ &domain) < 0)
+ goto cleanup;
+
+ doms[count++] = domain;
+ }
+
+ if (doms)
+ *domains = doms;
+ doms = NULL;
+ ret = count;
+
+cleanup:
+ if (doms) {
+ for (i = 0; i < count; ++i) {
+ if (doms[i])
+ virDomainFree(doms[i]);
+ }
+ }
+
+ VIR_FREE(doms);
+ hypervFreeObject(priv, (hypervObject *)computerSystemList);
+ return ret;
+
+no_memory:
+ virReportOOMError();
+ goto cleanup;
+}
+#undef MATCH
+
+
+
static virDriver hypervDriver = {
.no = VIR_DRV_HYPERV,
.nodeGetInfo = hypervNodeGetInfo, /* 0.9.5 */
.listDomains = hypervListDomains, /* 0.9.5 */
.numOfDomains = hypervNumberOfDomains, /* 0.9.5 */
+ .listAllDomains = hypervListAllDomains, /* 0.10.2 */
.domainLookupByID = hypervDomainLookupByID, /* 0.9.5 */
.domainLookupByUUID = hypervDomainLookupByUUID, /* 0.9.5 */
.domainLookupByName = hypervDomainLookupByName, /* 0.9.5 */