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 <rkagan@xxxxxxxxxxxxx> --- 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 <rkagan@xxxxxxxxxxxxx> +# 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 <rkagan@xxxxxxxxxxxxx> + * 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 virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list