summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostDrivers/win
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostDrivers/win')
-rw-r--r--src/VBox/HostDrivers/win/Makefile.kmk47
-rw-r--r--src/VBox/HostDrivers/win/VBoxDbgLog.h140
-rw-r--r--src/VBox/HostDrivers/win/cfg/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp884
-rw-r--r--src/VBox/HostDrivers/win/load.cmd52
-rwxr-xr-xsrc/VBox/HostDrivers/win/load.sh88
-rw-r--r--src/VBox/HostDrivers/win/loadall.cmd52
-rwxr-xr-xsrc/VBox/HostDrivers/win/loadall.sh100
8 files changed, 1363 insertions, 0 deletions
diff --git a/src/VBox/HostDrivers/win/Makefile.kmk b/src/VBox/HostDrivers/win/Makefile.kmk
new file mode 100644
index 00000000..a96006f6
--- /dev/null
+++ b/src/VBox/HostDrivers/win/Makefile.kmk
@@ -0,0 +1,47 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for Windows driver tooling lib.
+#
+
+#
+# Copyright (C) 2011-2019 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+# VirtualBox OSE distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+LIBRARIES += VBoxDrvCfg
+VBoxDrvCfg_TEMPLATE = VBOXR3STATIC
+VBoxDrvCfg_SDKS = ReorderCompilerIncs $(VBOX_WINPSDK) $(VBOX_WINDDK)
+VBoxDrvCfg_DEFS = _WIN32_WINNT=0x0501 _UNICODE UNICODE
+VBoxDrvCfg_SOURCES = cfg/VBoxDrvCfg.cpp
+
+
+INSTALLS += HostDrivers-scripts
+HostDrivers-scripts_INST = $(INST_DIST)
+HostDrivers-scripts_EXEC_SOURCES = \
+ loadall.sh \
+ loadall.cmd \
+ load.sh \
+ load.cmd
+
+# generate rules
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/HostDrivers/win/VBoxDbgLog.h b/src/VBox/HostDrivers/win/VBoxDbgLog.h
new file mode 100644
index 00000000..d22744cb
--- /dev/null
+++ b/src/VBox/HostDrivers/win/VBoxDbgLog.h
@@ -0,0 +1,140 @@
+/* $Id: VBoxDbgLog.h $ */
+/** @file
+ * Logging helper
+ */
+
+/*
+ * Copyright (C) 2011-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef VBOX_INCLUDED_SRC_win_VBoxDbgLog_h
+#define VBOX_INCLUDED_SRC_win_VBoxDbgLog_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifndef VBOX_DBG_LOG_NAME
+# error VBOX_DBG_LOG_NAME should be defined!
+#endif
+
+/* Uncomment to show file/line info in the log */
+/*#define VBOX_DBG_LOG_SHOWLINEINFO*/
+
+#define VBOX_DBG_LOG_PREFIX_FMT VBOX_DBG_LOG_NAME"::"LOG_FN_FMT": "
+#define VBOX_DBG_LOG_PREFIX_PARMS __PRETTY_FUNCTION__
+
+#ifdef VBOX_DBG_LOG_SHOWLINEINFO
+# define VBOX_DBG_LOG_SUFFIX_FMT " (%s:%d)\n"
+# define VBOX_DBG_LOG_SUFFIX_PARMS ,__FILE__, __LINE__
+#else
+# define VBOX_DBG_LOG_SUFFIX_FMT "\n"
+# define VBOX_DBG_LOG_SUFFIX_PARMS
+#endif
+
+#ifdef DEBUG_misha
+# define BP_WARN() AssertFailed()
+#else
+# define BP_WARN() do { } while (0)
+#endif
+
+#define _LOGMSG_EXACT(_logger, _a) \
+ do \
+ { \
+ _logger(_a); \
+ } while (0)
+
+#define _LOGMSG(_logger, _a) \
+ do \
+ { \
+ _logger((VBOX_DBG_LOG_PREFIX_FMT, VBOX_DBG_LOG_PREFIX_PARMS)); \
+ _logger(_a); \
+ _logger((VBOX_DBG_LOG_SUFFIX_FMT VBOX_DBG_LOG_SUFFIX_PARMS)); \
+ } while (0)
+
+/* we can not print paged strings to RT logger, do it this way */
+#define _LOGMSG_STR(_logger, _a, _f) do {\
+ int _i = 0; \
+ _logger(("\"")); \
+ for (;(_a)[_i];++_i) { \
+ _logger(("%"_f, (_a)[_i])); \
+ }\
+ _logger(("\"\n")); \
+ } while (0)
+
+#define _LOGMSG_USTR(_logger, _a) do {\
+ int _i = 0; \
+ _logger(("\"")); \
+ for (;_i<(_a)->Length/2;++_i) { \
+ _logger(("%c", (_a)->Buffer[_i])); \
+ }\
+ _logger(("\"\n")); \
+ } while (0)
+
+#define WARN_NOBP(_a) \
+ do \
+ { \
+ Log((VBOX_DBG_LOG_PREFIX_FMT"WARNING! ", VBOX_DBG_LOG_PREFIX_PARMS)); \
+ Log(_a); \
+ Log((VBOX_DBG_LOG_SUFFIX_FMT VBOX_DBG_LOG_SUFFIX_PARMS)); \
+ } while (0)
+
+#define WARN(_a) \
+ do \
+ { \
+ WARN_NOBP(_a); \
+ BP_WARN(); \
+ } while (0)
+
+#define ASSERT_WARN(_a, _w) do {\
+ if(!(_a)) { \
+ WARN(_w); \
+ }\
+ } while (0)
+
+#define LOG(_a) _LOGMSG(Log, _a)
+#define LOGREL(_a) _LOGMSG(LogRel, _a)
+#define LOGF(_a) _LOGMSG(LogFlow, _a)
+#define LOGF_ENTER() LOGF(("ENTER"))
+#define LOGF_LEAVE() LOGF(("LEAVE"))
+#define LOG_EXACT(_a) _LOGMSG_EXACT(Log, _a)
+#define LOGREL_EXACT(_a) _LOGMSG_EXACT(LogRel, _a)
+/* we can not print paged strings to RT logger, do it this way */
+#define LOG_STRA(_a) do {\
+ _LOGMSG_STR(Log, _a, "c"); \
+ } while (0)
+#define LOG_STRW(_a) do {\
+ _LOGMSG_STR(Log, _a, "c"); \
+ } while (0)
+#define LOG_USTR(_a) do {\
+ _LOGMSG_USTR(Log, _a); \
+ } while (0)
+#define LOGREL_STRA(_a) do {\
+ _LOGMSG_STR(LogRel, _a, "c"); \
+ } while (0)
+#define LOGREL_STRW(_a) do {\
+ _LOGMSG_STR(LogRel, _a, "c"); \
+ } while (0)
+#define LOGREL_USTR(_a) do {\
+ _LOGMSG_USTR(LogRel, _a); \
+ } while (0)
+
+
+#endif /* !VBOX_INCLUDED_SRC_win_VBoxDbgLog_h */
+
diff --git a/src/VBox/HostDrivers/win/cfg/Makefile.kup b/src/VBox/HostDrivers/win/cfg/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/HostDrivers/win/cfg/Makefile.kup
diff --git a/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp b/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
new file mode 100644
index 00000000..7bcda464
--- /dev/null
+++ b/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
@@ -0,0 +1,884 @@
+/* $Id: VBoxDrvCfg.cpp $ */
+/** @file
+ * VBoxDrvCfg.cpp - Windows Driver Manipulation API implementation
+ */
+
+/*
+ * Copyright (C) 2011-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/VBoxDrvCfg-win.h>
+
+#include <iprt/win/setupapi.h>
+#include <iprt/win/shlobj.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+#include <malloc.h>
+#include <stdio.h>
+
+#include <Newdev.h>
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+static PFNVBOXDRVCFG_LOG g_pfnVBoxDrvCfgLog;
+static void *g_pvVBoxDrvCfgLog;
+
+static PFNVBOXDRVCFG_PANIC g_pfnVBoxDrvCfgPanic;
+static void *g_pvVBoxDrvCfgPanic;
+
+
+VBOXDRVCFG_DECL(void) VBoxDrvCfgLoggerSet(PFNVBOXDRVCFG_LOG pfnLog, void *pvLog)
+{
+ g_pfnVBoxDrvCfgLog = pfnLog;
+ g_pvVBoxDrvCfgLog = pvLog;
+}
+
+VBOXDRVCFG_DECL(void) VBoxDrvCfgPanicSet(PFNVBOXDRVCFG_PANIC pfnPanic, void *pvPanic)
+{
+ g_pfnVBoxDrvCfgPanic = pfnPanic;
+ g_pvVBoxDrvCfgPanic = pvPanic;
+}
+
+static void vboxDrvCfgLogRel(LPCSTR szString, ...)
+{
+ PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
+ void * pvLog = g_pvVBoxDrvCfgLog;
+ if (pfnLog)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+ pfnLog(VBOXDRVCFG_LOG_SEVERITY_REL, szBuffer, pvLog);
+ }
+}
+
+static void vboxDrvCfgLogRegular(LPCSTR szString, ...)
+{
+ PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
+ void * pvLog = g_pvVBoxDrvCfgLog;
+ if (pfnLog)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+ pfnLog(VBOXDRVCFG_LOG_SEVERITY_REGULAR, szBuffer, pvLog);
+ }
+}
+
+static void vboxDrvCfgLogFlow(LPCSTR szString, ...)
+{
+ PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
+ void * pvLog = g_pvVBoxDrvCfgLog;
+ if (pfnLog)
+ {
+ char szBuffer[4096] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
+ va_end(pArgList);
+ pfnLog(VBOXDRVCFG_LOG_SEVERITY_FLOW, szBuffer, pvLog);
+ }
+}
+
+static void vboxDrvCfgPanic()
+{
+ PFNVBOXDRVCFG_PANIC pfnPanic = g_pfnVBoxDrvCfgPanic;
+ void * pvPanic = g_pvVBoxDrvCfgPanic;
+ if (pfnPanic)
+ {
+ pfnPanic(pvPanic);
+ }
+}
+
+/* we do not use IPRT Logging because the lib is used in host installer and needs to
+ * post its msgs to MSI logger */
+#define NonStandardLogCrap(_m) do { vboxDrvCfgLogRegular _m ; } while (0)
+#define NonStandardLogFlowCrap(_m) do { vboxDrvCfgLogFlow _m ; } while (0)
+#define NonStandardLogRelCrap(_m) do { vboxDrvCfgLogRel _m ; } while (0)
+#define NonStandardAssertFailed() vboxDrvCfgPanic()
+#define NonStandardAssert(_m) do { \
+ if (RT_UNLIKELY(!(_m))) { vboxDrvCfgPanic(); } \
+ } while (0)
+
+
+class VBoxDrvCfgStringList
+{
+public:
+ VBoxDrvCfgStringList(int aSize);
+
+ ~VBoxDrvCfgStringList();
+
+ HRESULT add(LPWSTR pStr);
+
+ int size() {return mSize;}
+
+ LPWSTR get(int i) {return maList[i];}
+private:
+ HRESULT resize(int newSize);
+
+ LPWSTR *maList;
+ int mBufSize;
+ int mSize;
+};
+
+VBoxDrvCfgStringList::VBoxDrvCfgStringList(int aSize)
+{
+ maList = (LPWSTR*)malloc( sizeof(maList[0]) * aSize);
+ mBufSize = aSize;
+ mSize = 0;
+}
+
+VBoxDrvCfgStringList::~VBoxDrvCfgStringList()
+{
+ if (!mBufSize)
+ return;
+
+ for (int i = 0; i < mSize; ++i)
+ {
+ free(maList[i]);
+ }
+
+ free(maList);
+}
+
+HRESULT VBoxDrvCfgStringList::add(LPWSTR pStr)
+{
+ if (mSize == mBufSize)
+ {
+ int hr = resize(mBufSize+10);
+ if (SUCCEEDED(hr))
+ return hr;
+ }
+ size_t cStr = wcslen(pStr) + 1;
+ LPWSTR str = (LPWSTR)malloc( sizeof(maList[0][0]) * cStr);
+ memcpy(str, pStr, sizeof(maList[0][0]) * cStr);
+ maList[mSize] = str;
+ ++mSize;
+ return S_OK;
+}
+
+HRESULT VBoxDrvCfgStringList::resize(int newSize)
+{
+ NonStandardAssert(newSize >= mSize);
+ if (newSize < mSize)
+ return E_FAIL;
+ LPWSTR* pOld = maList;
+ maList = (LPWSTR*)malloc( sizeof(maList[0]) * newSize);
+ mBufSize = newSize;
+ memcpy(maList, pOld, mSize*sizeof(maList[0]));
+ free(pOld);
+ return S_OK;
+}
+
+/*
+ * inf file manipulation API
+ */
+typedef bool (*PFNVBOXNETCFG_ENUMERATION_CALLBACK) (LPCWSTR lpszFileName, PVOID pContext);
+
+typedef struct _INF_INFO
+{
+ LPCWSTR lpszClassName;
+ LPCWSTR lpszPnPId;
+} INF_INFO, *PINF_INFO;
+
+typedef struct _INFENUM_CONTEXT
+{
+ INF_INFO InfInfo;
+ DWORD Flags;
+ HRESULT hr;
+} INFENUM_CONTEXT, *PINFENUM_CONTEXT;
+
+static HRESULT vboxDrvCfgInfQueryContext(HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, PINFCONTEXT pCtx)
+{
+ if (!SetupFindFirstLineW(hInf, lpszSection, lpszKey, pCtx))
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupFindFirstLine failed WinEr (%d) for Section(%S), Key(%S)\n", dwErr, lpszSection, lpszKey));
+ return HRESULT_FROM_WIN32(dwErr);
+ }
+ return S_OK;
+}
+
+static HRESULT vboxDrvCfgInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, LPWSTR *lppszValue, PDWORD pcValue)
+{
+ DWORD dwErr;
+ DWORD cValue;
+
+ if (!SetupGetStringFieldW(pCtx, iValue, NULL, 0, &cValue))
+ {
+ dwErr = GetLastError();
+// NonStandardAssert(dwErr == ERROR_INSUFFICIENT_BUFFER);
+ if (dwErr != ERROR_INSUFFICIENT_BUFFER)
+ {
+ NonStandardLogFlowCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", dwErr, iValue));
+ return HRESULT_FROM_WIN32(dwErr);
+ }
+ }
+
+ LPWSTR lpszValue = (LPWSTR)malloc(cValue * sizeof (lpszValue[0]));
+ NonStandardAssert(lpszValue);
+ if (!lpszValue)
+ {
+ NonStandardLogRelCrap((__FUNCTION__ ": SetCoTaskMemAlloc failed to alloc mem of size (%d), for iValue(%d)\n", cValue * sizeof (lpszValue[0]), iValue));
+ return E_FAIL;
+ }
+
+ if (!SetupGetStringFieldW(pCtx, iValue, lpszValue, cValue, &cValue))
+ {
+ dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", dwErr, iValue));
+ NonStandardAssert(0);
+ free(lpszValue);
+ return HRESULT_FROM_WIN32(dwErr);
+ }
+
+ *lppszValue = lpszValue;
+ if (pcValue)
+ *pcValue = cValue;
+ return S_OK;
+}
+#if defined(RT_ARCH_AMD64)
+# define VBOXDRVCFG_ARCHSTR L"amd64"
+#else
+# define VBOXDRVCFG_ARCHSTR L"x86"
+#endif
+
+static HRESULT vboxDrvCfgInfQueryModelsSectionName(HINF hInf, LPWSTR *lppszValue, PDWORD pcValue)
+{
+ INFCONTEXT InfCtx;
+ LPWSTR lpszModels, lpszPlatform = NULL, lpszPlatformCur;
+ LPWSTR lpszResult = NULL;
+ DWORD cModels, cPlatform = 0, cPlatformCur, cResult = 0;
+ bool bNt = false, bArch = false /*, bOs = false */;
+
+ HRESULT hr = vboxDrvCfgInfQueryContext(hInf, L"Manufacturer", NULL, &InfCtx);
+ if (hr != S_OK)
+ {
+ NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgInfQueryContext for Manufacturer failed, hr=0x%x\n", hr));
+ return hr;
+ }
+
+ hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 1, &lpszModels, &cModels);
+ if (hr != S_OK)
+ {
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue 1 for Manufacturer failed, hr=0x%x\n", hr));
+ return hr;
+ }
+
+ for (DWORD i = 2; (hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, i, &lpszPlatformCur, &cPlatformCur)) == S_OK; ++i)
+ {
+ if (wcsicmp(lpszPlatformCur, L"NT"VBOXDRVCFG_ARCHSTR))
+ {
+ if (bNt)
+ {
+ free(lpszPlatformCur);
+ lpszPlatformCur = NULL;
+ continue;
+ }
+
+ if (wcsicmp(lpszPlatformCur, L"NT"))
+ {
+ free(lpszPlatformCur);
+ lpszPlatformCur = NULL;
+ continue;
+ }
+
+ bNt = true;
+ }
+ else
+ {
+ bArch = true;
+ }
+
+ cPlatform = cPlatformCur;
+ if(lpszPlatform)
+ free(lpszPlatform);
+ lpszPlatform = lpszPlatformCur;
+ lpszPlatformCur = NULL;
+ }
+
+ hr = S_OK;
+
+ if (lpszPlatform)
+ {
+ lpszResult = (LPWSTR)malloc((cModels + cPlatform) * sizeof (lpszResult[0]));
+ if (lpszResult)
+ {
+ memcpy(lpszResult, lpszModels, (cModels - 1) * sizeof (lpszResult[0]));
+ *(lpszResult + cModels - 1) = L'.';
+ memcpy(lpszResult + cModels, lpszPlatform, cPlatform * sizeof (lpszResult[0]));
+ cResult = cModels + cPlatform;
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ else
+ {
+ lpszResult = lpszModels;
+ cResult = cModels;
+ lpszModels = NULL;
+ }
+
+ if (lpszModels)
+ free(lpszModels);
+ if (lpszPlatform)
+ free(lpszPlatform);
+
+ if (hr == S_OK)
+ {
+ *lppszValue = lpszResult;
+ if (pcValue)
+ *pcValue = cResult;
+ }
+
+ return hr;
+}
+
+static HRESULT vboxDrvCfgInfQueryFirstPnPId(HINF hInf, LPWSTR *lppszPnPId)
+{
+ *lppszPnPId = NULL;
+
+ LPWSTR lpszModels;
+ HRESULT hr = vboxDrvCfgInfQueryModelsSectionName(hInf, &lpszModels, NULL);
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryModelsSectionName returned lpszModels = (%S)", lpszModels));
+ if (hr != S_OK)
+ {
+ NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for Manufacturer failed, hr=0x%x\n", hr));
+ return hr;
+ }
+
+ LPWSTR lpszPnPId = NULL;
+ INFCONTEXT InfCtx;
+ hr = vboxDrvCfgInfQueryContext(hInf, lpszModels, NULL, &InfCtx);
+ if (hr != S_OK)
+ {
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryContext for models (%S) failed, hr=0x%x\n", lpszModels, hr));
+ }
+ else
+ {
+ hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 2, &lpszPnPId, NULL);
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) returned lpszPnPId (%S) \n", lpszModels, lpszPnPId));
+
+ if (hr != S_OK)
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) failed, hr=0x%x\n", lpszModels, hr));
+ }
+ /* free models string right away */
+ free(lpszModels);
+ if (hr != S_OK)
+ return hr;
+
+ *lppszPnPId = lpszPnPId;
+ return S_OK;
+}
+
+static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt);
+
+#define VBOXDRVCFG_S_INFEXISTS (HRESULT_FROM_WIN32(ERROR_FILE_EXISTS))
+
+static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR lpszInfPath, IN DWORD fCopyStyle, OUT LPWSTR lpszDstName, IN DWORD cbDstName, OUT PDWORD pcbDstNameSize, OUT LPWSTR* lpszDstNameComponent)
+{
+ WCHAR aMediaLocation[_MAX_DIR];
+ WCHAR aDir[_MAX_DIR];
+
+ _wsplitpath(lpszInfPath, aMediaLocation, aDir, NULL, NULL);
+ wcscat(aMediaLocation, aDir);
+
+ if (!SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,
+ lpszDstName, cbDstName, pcbDstNameSize,
+ lpszDstNameComponent))
+ {
+ DWORD dwErr = GetLastError();
+ HRESULT hr = HRESULT_FROM_WIN32(dwErr);
+ if (fCopyStyle != SP_COPY_REPLACEONLY || hr != VBOXDRVCFG_S_INFEXISTS)
+ {
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail dwErr=%ld\n", dwErr));
+ }
+ return hr;
+ }
+
+ return S_OK;
+}
+
+static HRESULT vboxDrvCfgInfCopy(IN LPCWSTR lpszInfPath)
+{
+ return vboxDrvCfgInfCopyEx(lpszInfPath, 0, NULL, 0, NULL, NULL);
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfInstall(IN LPCWSTR lpszInfPath)
+{
+ return vboxDrvCfgInfCopy(lpszInfPath);
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstall(IN LPCWSTR lpszInfPath, DWORD fFlags)
+{
+ WCHAR DstInfName[MAX_PATH];
+ DWORD cbDword = sizeof (DstInfName);
+ HRESULT hr = vboxDrvCfgInfCopyEx(lpszInfPath, SP_COPY_REPLACEONLY, DstInfName, cbDword, &cbDword, NULL);
+ if (hr == VBOXDRVCFG_S_INFEXISTS)
+ {
+ if (!SetupUninstallOEMInfW(DstInfName, fFlags, NULL /*__in PVOID Reserved == NULL */))
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), oem(%S), dwErr=%ld\n", lpszInfPath, DstInfName, dwErr));
+ NonStandardAssert(0);
+ return HRESULT_FROM_WIN32(dwErr);
+ }
+ }
+ return S_OK;
+}
+
+
+static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId, VBoxDrvCfgStringList & list)
+{
+ DWORD dwErr = ERROR_SUCCESS;
+ HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(
+ pGuid, /* IN LPGUID ClassGuid, OPTIONAL */
+ NULL /*IN HWND hwndParent OPTIONAL */
+ );
+ if (hDevInfo != INVALID_HANDLE_VALUE)
+ {
+ if (SetupDiBuildDriverInfoList(hDevInfo,
+ NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ SPDIT_CLASSDRIVER /*IN DWORD DriverType*/
+ ))
+ {
+ SP_DRVINFO_DATA DrvInfo;
+ DrvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
+ char DetailBuf[16384];
+ PSP_DRVINFO_DETAIL_DATA pDrvDetail = (PSP_DRVINFO_DETAIL_DATA)DetailBuf;
+
+ for (DWORD i = 0; ; i++)
+ {
+ if (SetupDiEnumDriverInfo(hDevInfo,
+ NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/
+ i, /*IN DWORD MemberIndex,*/
+ &DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/
+ ))
+ {
+ DWORD dwReq;
+ pDrvDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
+ if (SetupDiGetDriverInfoDetail(
+ hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/
+ NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ &DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/
+ pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/
+ sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/
+ &dwReq /*OUT PDWORD RequiredSize OPTIONAL*/
+ ))
+ {
+ for (WCHAR * pHwId = pDrvDetail->HardwareID; pHwId && *pHwId && pHwId < (TCHAR*)(DetailBuf + sizeof(DetailBuf)/sizeof(DetailBuf[0])) ;pHwId += wcslen(pHwId) + 1)
+ {
+ if (!wcsicmp(pHwId, pPnPId))
+ {
+ NonStandardAssert(pDrvDetail->InfFileName[0]);
+ if (pDrvDetail->InfFileName)
+ {
+ list.add(pDrvDetail->InfFileName);
+ NonStandardLogRelCrap((__FUNCTION__": %S added to list", pDrvDetail->InfFileName));
+ }
+ }
+ }
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": SetupDiGetDriverInfoDetail fail dwErr=%ld, size(%d)", dwErr, dwReq));
+// NonStandardAssert(0);
+ }
+
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr == ERROR_NO_MORE_ITEMS)
+ {
+ NonStandardLogRelCrap((__FUNCTION__": dwErr == ERROR_NO_MORE_ITEMS -> search was finished "));
+ break;
+ }
+
+ NonStandardAssert(0);
+ }
+ }
+
+ SetupDiDestroyDriverInfoList(hDevInfo,
+ NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
+ SPDIT_CLASSDRIVER/*IN DWORD DriverType*/
+ );
+ }
+ else
+ {
+ dwErr = GetLastError();
+ NonStandardAssert(0);
+ }
+
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+ }
+ else
+ {
+ dwErr = GetLastError();
+ NonStandardAssert(0);
+ }
+
+ return HRESULT_FROM_WIN32(dwErr);
+}
+
+#if 0
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInit()
+{
+ int rc = RTR3InitDll(0);
+ if (rc != VINF_SUCCESS)
+ {
+ NonStandardLogRelCrap(("Could not init IPRT!, rc (%d)\n", rc));
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgTerm()
+{
+ return S_OK;
+}
+#endif
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidClass, IN LPCWSTR lpszClassName, IN LPCWSTR lpszPnPId, IN DWORD Flags)
+{
+ VBoxDrvCfgStringList list(128);
+ HRESULT hr = vboxDrvCfgCollectInfsSetupDi(pGuidClass, lpszPnPId, list);
+ NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgCollectInfsSetupDi returned %d devices with PnPId %S and class name %S", list.size(), lpszPnPId, lpszClassName));
+ if (hr == S_OK)
+ {
+ INFENUM_CONTEXT Context;
+ Context.InfInfo.lpszClassName = lpszClassName;
+ Context.InfInfo.lpszPnPId = lpszPnPId;
+ Context.Flags = Flags;
+ Context.hr = S_OK;
+ int size = list.size();
+ for (int i = 0; i < size; ++i)
+ {
+ LPCWSTR pInf = list.get(i);
+ const WCHAR* pRel = wcsrchr(pInf, '\\');
+ if (pRel)
+ ++pRel;
+ else
+ pRel = pInf;
+
+ vboxDrvCfgInfEnumerationCallback(pRel, &Context);
+ NonStandardLogRelCrap((__FUNCTION__": inf = %S\n", list.get(i)));
+ }
+ }
+ return hr;
+}
+
+static HRESULT vboxDrvCfgEnumFiles(LPCWSTR pPattern, PFNVBOXNETCFG_ENUMERATION_CALLBACK pfnCallback, PVOID pContext)
+{
+ WIN32_FIND_DATA Data;
+ memset(&Data, 0, sizeof(Data));
+ HRESULT hr = S_OK;
+
+ HANDLE hEnum = FindFirstFile(pPattern,&Data);
+ if (hEnum != INVALID_HANDLE_VALUE)
+ {
+
+ do
+ {
+ if (!pfnCallback(Data.cFileName, pContext))
+ {
+ break;
+ }
+
+ /* next iteration */
+ memset(&Data, 0, sizeof(Data));
+ BOOL bNext = FindNextFile(hEnum,&Data);
+ if (!bNext)
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr != ERROR_NO_MORE_FILES)
+ {
+ NonStandardLogRelCrap((__FUNCTION__": FindNextFile fail dwErr=%ld\n", dwErr));
+ NonStandardAssert(0);
+ hr = HRESULT_FROM_WIN32(dwErr);
+ }
+ break;
+ }
+ }while (true);
+ FindClose(hEnum);
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr != ERROR_NO_MORE_FILES)
+ {
+ NonStandardLogRelCrap((__FUNCTION__": FindFirstFile fail dwErr=%ld\n", dwErr));
+ NonStandardAssert(0);
+ hr = HRESULT_FROM_WIN32(dwErr);
+ }
+ }
+
+ return hr;
+}
+
+static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt)
+{
+ PINFENUM_CONTEXT pContext = (PINFENUM_CONTEXT)pCtxt;
+ DWORD dwErr;
+ NonStandardLogRelCrap((__FUNCTION__": lpszFileName (%S)\n", lpszFileName));
+ NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.lpszClassName = (%S)\n", pContext->InfInfo.lpszClassName));
+ HINF hInf = SetupOpenInfFileW(lpszFileName, pContext->InfInfo.lpszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
+ if (hInf == INVALID_HANDLE_VALUE)
+ {
+ dwErr = GetLastError();
+// NonStandardAssert(dwErr == ERROR_CLASS_MISMATCH);
+ if (dwErr != ERROR_CLASS_MISMATCH)
+ {
+ NonStandardLogCrap((__FUNCTION__ ": SetupOpenInfFileW err dwErr=%ld\n", dwErr));
+ }
+ else
+ {
+ NonStandardLogCrap((__FUNCTION__ ": dwErr == ERROR_CLASS_MISMATCH\n"));
+ }
+ return true;
+ }
+
+ LPWSTR lpszPnPId;
+ HRESULT hr = vboxDrvCfgInfQueryFirstPnPId(hInf, &lpszPnPId);
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId returned lpszPnPId = (%S)\n", lpszPnPId));
+ NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.lpszPnPId = (%S)\n", pContext->InfInfo.lpszPnPId));
+ if (hr == S_OK)
+ {
+ if (!wcsicmp(pContext->InfInfo.lpszPnPId, lpszPnPId))
+ {
+ if (!SetupUninstallOEMInfW(lpszFileName,
+ pContext->Flags, /*DWORD Flags could be SUOI_FORCEDELETE */
+ NULL /*__in PVOID Reserved == NULL */
+ ))
+ {
+ dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), dwErr=%ld\n", lpszFileName, dwErr));
+ NonStandardAssert(0);
+ hr = HRESULT_FROM_WIN32( dwErr );
+ }
+ }
+
+ free(lpszPnPId);
+ }
+ else
+ {
+ NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId failed, hr=0x%x\n", hr));
+ }
+
+ SetupCloseInfFile(hInf);
+
+ return true;
+}
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(LPCWSTR lpszClassName, LPCWSTR lpszPnPId, DWORD Flags)
+{
+ static WCHAR const s_wszFilter[] = L"\\inf\\oem*.inf";
+ HRESULT hr;
+ WCHAR wszInfDirPath[MAX_PATH];
+ UINT cwcInput = RT_ELEMENTS(wszInfDirPath) - RT_ELEMENTS(s_wszFilter);
+ UINT cwcWindows = GetSystemWindowsDirectory(wszInfDirPath, cwcInput);
+ if (cwcWindows > 0 && cwcWindows < cwcInput)
+ {
+ wcscpy(&wszInfDirPath[cwcWindows], s_wszFilter);
+
+ INFENUM_CONTEXT Context;
+ Context.InfInfo.lpszClassName = lpszClassName;
+ Context.InfInfo.lpszPnPId = lpszPnPId;
+ Context.Flags = Flags;
+ Context.hr = S_OK;
+ NonStandardLogRelCrap((__FUNCTION__": Calling vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context)"));
+ hr = vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context);
+ NonStandardAssert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ hr = Context.hr;
+ }
+ else
+ {
+ NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgEnumFiles failed, hr=0x%x\n", hr));
+ }
+ }
+ else
+ {
+ NonStandardLogRelCrap((__FUNCTION__": GetSystemWindowsDirectory failed, cwcWindows=%u lasterr=%u\n", cwcWindows, GetLastError()));
+ NonStandardAssertFailed();
+ hr = E_FAIL;
+ }
+
+ return hr;
+
+}
+
+/* time intervals in milliseconds */
+/* max time to wait for the service to startup */
+#define VBOXDRVCFG_SVC_WAITSTART_TIME 10000
+/* sleep time before service status polls */
+#define VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD 100
+/* number of service start polls */
+#define VBOXDRVCFG_SVC_WAITSTART_RETRIES (VBOXDRVCFG_SVC_WAITSTART_TIME/VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD)
+
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgSvcStart(LPCWSTR lpszSvcName)
+{
+ SC_HANDLE hMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
+ if (hMgr == NULL)
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": OpenSCManager failed, dwErr=%ld\n", dwErr));
+ return HRESULT_FROM_WIN32(dwErr);
+ }
+
+ HRESULT hr = S_OK;
+ SC_HANDLE hSvc = OpenServiceW(hMgr, lpszSvcName, SERVICE_QUERY_STATUS | SERVICE_START);
+ if (hSvc)
+ {
+ do
+ {
+ SERVICE_STATUS Status;
+ BOOL fRc = QueryServiceStatus(hSvc, &Status);
+ if (!fRc)
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ break;
+ }
+
+ if (Status.dwCurrentState != SERVICE_RUNNING && Status.dwCurrentState != SERVICE_START_PENDING)
+ {
+ NonStandardLogRelCrap(("Starting service (%S)\n", lpszSvcName));
+
+ fRc = StartService(hSvc, 0, NULL);
+ if (!fRc)
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": StartService failed dwErr=%ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ break;
+ }
+ }
+
+ fRc = QueryServiceStatus(hSvc, &Status);
+ if (!fRc)
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ break;
+ }
+
+ if (Status.dwCurrentState == SERVICE_START_PENDING)
+ {
+ for (int i = 0; i < VBOXDRVCFG_SVC_WAITSTART_RETRIES; ++i)
+ {
+ Sleep(VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD);
+ fRc = QueryServiceStatus(hSvc, &Status);
+ if (!fRc)
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ break;
+ }
+ else if (Status.dwCurrentState != SERVICE_START_PENDING)
+ break;
+ }
+ }
+
+ if (hr != S_OK || Status.dwCurrentState != SERVICE_RUNNING)
+ {
+ NonStandardLogRelCrap((__FUNCTION__": Failed to start the service\n"));
+ hr = E_FAIL;
+ break;
+ }
+
+ } while (0);
+
+ CloseServiceHandle(hSvc);
+ }
+ else
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogRelCrap((__FUNCTION__": OpenServiceW failed, dwErr=%ld\n", dwErr));
+ hr = HRESULT_FROM_WIN32(dwErr);
+ }
+
+ CloseServiceHandle(hMgr);
+
+ return hr;
+}
+
+
+HRESULT VBoxDrvCfgDrvUpdate(LPCWSTR pcszwHwId, LPCWSTR pcsxwInf, BOOL *pbRebootRequired)
+{
+ if (pbRebootRequired)
+ *pbRebootRequired = FALSE;
+ BOOL bRebootRequired = FALSE;
+ WCHAR InfFullPath[MAX_PATH];
+ DWORD dwChars = GetFullPathNameW(pcsxwInf,
+ sizeof (InfFullPath) / sizeof (InfFullPath[0]),
+ InfFullPath,
+ NULL /* LPTSTR *lpFilePart */
+ );
+ if (!dwChars || dwChars >= MAX_PATH)
+ {
+ NonStandardLogCrap(("GetFullPathNameW failed, dwErr=%ld, dwChars=%ld\n",
+ GetLastError(), dwChars));
+ return E_INVALIDARG;
+ }
+
+
+ if (!UpdateDriverForPlugAndPlayDevicesW(NULL, /* HWND hwndParent */
+ pcszwHwId,
+ InfFullPath,
+ INSTALLFLAG_FORCE,
+ &bRebootRequired))
+ {
+ DWORD dwErr = GetLastError();
+ NonStandardLogCrap(("UpdateDriverForPlugAndPlayDevicesW failed, dwErr=%ld\n",
+ dwErr));
+ return HRESULT_FROM_WIN32(dwErr);
+ }
+
+
+ if (bRebootRequired)
+ NonStandardLogCrap(("!!Driver Update: REBOOT REQUIRED!!\n", GetLastError(), dwChars));
+
+ if (pbRebootRequired)
+ *pbRebootRequired = bRebootRequired;
+
+ return S_OK;
+}
diff --git a/src/VBox/HostDrivers/win/load.cmd b/src/VBox/HostDrivers/win/load.cmd
new file mode 100644
index 00000000..0cde60f0
--- /dev/null
+++ b/src/VBox/HostDrivers/win/load.cmd
@@ -0,0 +1,52 @@
+@echo off
+rem $Id: load.cmd $
+rem rem @file
+rem Windows NT batch script for launching load.sh
+rem
+
+rem
+rem Copyright (C) 2009-2019 Oracle Corporation
+rem
+rem This file is part of VirtualBox Open Source Edition (OSE), as
+rem available from http://www.virtualbox.org. This file is free software;
+rem you can redistribute it and/or modify it under the terms of the GNU
+rem General Public License (GPL) as published by the Free Software
+rem Foundation, in version 2 as it comes in the "COPYING" file of the
+rem VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+rem hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+rem
+rem The contents of this file may alternatively be used under the terms
+rem of the Common Development and Distribution License Version 1.0
+rem (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+rem VirtualBox OSE distribution, in which case the provisions of the
+rem CDDL are applicable instead of those of the GPL.
+rem
+rem You may elect to license modified versions of this file under the
+rem terms and conditions of either the GPL or the CDDL or both.
+rem
+
+
+setlocal ENABLEEXTENSIONS
+setlocal
+
+rem
+rem loadall.sh should be in the same directory as this script.
+rem
+set MY_SCRIPT=%~dp0load.sh
+if exist "%MY_SCRIPT%" goto found
+echo load.cmd: failed to find load.sh in "%~dp0".
+goto end
+
+rem
+rem Found it, convert slashes and tell kmk_ash to interpret it.
+rem
+:found
+set MY_SCRIPT=%MY_SCRIPT:\=/%
+set MY_ARGS=%*
+if ".%MY_ARGS%." NEQ ".." set MY_ARGS=%MY_ARGS:\=/%
+kmk_ash %MY_SCRIPT% %MY_ARGS%
+
+:end
+endlocal
+endlocal
+
diff --git a/src/VBox/HostDrivers/win/load.sh b/src/VBox/HostDrivers/win/load.sh
new file mode 100755
index 00000000..370afded
--- /dev/null
+++ b/src/VBox/HostDrivers/win/load.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+## @file
+# For development, loads the support driver.
+#
+
+#
+# Copyright (C) 2010-2019 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+# VirtualBox OSE distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+
+if test -n "$Path" -a -z "$PATH"; then
+ export PATH="$Path"
+fi
+
+MY_DIR=`cd "${0}/.." && cmd /c cd | kmk_sed -e 's,\\\\,/,g' `
+if [ ! -d "${MY_DIR}" ]; then
+ echo "Cannot find ${MY_DIR} or it's not a directory..."
+ exit 1;
+fi
+echo MY_DIR=$MY_DIR
+
+set -e
+cd "$MY_DIR"
+set +e
+
+
+#
+# Query the status of the drivers.
+#
+for drv in VBoxNetAdp VBoxNetAdp6 VBoxNetFlt VBoxNetLwf VBoxUSBMon VBoxUSB VBoxDrv;
+do
+ if sc query $drv > /dev/null; then
+ STATE=`sc query $drv \
+ | kmk_sed -e '/^ *STATE /!d' -e 's/^[^:]*: [0-9 ]*//' \
+ -e 's/ */ /g' \
+ -e 's/^ *//g' \
+ -e 's/ *$//g' \
+ `
+ echo "load.sh: $drv - $STATE"
+ else
+ echo "load.sh: $drv - not configured, probably."
+ fi
+done
+
+set -e
+set -x
+
+#
+# Invoke the uninstallers.
+#
+for uninst in NetAdpUninstall.exe NetAdp6Uninstall.exe USBUninstall.exe NetFltUninstall.exe NetLwfUninstall.exe SUPUninstall.exe;
+do
+ if test -f ${MY_DIR}/$uninst; then
+ ${MY_DIR}/$uninst
+ fi
+done
+
+#
+# Invoke the installer.
+#
+if test "$1" != "-u" -a "$1" != "--uninstall"; then
+ for inst in SUPInstall.exe;
+ do
+ if test -f ${MY_DIR}/$inst; then
+ ${MY_DIR}/$inst
+ fi
+ done
+fi
+
+echo "load.sh: Successfully installed SUPDrv (aka VBoxDrv)"
+exit 0
+
diff --git a/src/VBox/HostDrivers/win/loadall.cmd b/src/VBox/HostDrivers/win/loadall.cmd
new file mode 100644
index 00000000..15117588
--- /dev/null
+++ b/src/VBox/HostDrivers/win/loadall.cmd
@@ -0,0 +1,52 @@
+@echo off
+rem $Id: loadall.cmd $
+rem rem @file
+rem Windows NT batch script for launching loadall.sh
+rem
+
+rem
+rem Copyright (C) 2009-2019 Oracle Corporation
+rem
+rem This file is part of VirtualBox Open Source Edition (OSE), as
+rem available from http://www.virtualbox.org. This file is free software;
+rem you can redistribute it and/or modify it under the terms of the GNU
+rem General Public License (GPL) as published by the Free Software
+rem Foundation, in version 2 as it comes in the "COPYING" file of the
+rem VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+rem hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+rem
+rem The contents of this file may alternatively be used under the terms
+rem of the Common Development and Distribution License Version 1.0
+rem (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+rem VirtualBox OSE distribution, in which case the provisions of the
+rem CDDL are applicable instead of those of the GPL.
+rem
+rem You may elect to license modified versions of this file under the
+rem terms and conditions of either the GPL or the CDDL or both.
+rem
+
+
+setlocal ENABLEEXTENSIONS
+setlocal
+
+rem
+rem loadall.sh should be in the same directory as this script.
+rem
+set MY_SCRIPT=%~dp0loadall.sh
+if exist "%MY_SCRIPT%" goto found
+echo loadall.cmd: failed to find loadall.sh in "%~dp0".
+goto end
+
+rem
+rem Found it, convert slashes and tell kmk_ash to interpret it.
+rem
+:found
+set MY_SCRIPT=%MY_SCRIPT:\=/%
+set MY_ARGS=%*
+if ".%MY_ARGS%." NEQ ".." set MY_ARGS=%MY_ARGS:\=/%
+kmk_ash %MY_SCRIPT% %MY_ARGS%
+
+:end
+endlocal
+endlocal
+
diff --git a/src/VBox/HostDrivers/win/loadall.sh b/src/VBox/HostDrivers/win/loadall.sh
new file mode 100755
index 00000000..08b20adb
--- /dev/null
+++ b/src/VBox/HostDrivers/win/loadall.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+## @file
+# For development, loads all the host drivers.
+#
+
+#
+# Copyright (C) 2010-2019 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+# VirtualBox OSE distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+
+if test -n "$Path" -a -z "$PATH"; then
+ export PATH="$Path"
+fi
+
+MY_DIR=`cd "${0}/.." && cmd /c cd | kmk_sed -e 's,\\\\,/,g' `
+if [ ! -d "${MY_DIR}" ]; then
+ echo "Cannot find ${MY_DIR} or it's not a directory..."
+ exit 1;
+fi
+echo MY_DIR=$MY_DIR
+
+set -e
+cd "$MY_DIR"
+set +e
+
+
+#
+# Query the status of the drivers.
+#
+for drv in VBoxNetAdp VBoxNetAdp6 VBoxNetFlt VBoxNetLwf VBoxUSBMon VBoxUSB VBoxDrv;
+do
+ if sc query $drv > /dev/null; then
+ STATE=`sc query $drv \
+ | kmk_sed -e '/^ *STATE /!d' -e 's/^[^:]*: [0-9 ]*//' \
+ -e 's/ */ /g' \
+ -e 's/^ *//g' \
+ -e 's/ *$//g' \
+ `
+ echo "loadall.sh: $drv - $STATE"
+ else
+ echo "loadall.sh: $drv - not configured, probably."
+ fi
+done
+
+set -e
+set -x
+
+#
+# Invoke the uninstallers.
+#
+for uninst in NetAdpUninstall.exe NetAdp6Uninstall.exe USBUninstall.exe NetFltUninstall.exe NetLwfUninstall.exe SUPUninstall.exe;
+do
+ if test -f ${MY_DIR}/$uninst; then
+ ${MY_DIR}/$uninst
+ fi
+done
+
+#
+# Invoke the installers.
+#
+if test "$1" != "-u" -a "$1" != "--uninstall"; then
+ INSTALLERS="SUPInstall.exe USBInstall.exe";
+ VER=`cmd.exe /c ver`
+ VER=`echo "$VER" | kmk_sed -e 's/^.*\[[^0-9]* \(.*\)\]/\1/' -e '/^$/d`
+ case "$VER" in
+ 6.*|10.*|11.*|12.*)
+ INSTALLERS="$INSTALLERS NetLwfInstall.exe"; #NetAdp6Install.exe - also busted?
+ ;;
+ *)
+ INSTALLERS="$INSTALLERS NetFltInstall.exe"; #NetAdpInstall.exe; - busted
+ ;;
+ esac
+
+ for inst in $INSTALLERS;
+ do
+ if test -f ${MY_DIR}/$inst; then
+ ${MY_DIR}/$inst
+ fi
+ done
+fi
+
+echo "loadall.sh: Successfully installed all drivers"
+exit 0
+