Windows PnP manager may start driver installations asynchronously upon
receiving notifications from kernel mode PnP system about discovery of
new devices.

Those installations may interact destructively with other
installation/uninstallation activities, either initiated by a user or
started from another service.

Add a tool which can wait until the installations initiated by the PnP
manager are finished (or the timeout elapses), which allows to serialize
them with user- or script- initiated ones.

A foreseen user of this tool is libguestfs/v2v.

Signed-off-by: Roman Kagan <[email protected]>
---
 Makefile.am                         |   2 +-
 configure.ac                        |   2 +-
 Makefile.am => pnp_wait/Makefile.am |  14 ++---
 pnp_wait/pnp_wait.c                 | 109 ++++++++++++++++++++++++++++++++++++
 4 files changed, 117 insertions(+), 10 deletions(-)
 copy Makefile.am => pnp_wait/Makefile.am (63%)
 create mode 100644 pnp_wait/pnp_wait.c

diff --git a/Makefile.am b/Makefile.am
index e853ff1..43b68ba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,4 +21,4 @@
 # the Fedora Windows cross-compiler and invoke 'mingw32-configure'
 # instead of the normal './configure' command.
 
-SUBDIRS = RHSrvAny
+SUBDIRS = RHSrvAny pnp_wait
diff --git a/configure.ac b/configure.ac
index 07cc982..81484a0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,5 +43,5 @@ AC_CHECK_FUNCS([StringCchPrintf])
 
 dnl Produce output files.
 AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile RHSrvAny/Makefile])
+AC_CONFIG_FILES([Makefile RHSrvAny/Makefile pnp_wait/Makefile])
 AC_OUTPUT
diff --git a/Makefile.am b/pnp_wait/Makefile.am
similarity index 63%
copy from Makefile.am
copy to pnp_wait/Makefile.am
index e853ff1..a9a81b3 100644
--- a/Makefile.am
+++ b/pnp_wait/Makefile.am
@@ -1,6 +1,6 @@
-# RHSrvAny - Turn any Windows program into a Windows service.
-# Written by Yuval Kashtan.
-# Copyright (C) 2010 Red Hat Inc.
+# pnp_wait - wait for PnP installation activities to complete.
+# Author: Roman Kagan <[email protected]>
+# Copyright (C) 2016 Parallels IP Holdings GmbH.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,9 +16,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-# Note that this program only makes sense when cross-compiled as a
-# Windows program.  Therefore you probably need to use something like
-# the Fedora Windows cross-compiler and invoke 'mingw32-configure'
-# instead of the normal './configure' command.
+bin_PROGRAMS = pnp_wait$(EXEEXT)
 
-SUBDIRS = RHSrvAny
+pnp_wait_SOURCES = pnp_wait.c
+pnp_wait_LDADD = -lcfgmgr32
diff --git a/pnp_wait/pnp_wait.c b/pnp_wait/pnp_wait.c
new file mode 100644
index 0000000..5e5ed10
--- /dev/null
+++ b/pnp_wait/pnp_wait.c
@@ -0,0 +1,109 @@
+/* pnp_wait - wait for PnP installation activities to complete.
+ * Author: Roman Kagan <[email protected]>
+ * Copyright (C) 2016 Parallels IP Holdings GmbH.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <cfgmgr32.h>
+
+#define RET_SUCCESS    0
+#define RET_TIMEOUT    1
+#define RET_ERROR      2
+
+static const char *waitres2str(int res)
+{
+       switch (res) {
+       case WAIT_OBJECT_0:
+               return "done";
+       case WAIT_TIMEOUT:
+               return "timed out";
+       default:
+               return "error";
+       }
+}
+
+static int waitres2retcode(int res)
+{
+       switch (res) {
+       case WAIT_OBJECT_0:
+               return RET_SUCCESS;
+       case WAIT_TIMEOUT:
+               return RET_TIMEOUT;
+       default:
+               return RET_ERROR;
+       }
+}
+
+void usage(FILE *fp, const char *cmd)
+{
+       fprintf(fp,
+               "Usage: %s [-h|--help] [TIMEOUT]\n"
+               "Wait for PnP activities to complete\n"
+               "\n"
+               "  -h,--help   show this message\n"
+               "  TIMEOUT     timeout in ms (default: wait forever)\n"
+               "\n"
+               "exit code:\n"
+               "  %d          %s\n"
+               "  %d          %s\n"
+               "  %d          %s\n",
+               cmd,
+               waitres2retcode(WAIT_OBJECT_0), waitres2str(WAIT_OBJECT_0),
+               waitres2retcode(WAIT_TIMEOUT), waitres2str(WAIT_TIMEOUT),
+               waitres2retcode(WAIT_FAILED), waitres2str(WAIT_FAILED));
+}
+
+int main(int argc, char **argv)
+{
+       int ret, i;
+       time_t t;
+       unsigned tmo = INFINITE;
+       const char *prog = argv[0];
+
+       for (i = 1; i < argc; i++) {
+               const char *s = argv[i];
+               char *e;
+
+               if (!strcmp(s, "-h") || !strcmp(s, "--help")) {
+                       usage(stdout, prog);
+                       return RET_SUCCESS;
+               }
+
+               tmo = strtoul(s, &e, 0);
+               if (*e == '\0' && e != s)
+                       continue;
+
+               fprintf(stderr, "failed to parse parameter: \"%s\"\n", s);
+               usage(stderr, prog);
+               return RET_ERROR;
+       }
+
+       t = time(NULL);
+       printf("start waiting for PnP to complete @ %s", ctime(&t));
+
+       ret = CMP_WaitNoPendingInstallEvents(tmo);
+
+       t = time(NULL);
+       printf("%s waiting for PnP to complete @ %s", waitres2str(ret),
+              ctime(&t));
+       return waitres2retcode(ret);
+}
-- 
2.7.4

_______________________________________________
virt-tools-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/virt-tools-list

Reply via email to